问:
Using one keyboard for a two player game
I'm having some problems with a game I'm making as a project. It consists mainly of two players using the WASD to move and E to stop and the second player uses de arrow keys to move and SHIFT to stop.

The main problem I have is when both players move the rockets at the same time, when one rocket turns to the left or right the other player can't move at all to the sides or it moves forward but slowly and with the same issue, it can't move to the left or right.

Any idea on what could be the issue with the controls or anything I'm not considering in my code?

This are some of the classes for the game:

GameDraw Class, it has the movements of the players and draw the rockets.

```<code>import javax.swing.*;
import java.awt.*;
import java.awt.geom.*;

class GameDraw extends JComponent{
            static Jugador rocket1 = new Jugador();
            static Jugador rocket2 = new Jugador();
            int width = GUI.width;
            int height = GUI.height;

            public GameDraw() {}

            public void paint(Graphics g) {
                Graphics2D graphicsSet = (Graphics2D) g;
                AffineTransform id = new AffineTransform();
                AffineTransform id2 = new AffineTransform();
                graphicsSet.setColor(Color.LIGHT_GRAY);
                graphicsSet.fillRect(0, 0, getWidth(), getHeight());
                graphicsSet.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON);
                graphicsSet.setPaint(Color.blue);

                //Player 1 Controls//
                if(GUI.keyHeld_D == true && GUI.keyHeldCode == Controls.D) {
                    rocket1.increaseRotAngle();
                }
                else if(GUI.keyHeld_A == true && GUI.keyHeldCode == Controls.A) {
                    rocket1.decreaseRotAngle();
                }
                else if(GUI.keyHeld_W == true && GUI.keyHeldCode == Controls.W) {
                    rocket1.setMovingAngle(rocket1.getRotationAngle());
                    rocket1.increaseXVel(rocket1.rocketXMoveAngle(rocket1.getMovingAngle())*0.1);
                    rocket1.increaseYVel(rocket1.rocketYMoveAngle(rocket1.getMovingAngle())*0.1);
                }
                else if(GUI.keyHeld_S == true && GUI.keyHeldCode == Controls.S) {
                    rocket1.setMovingAngle(rocket1.getRotationAngle());
                    rocket1.decreaseXVel(rocket1.rocketXMoveAngle(rocket1.getMovingAngle())*0.1);
                    rocket1.decreaseYVel(rocket1.rocketYMoveAngle(rocket1.getMovingAngle())*0.1);
                }
                else if(GUI.keyHeld_E == true && GUI.keyHeldCode == Controls.E) {
                    rocket1.stopRocket();
                }

                //Player 2 Controls//
                if(GUI.keyHeld_RIGHT == true && GUI.keyHeldCode == Controls.RIGHT) {
                    rocket2.increaseRotAngle();
                }
                else if(GUI.keyHeld_LEFT == true && GUI.keyHeldCode == Controls.LEFT) {
                    rocket2.decreaseRotAngle();
                }
                else if(GUI.keyHeld_UP == true && GUI.keyHeldCode == Controls.UP) {
                    rocket2.setMovingAngle(rocket2.getRotationAngle());
                    rocket2.increaseXVel(rocket2.rocketXMoveAngle(rocket2.getMovingAngle())*0.1);
                    rocket2.increaseYVel(rocket2.rocketYMoveAngle(rocket2.getMovingAngle())*0.1);
                }
                else if(GUI.keyHeld_DOWN == true && GUI.keyHeldCode == Controls.DOWN) {
                    rocket2.setMovingAngle(rocket2.getRotationAngle());
                    rocket2.decreaseXVel(rocket2.rocketXMoveAngle(rocket2.getMovingAngle())*0.1);
                    rocket2.decreaseYVel(rocket2.rocketYMoveAngle(rocket2.getMovingAngle())*0.1);
                }
                else if(GUI.keyHeld_SHIFT == true && GUI.keyHeldCode == Controls.SHIFT) {
                    rocket2.stopRocket();
                }

                rocket1.movement();
                graphicsSet.setTransform(id);
                graphicsSet.translate(rocket1.getXCenter(), rocket1.getYCenter());
                graphicsSet.rotate(Math.toRadians(rocket1.getRotationAngle()));
                graphicsSet.draw(rocket1);

                rocket2.movement();
                graphicsSet.setTransform(id2);
                graphicsSet.translate(rocket2.getXCenter(), rocket2.getYCenter());
                graphicsSet.rotate(Math.toRadians(rocket2.getRotationAngle()));
                graphicsSet.draw(rocket2);
            }
        }
</code>```

GUI Class

```<code>import javax.swing.*;
import java.awt.*;
import java.awt.event.*;
import java.util.concurrent.ScheduledThreadPoolExecutor;
import java.util.concurrent.TimeUnit;

public class GUI extends JFrame {
    public static int width = 1000;
    public static int height = 600;
    public static boolean keyHeld_W = false, keyHeld_A = false, keyHeld_S = false, keyHeld_D = false, keyHeld_E = false, keyHeld_UP = false, keyHeld_LEFT = false, keyHeld_DOWN = false, keyHeld_RIGHT = false, keyHeld_SHIFT = false;
    public static int keyHeldCode;

    public GUI() {
        this.setTitle("ROCKET FOOTBALL");
        this.setSize(width, height);
        this.setVisible(true);
        this.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        this.addKeyListener(new KeyAdapter() {

            public void keyTyped(KeyEvent e) {}

            public void keyPressed(KeyEvent e) {
                int keyCode = e.getKeyCode();
                keyHeldCode = keyCode;
                //Player 1 Controls//
                if(keyHeldCode == Controls.W) {
                    Jugador.interaction_W = true;
                    keyHeld_W = true;
                }
                if(keyHeldCode == Controls.A) {
                    Jugador.interaction_A = true;
                    keyHeld_A = true;
                }
                if(keyHeldCode == Controls.S) {
                    Jugador.interaction_S = true;
                    keyHeld_S = true;
                }
                if(keyHeldCode == Controls.D) {
                    Jugador.interaction_D = true;
                    keyHeld_D = true;
                }
                if(keyHeldCode == Controls.E) {
                    Jugador.interaction_E = true;
                    keyHeld_E = true;
                }

                    //Player 2 Controls//
                if(keyHeldCode == Controls.UP) {
                    Jugador.interaction_UP = true;
                    keyHeld_UP = true;
                }
                if(keyHeldCode == Controls.LEFT) {
                    Jugador.interaction_LEFT = true;
                    keyHeld_LEFT = true;
                }
                if(keyHeldCode == Controls.DOWN) {
                    Jugador.interaction_DOWN = true;
                    keyHeld_DOWN = true;
                }
                if(keyHeldCode == Controls.RIGHT) {
                    Jugador.interaction_RIGHT = true;
                    keyHeld_RIGHT = true;
                }
                if(keyHeldCode == Controls.SHIFT) {
                    Jugador.interaction_SHIFT = true;
                    keyHeld_SHIFT = true;
                }
            }

            public void keyReleased(KeyEvent e) {
                //Player 1//
                    if(keyHeldCode == Controls.W) {
                        keyHeld_W = false;
                    }
                    if(keyHeldCode == Controls.A) {
                        keyHeld_A = false;
                    }
                    if(keyHeldCode == Controls.S) {
                        keyHeld_S = false;
                    }
                    if(keyHeldCode == Controls.D) {
                        keyHeld_D = false;
                    }
                    if(keyHeldCode == Controls.E) {
                        keyHeld_E = false;
                    }

                    //Player 2//
                    if(keyHeldCode == Controls.UP) {
                        keyHeld_UP = false;
                    }
                    if(keyHeldCode == Controls.LEFT) {
                        keyHeld_LEFT = false;
                    }
                    if(keyHeldCode == Controls.DOWN) {
                        keyHeld_DOWN = false;
                    }
                    if(keyHeldCode == Controls.RIGHT) {
                        keyHeld_RIGHT = false;
                    }
                    if(keyHeldCode == Controls.SHIFT) {
                        keyHeld_SHIFT = false;
                    }
                }
            });
        GameDraw gamePanel = new GameDraw();
        this.add(gamePanel, BorderLayout.CENTER);
        ScheduledThreadPoolExecutor ex = new ScheduledThreadPoolExecutor(2);
        ex.scheduleAtFixedRate(new RepaintTheBoard(this), 0L,20L, TimeUnit.MILLISECONDS);
        this.setResizable(false);
        this.setVisible(true);
    }
}
</code>```

答:
when one rocket turns to the left or right the other player can't move at all

KeyEvents can only be generated for the last key pressed. So basically you need to keep track of a key as it is pressed and you need to use a Timer to schedule the animation. So every time the Timer fires, you check which keys are currently pressed and invoke the appropriate action.

also on using keybindings

Yes, key bindings is the preferred approach as it removes focus issues.

Check out the KeyboardAnimation example found in Motion Using the Keyboard. The example uses the 4 arrow keys for one player and WASD for the other player with a couple of differences:

You can hold two keys down at the same time to have diagonal movement

You need to release the keys to stop the motion

Body:
I'm having some problems with a game I'm making as a project. It consists mainly of two players using the WASD to move and E to stop and the second player uses de arrow keys to move and SHIFT to stop.

The main problem I have is when both players move the rockets at the same time, when one rocket turns to the left or right the other player can't move at all to the sides or it moves forward but slowly and with the same issue, it can't move to the left or right.

Any idea on what could be the issue with the controls or anything I'm not considering in my code?

This are some of the classes for the game:

GameDraw Class, it has the movements of the players and draw the rockets.

import javax.swing.*;
import java.awt.*;
import java.awt.geom.*;

class GameDraw extends JComponent{
            static Jugador rocket1 = new Jugador();
            static Jugador rocket2 = new Jugador();
            int width = GUI.width;
            int height = GUI.height;

            public GameDraw() {}

            public void paint(Graphics g) {
                Graphics2D graphicsSet = (Graphics2D) g;
                AffineTransform id = new AffineTransform();
                AffineTransform id2 = new AffineTransform();
                graphicsSet.setColor(Color.LIGHT_GRAY);
                graphicsSet.fillRect(0, 0, getWidth(), getHeight());
                graphicsSet.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON);
                graphicsSet.setPaint(Color.blue);

                //Player 1 Controls//
                if(GUI.keyHeld_D == true && GUI.keyHeldCode == Controls.D) {
                    rocket1.increaseRotAngle();
                }
                else if(GUI.keyHeld_A == true && GUI.keyHeldCode == Controls.A) {
                    rocket1.decreaseRotAngle();
                }
                else if(GUI.keyHeld_W == true && GUI.keyHeldCode == Controls.W) {
                    rocket1.setMovingAngle(rocket1.getRotationAngle());
                    rocket1.increaseXVel(rocket1.rocketXMoveAngle(rocket1.getMovingAngle())*0.1);
                    rocket1.increaseYVel(rocket1.rocketYMoveAngle(rocket1.getMovingAngle())*0.1);
                }
                else if(GUI.keyHeld_S == true && GUI.keyHeldCode == Controls.S) {
                    rocket1.setMovingAngle(rocket1.getRotationAngle());
                    rocket1.decreaseXVel(rocket1.rocketXMoveAngle(rocket1.getMovingAngle())*0.1);
                    rocket1.decreaseYVel(rocket1.rocketYMoveAngle(rocket1.getMovingAngle())*0.1);
                }
                else if(GUI.keyHeld_E == true && GUI.keyHeldCode == Controls.E) {
                    rocket1.stopRocket();
                }

                //Player 2 Controls//
                if(GUI.keyHeld_RIGHT == true && GUI.keyHeldCode == Controls.RIGHT) {
                    rocket2.increaseRotAngle();
                }
                else if(GUI.keyHeld_LEFT == true && GUI.keyHeldCode == Controls.LEFT) {
                    rocket2.decreaseRotAngle();
                }
                else if(GUI.keyHeld_UP == true && GUI.keyHeldCode == Controls.UP) {
                    rocket2.setMovingAngle(rocket2.getRotationAngle());
                    rocket2.increaseXVel(rocket2.rocketXMoveAngle(rocket2.getMovingAngle())*0.1);
                    rocket2.increaseYVel(rocket2.rocketYMoveAngle(rocket2.getMovingAngle())*0.1);
                }
                else if(GUI.keyHeld_DOWN == true && GUI.keyHeldCode == Controls.DOWN) {
                    rocket2.setMovingAngle(rocket2.getRotationAngle());
                    rocket2.decreaseXVel(rocket2.rocketXMoveAngle(rocket2.getMovingAngle())*0.1);
                    rocket2.decreaseYVel(rocket2.rocketYMoveAngle(rocket2.getMovingAngle())*0.1);
                }
                else if(GUI.keyHeld_SHIFT == true && GUI.keyHeldCode == Controls.SHIFT) {
                    rocket2.stopRocket();
                }

                rocket1.movement();
                graphicsSet.setTransform(id);
                graphicsSet.translate(rocket1.getXCenter(), rocket1.getYCenter());
                graphicsSet.rotate(Math.toRadians(rocket1.getRotationAngle()));
                graphicsSet.draw(rocket1);

                rocket2.movement();
                graphicsSet.setTransform(id2);
                graphicsSet.translate(rocket2.getXCenter(), rocket2.getYCenter());
                graphicsSet.rotate(Math.toRadians(rocket2.getRotationAngle()));
                graphicsSet.draw(rocket2);
            }
        }

GUI Class

import javax.swing.*;
import java.awt.*;
import java.awt.event.*;
import java.util.concurrent.ScheduledThreadPoolExecutor;
import java.util.concurrent.TimeUnit;

public class GUI extends JFrame {
    public static int width = 1000;
    public static int height = 600;
    public static boolean keyHeld_W = false, keyHeld_A = false, keyHeld_S = false, keyHeld_D = false, keyHeld_E = false, keyHeld_UP = false, keyHeld_LEFT = false, keyHeld_DOWN = false, keyHeld_RIGHT = false, keyHeld_SHIFT = false;
    public static int keyHeldCode;

    public GUI() {
        this.setTitle("ROCKET FOOTBALL");
        this.setSize(width, height);
        this.setVisible(true);
        this.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        this.addKeyListener(new KeyAdapter() {

            public void keyTyped(KeyEvent e) {}

            public void keyPressed(KeyEvent e) {
                int keyCode = e.getKeyCode();
                keyHeldCode = keyCode;
                //Player 1 Controls//
                if(keyHeldCode == Controls.W) {
                    Jugador.interaction_W = true;
                    keyHeld_W = true;
                }
                if(keyHeldCode == Controls.A) {
                    Jugador.interaction_A = true;
                    keyHeld_A = true;
                }
                if(keyHeldCode == Controls.S) {
                    Jugador.interaction_S = true;
                    keyHeld_S = true;
                }
                if(keyHeldCode == Controls.D) {
                    Jugador.interaction_D = true;
                    keyHeld_D = true;
                }
                if(keyHeldCode == Controls.E) {
                    Jugador.interaction_E = true;
                    keyHeld_E = true;
                }

                    //Player 2 Controls//
                if(keyHeldCode == Controls.UP) {
                    Jugador.interaction_UP = true;
                    keyHeld_UP = true;
                }
                if(keyHeldCode == Controls.LEFT) {
                    Jugador.interaction_LEFT = true;
                    keyHeld_LEFT = true;
                }
                if(keyHeldCode == Controls.DOWN) {
                    Jugador.interaction_DOWN = true;
                    keyHeld_DOWN = true;
                }
                if(keyHeldCode == Controls.RIGHT) {
                    Jugador.interaction_RIGHT = true;
                    keyHeld_RIGHT = true;
                }
                if(keyHeldCode == Controls.SHIFT) {
                    Jugador.interaction_SHIFT = true;
                    keyHeld_SHIFT = true;
                }
            }

            public void keyReleased(KeyEvent e) {
                //Player 1//
                    if(keyHeldCode == Controls.W) {
                        keyHeld_W = false;
                    }
                    if(keyHeldCode == Controls.A) {
                        keyHeld_A = false;
                    }
                    if(keyHeldCode == Controls.S) {
                        keyHeld_S = false;
                    }
                    if(keyHeldCode == Controls.D) {
                        keyHeld_D = false;
                    }
                    if(keyHeldCode == Controls.E) {
                        keyHeld_E = false;
                    }

                    //Player 2//
                    if(keyHeldCode == Controls.UP) {
                        keyHeld_UP = false;
                    }
                    if(keyHeldCode == Controls.LEFT) {
                        keyHeld_LEFT = false;
                    }
                    if(keyHeldCode == Controls.DOWN) {
                        keyHeld_DOWN = false;
                    }
                    if(keyHeldCode == Controls.RIGHT) {
                        keyHeld_RIGHT = false;
                    }
                    if(keyHeldCode == Controls.SHIFT) {
                        keyHeld_SHIFT = false;
                    }
                }
            });
        GameDraw gamePanel = new GameDraw();
        this.add(gamePanel, BorderLayout.CENTER);
        ScheduledThreadPoolExecutor ex = new ScheduledThreadPoolExecutor(2);
        ex.scheduleAtFixedRate(new RepaintTheBoard(this), 0L,20L, TimeUnit.MILLISECONDS);
        this.setResizable(false);
        this.setVisible(true);
    }
}


来源: stackexchange

问:
How to parse a String in Java without using .parse()?
I'm trying to write a program that will take a string and parse it into two outputs, with the delimiter being a comma. It loops until the user enters the character "q".

i.e.: Console prompts to enter an input, and user inputs "first, second" and then "q" for the second prompt, and the output will be:

```<code>Enter input string:
First word: first
Second word: second

Enter input string:
</code>```

If there is no comma in the input, it throws an error and prompts again

i.e. User inputs "first second" and the output will be:

```<code>Enter input string:
Error: No comma in string
Enter input string:
</code>```

Below is what I have so far:

```<code>import java.util.Scanner;

public class ParseStrings {
   public static void main(String[] args) {
         Scanner scnr = new Scanner(System.in); // Scanner for standard input
         Scanner inSS = null;                   // Scanner to write input to buffer
         String firstWord = "";                 // First word string
         String secondWord = "";                // Second word string
         String userInput = "";                 // Input from prompt
         int i = 0;                             // Loop iterator
         boolean inputDone = false;             // Boolean to repeat while loop
         boolean hasComma = false;              // Boolean to check for comma

         // Do while inputDone is false
         while (!inputDone) {

            //Prompt user to input a string
            System.out.println("Enter input string: ");

            // Write string to userInput
            userInput = scnr.nextLine();

            // Exit program if user inputs q
            if((userInput.equals("q"))) {
               inputDone = true;
               break;
            }
            else{

               // Write userInput to buffer
               inSS = new Scanner(userInput);

               // Write first word from buffer
               firstWord = inSS.next();

               // Loop through first word string
               for (i = 0; i < firstWord.length(); ++i) {

                  // If char is a comma, write everything after to secondWord and set inputDone to true
                  if(firstWord.charAt(i) == ',') {
                     secondWord = inSS.next();
                     hasComma = true;
                  }
               }

               // If hasComma is false, return error
               if (!hasComma){
                  System.out.println("Error: No comma in string");
               }
               // Else print first word and second word
               else {
                  System.out.println("First word: " + firstWord);
                  System.out.println("Second word: " + secondWord);
                  System.out.println("");
                  System.out.println("");
               }
            }
         }
        return;
       }
    }
</code>```

Problems:

I don't know how to remove the comma from the output

If there is no space it errors out

If there is a space between the first word and the comma, it writes firstWord but does not overwrite the previous value for secondWord (or errors if it's the first input given)

I'm taking a beginner's Java course and we have not gone over the .parse() method yet, so it's not really an option at this time.

Thank you in advance!

答:
So what I've done is probably the laziest and the most rookie way, but it does work.

Use a for loop to check each character of the string for the comma.

```<code>char ch;
String str = "";

if(userInput.charAt(userInput.length()-1) == ',')
    System.out.println("Error. You must have a comma here.");
else {
for(int i = 0; i < userInput.length(); i++)
{
    ch = userInput.charAt(i);
    if(ch != ',')
        str += ch;
    else
    {
        firstWord = str;
        secondWord = userInput.substring(i+1);
        break;
    }
}
}
</code>```

If the selected letter is not a comma, it is added to the temporary string.

If it is a comma, then the temporary string becomes the first word, and the second word is the string after the occurrence of the comma.

if(userInput.charAt(userInput.length()-1) == ',') Handles the exception that may arise if the input is hello ,, or anything that ENDS with a comma.

ContentLicense: CC BY-SA 3.0

Body:
I'm trying to write a program that will take a string and parse it into two outputs, with the delimiter being a comma. It loops until the user enters the character "q".

i.e.: Console prompts to enter an input, and user inputs "first, second" and then "q" for the second prompt, and the output will be:

Enter input string:
First word: first
Second word: second

Enter input string:

If there is no comma in the input, it throws an error and prompts again

i.e. User inputs "first second" and the output will be:

Enter input string:
Error: No comma in string
Enter input string:

Below is what I have so far:

import java.util.Scanner;

public class ParseStrings {
   public static void main(String[] args) {
         Scanner scnr = new Scanner(System.in); // Scanner for standard input
         Scanner inSS = null;                   // Scanner to write input to buffer
         String firstWord = "";                 // First word string
         String secondWord = "";                // Second word string
         String userInput = "";                 // Input from prompt
         int i = 0;                             // Loop iterator
         boolean inputDone = false;             // Boolean to repeat while loop
         boolean hasComma = false;              // Boolean to check for comma

         // Do while inputDone is false
         while (!inputDone) {

            //Prompt user to input a string
            System.out.println("Enter input string: ");

            // Write string to userInput
            userInput = scnr.nextLine();

            // Exit program if user inputs q
            if((userInput.equals("q"))) {
               inputDone = true;
               break;
            }
            else{

               // Write userInput to buffer
               inSS = new Scanner(userInput);

               // Write first word from buffer
               firstWord = inSS.next();

               // Loop through first word string
               for (i = 0; i < firstWord.length(); ++i) {

                  // If char is a comma, write everything after to secondWord and set inputDone to true
                  if(firstWord.charAt(i) == ',') {
                     secondWord = inSS.next();
                     hasComma = true;
                  }
               }

               // If hasComma is false, return error
               if (!hasComma){
                  System.out.println("Error: No comma in string");
               }
               // Else print first word and second word
               else {
                  System.out.println("First word: " + firstWord);
                  System.out.println("Second word: " + secondWord);
                  System.out.println("");
                  System.out.println("");
               }
            }
         }
        return;
       }
    }

Problems:

I don't know how to remove the comma from the output

If there is no space it errors out

If there is a space between the first word and the comma, it writes firstWord but does not overwrite the previous value for secondWord (or errors if it's the first input given)

I'm taking a beginner's Java course and we have not gone over the .parse() method yet, so it's not really an option at this time.

Thank you in advance!

Body:
So what I've done is probably the laziest and the most rookie way, but it does work.

Use a for loop to check each character of the string for the comma.

char ch;
String str = "";

if(userInput.charAt(userInput.length()-1) == ',')
    System.out.println("Error. You must have a comma here.");
else {
for(int i = 0; i < userInput.length(); i++)
{
    ch = userInput.charAt(i);
    if(ch != ',')
        str += ch;
    else
    {
        firstWord = str;
        secondWord = userInput.substring(i+1);
        break;
    }
}
}

If the selected letter is not a comma, it is added to the temporary string.

If it is a comma, then the temporary string becomes the first word, and the second word is the string after the occurrence of the comma.

if(userInput.charAt(userInput.length()-1) == ',') Handles the exception that may arise if the input is hello ,, or anything that ENDS with a comma.


问:
Using webrtc-58 in Android NDK project - "Undefined reference to CopyOnWriteBuffer" when building with QT
I am trying to build a shared library for Android NDK which is referencing libjingle_peerconnection.so built for Android from webrtc-58, but linker errors appearing:

```<code>MyProject\Libs\webrtc-58\include\webrtc\api\datachannelinterface.h:64: error: undefined reference to 'rtc::CopyOnWriteBuffer::~CopyOnWriteBuffer()'
MyProject\Libs\webrtc-58\include\webrtc\base\copyonwritebuffer.h:48: error: undefined reference to 'rtc::CopyOnWriteBuffer::CopyOnWriteBuffer(unsigned int, unsigned int)'
</code>```

The same output I have building the project on Ubuntu as well as  Windows. When building on Ubuntu, I configured QT Creator to use Android SDK/NDK from webrtc build tools(which were used to build the libjingle_peerconnection

QT Creator 4.4.1 on Qt5.9.2
 webrtc-58 was built on Ubuntu using follwoing configuration

```<code>gn gen out/Debug/arm-v7 --args='target_os="android" is_component_build=false rtc_include_tests=false target_cpu="arm"'
</code>```

I've dumped the unstripped libjingle_peerconnection.so and noticed that contains CopyOnWriteBuffer class implementation:

```<code>001b2bbd t void rtc::CopyOnWriteBuffer::AppendData<unsigned char, (void*)0>(unsigned char const*, unsigned int)
000ee055 t rtc::CopyOnWriteBuffer::EnsureCapacity(unsigned int)
000edf51 t rtc::CopyOnWriteBuffer::CloneDataIfReferenced(unsigned int)
000fafd9 t char* rtc::CopyOnWriteBuffer::data<char, (void*)0>()
000fae61 t unsigned char* rtc::CopyOnWriteBuffer::data<unsigned char, (void*)0>()
000eddcd t rtc::CopyOnWriteBuffer::Clear()
00092cd1 t void rtc::CopyOnWriteBuffer::SetData<char, (void*)0>(char const*, unsigned int)
00092cd1 t void rtc::CopyOnWriteBuffer::SetData<unsigned char, (void*)0>(unsigned char const*, unsigned int)
000edb4d t rtc::CopyOnWriteBuffer::SetSize(unsigned int)
000fad19 t rtc::CopyOnWriteBuffer::operator=(rtc::CopyOnWriteBuffer&&)
000ed6f1 t rtc::CopyOnWriteBuffer::CopyOnWriteBuffer(unsigned int)
000ed7d9 t rtc::CopyOnWriteBuffer::CopyOnWriteBuffer(unsigned int, unsigned int)
000ed6e1 t rtc::CopyOnWriteBuffer::CopyOnWriteBuffer(rtc::CopyOnWriteBuffer&&)
0003462f t rtc::CopyOnWriteBuffer::CopyOnWriteBuffer(rtc::CopyOnWriteBuffer const&)
0002f1f7 t rtc::CopyOnWriteBuffer::CopyOnWriteBuffer()
000faa35 t rtc::CopyOnWriteBuffer::CopyOnWriteBuffer<char, (void*)0>(char const*, unsigned int)
000ed6f1 t rtc::CopyOnWriteBuffer::CopyOnWriteBuffer(unsigned int)
000ed7d9 t rtc::CopyOnWriteBuffer::CopyOnWriteBuffer(unsigned int, unsigned int)
000ed6e1 t rtc::CopyOnWriteBuffer::CopyOnWriteBuffer(rtc::CopyOnWriteBuffer&&)
0003462f t rtc::CopyOnWriteBuffer::CopyOnWriteBuffer(rtc::CopyOnWriteBuffer const&)
0002f1f7 t rtc::CopyOnWriteBuffer::CopyOnWriteBuffer()
000faa35 t rtc::CopyOnWriteBuffer::CopyOnWriteBuffer<char, (void*)0>(char const*, unsigned int)
0003452d t rtc::CopyOnWriteBuffer::~CopyOnWriteBuffer()
0003452d t rtc::CopyOnWriteBuffer::~CopyOnWriteBuffer()
</code>```

Content of the MYPROJECT_Core.Pro

```<code>QT  += core xml
QT  -= gui

TARGET = MYPROJECT_Core
TEMPLATE = lib

DEFINES += MYPROJECT_CORE_LIBRARY

DEFINES += QT_DEPRECATED_WARNINGS
DEFINES += NOMINMAX
DEFINES += ENABLE_RTC_EVENT_LOG

QMAKE_CFLAGS_WARN_ON -= -Wall
QMAKE_CXXFLAGS_WARN_ON -= -Wall
CONFIG += warn_off

android {
    CONFIG += c++11
    QMAKE_CXXFLAGS += -std=c++11

    DEFINES += NDEBUG=1
    DEFINES += WEBRTC_POSIX
    DEFINES += WEBRTC_ANDROID

    LIBS += -L$$PWD/../Libs/webrtc-58/lib/android/armeabi-v7a/jni/armeabi-v7a -ljingle_peerconnection_so
    INCLUDEPATH += $$PWD/../Libs/webrtc-58/include
    DEPENDPATH += $$PWD/../Libs/webrtc-58/include
}

SOURCES += \
    main.cpp \
</code>```

答:
I don't know about WebRTC-58, but I know that WebRTC 60 has a script to build the Android libs for you.  From the src/ directory, just run

```<code>python tools_webrtc/android/build_aar.py
</code>```

This will configured everything for you, build for x86, x86_64, arm, and arm64, and combine them into libwebrtc.aar which you can add to your android project.

Body:
I am trying to build a shared library for Android NDK which is referencing libjingle_peerconnection.so built for Android from webrtc-58, but linker errors appearing:

MyProject\Libs\webrtc-58\include\webrtc\api\datachannelinterface.h:64: error: undefined reference to 'rtc::CopyOnWriteBuffer::~CopyOnWriteBuffer()'
MyProject\Libs\webrtc-58\include\webrtc\base\copyonwritebuffer.h:48: error: undefined reference to 'rtc::CopyOnWriteBuffer::CopyOnWriteBuffer(unsigned int, unsigned int)'

The same output I have building the project on Ubuntu as well as  Windows. When building on Ubuntu, I configured QT Creator to use Android SDK/NDK from webrtc build tools(which were used to build the libjingle_peerconnection

QT Creator 4.4.1 on Qt5.9.2
 webrtc-58 was built on Ubuntu using follwoing configuration

gn gen out/Debug/arm-v7 --args='target_os="android" is_component_build=false rtc_include_tests=false target_cpu="arm"'

I've dumped the unstripped libjingle_peerconnection.so and noticed that contains CopyOnWriteBuffer class implementation:

001b2bbd t void rtc::CopyOnWriteBuffer::AppendData<unsigned char, (void*)0>(unsigned char const*, unsigned int)
000ee055 t rtc::CopyOnWriteBuffer::EnsureCapacity(unsigned int)
000edf51 t rtc::CopyOnWriteBuffer::CloneDataIfReferenced(unsigned int)
000fafd9 t char* rtc::CopyOnWriteBuffer::data<char, (void*)0>()
000fae61 t unsigned char* rtc::CopyOnWriteBuffer::data<unsigned char, (void*)0>()
000eddcd t rtc::CopyOnWriteBuffer::Clear()
00092cd1 t void rtc::CopyOnWriteBuffer::SetData<char, (void*)0>(char const*, unsigned int)
00092cd1 t void rtc::CopyOnWriteBuffer::SetData<unsigned char, (void*)0>(unsigned char const*, unsigned int)
000edb4d t rtc::CopyOnWriteBuffer::SetSize(unsigned int)
000fad19 t rtc::CopyOnWriteBuffer::operator=(rtc::CopyOnWriteBuffer&&)
000ed6f1 t rtc::CopyOnWriteBuffer::CopyOnWriteBuffer(unsigned int)
000ed7d9 t rtc::CopyOnWriteBuffer::CopyOnWriteBuffer(unsigned int, unsigned int)
000ed6e1 t rtc::CopyOnWriteBuffer::CopyOnWriteBuffer(rtc::CopyOnWriteBuffer&&)
0003462f t rtc::CopyOnWriteBuffer::CopyOnWriteBuffer(rtc::CopyOnWriteBuffer const&)
0002f1f7 t rtc::CopyOnWriteBuffer::CopyOnWriteBuffer()
000faa35 t rtc::CopyOnWriteBuffer::CopyOnWriteBuffer<char, (void*)0>(char const*, unsigned int)
000ed6f1 t rtc::CopyOnWriteBuffer::CopyOnWriteBuffer(unsigned int)
000ed7d9 t rtc::CopyOnWriteBuffer::CopyOnWriteBuffer(unsigned int, unsigned int)
000ed6e1 t rtc::CopyOnWriteBuffer::CopyOnWriteBuffer(rtc::CopyOnWriteBuffer&&)
0003462f t rtc::CopyOnWriteBuffer::CopyOnWriteBuffer(rtc::CopyOnWriteBuffer const&)
0002f1f7 t rtc::CopyOnWriteBuffer::CopyOnWriteBuffer()
000faa35 t rtc::CopyOnWriteBuffer::CopyOnWriteBuffer<char, (void*)0>(char const*, unsigned int)
0003452d t rtc::CopyOnWriteBuffer::~CopyOnWriteBuffer()
0003452d t rtc::CopyOnWriteBuffer::~CopyOnWriteBuffer()

Content of the MYPROJECT_Core.Pro

QT  += core xml
QT  -= gui

TARGET = MYPROJECT_Core
TEMPLATE = lib

DEFINES += MYPROJECT_CORE_LIBRARY

DEFINES += QT_DEPRECATED_WARNINGS
DEFINES += NOMINMAX
DEFINES += ENABLE_RTC_EVENT_LOG

QMAKE_CFLAGS_WARN_ON -= -Wall
QMAKE_CXXFLAGS_WARN_ON -= -Wall
CONFIG += warn_off

android {
    CONFIG += c++11
    QMAKE_CXXFLAGS += -std=c++11

    DEFINES += NDEBUG=1
    DEFINES += WEBRTC_POSIX
    DEFINES += WEBRTC_ANDROID

    LIBS += -L$$PWD/../Libs/webrtc-58/lib/android/armeabi-v7a/jni/armeabi-v7a -ljingle_peerconnection_so
    INCLUDEPATH += $$PWD/../Libs/webrtc-58/include
    DEPENDPATH += $$PWD/../Libs/webrtc-58/include
}

SOURCES += \
    main.cpp \

Body:
I don't know about WebRTC-58, but I know that WebRTC 60 has a script to build the Android libs for you.  From the src/ directory, just run

python tools_webrtc/android/build_aar.py

This will configured everything for you, build for x86, x86_64, arm, and arm64, and combine them into libwebrtc.aar which you can add to your android project.


问:
Maven - Using Dependency Management
We need to modularize our project structure. For that we are using from beginning the Build-Management-System Maven. The projects uses internal library. We want use the benefit of the dependency Managent of Maven and override all used internal library with one version that is definied there. My question is very simple, but  not clear for me. Maybe you can help me with that.

I have two types of parent-poms.

(1) Parent.pom -> Set placeholder for the versions and define them

(2) Child.pom -> Build and copy modules to some place

Every project is a child from (2).

My question is: Where is the best place to put the dependency Management? In parent.pom or in child.pom? I found out, that using depManagement in parent.pom does not support to remove the version tag in the dependencies in the projects.

So my question, where is the best place to put the dependency Management?

Thanks.

答:
I would use bill of materials(BOM) for dependency managment.
You could get more about BOM from:

How to use BOM file with Maven?

Maven BOM [Bill Of Materials] Dependency

The structure that I would suggest:

Parent project:

```<code>    <groupId>bom.test</groupId>
    <artifactId>parent</artifactId>
    <packaging>pom</packaging>
    <version>1.0-SNAPSHOT</version>
    <modules>
        <module>childA</module>
    </modules>

    <dependencyManagement>
        <dependencies>
            <dependency>
                <groupId>org.springframework</groupId>
                <artifactId>spring-framework-bom</artifactId>
                <version>4.3.8.RELEASE</version>
                <type>pom</type>
                <scope>import</scope>
            </dependency>
        </dependencies>
    </dependencyManagement>
</code>```

As you could see here I've used spring BOM.

Child A project:

```<code>    <parent>
        <artifactId>parent</artifactId>
        <groupId>bom.test</groupId>
        <version>1.0-SNAPSHOT</version>
    </parent>
    <modelVersion>4.0.0</modelVersion>

    <artifactId>childA</artifactId>
    <dependencies>
        <dependency>
            <groupId>org.springframework</groupId>
            <artifactId>spring-web</artifactId>
        </dependency>
        <dependency>
            <groupId>org.springframework</groupId>
            <artifactId>spring-test</artifactId>
            <version>3.0.0.RELEASE</version>
        </dependency>
    </dependencies>
</code>```

As you see from child dependencies I do not specify spring-web version, it is taken from BOM. However spring-test version was specified. Let's check how maven sees it.

Checking bom content by

```<code>mvn help:effective-pom

.....
      <dependency>
        <groupId>org.springframework</groupId>
        <artifactId>spring-test</artifactId>
        <version>4.3.8.RELEASE</version>
      </dependency>
      <dependency>
        <groupId>org.springframework</groupId>
        <artifactId>spring-web</artifactId>
        <version>4.3.8.RELEASE</version>
      </dependency>
    </dependencies>
  </dependencyManagement>
.....
</code>```

So BOM version is 4.3.8

Let's check dependency managment to be sure that moduleA uses this version for web and overriden for test.

```<code>mvn dependency:tree

[INFO] bom.test:childA:jar:1.0-SNAPSHOT
[INFO] +- org.springframework:spring-web:jar:4.3.8.RELEASE:compile
[INFO] |  +- org.springframework:spring-aop:jar:4.3.8.RELEASE:compile
[INFO] \- org.springframework:spring-test:jar:3.0.0.RELEASE:compile
</code>```

Title: Maven - Using Dependency Management

Body:
I would use bill of materials(BOM) for dependency managment.
You could get more about BOM from:

How to use BOM file with Maven?

Maven BOM [Bill Of Materials] Dependency

The structure that I would suggest:

Parent project:

    <groupId>bom.test</groupId>
    <artifactId>parent</artifactId>
    <packaging>pom</packaging>
    <version>1.0-SNAPSHOT</version>
    <modules>
        <module>childA</module>
    </modules>

    <dependencyManagement>
        <dependencies>
            <dependency>
                <groupId>org.springframework</groupId>
                <artifactId>spring-framework-bom</artifactId>
                <version>4.3.8.RELEASE</version>
                <type>pom</type>
                <scope>import</scope>
            </dependency>
        </dependencies>
    </dependencyManagement>

As you could see here I've used spring BOM.

Child A project:

    <parent>
        <artifactId>parent</artifactId>
        <groupId>bom.test</groupId>
        <version>1.0-SNAPSHOT</version>
    </parent>
    <modelVersion>4.0.0</modelVersion>

    <artifactId>childA</artifactId>
    <dependencies>
        <dependency>
            <groupId>org.springframework</groupId>
            <artifactId>spring-web</artifactId>
        </dependency>
        <dependency>
            <groupId>org.springframework</groupId>
            <artifactId>spring-test</artifactId>
            <version>3.0.0.RELEASE</version>
        </dependency>
    </dependencies>

As you see from child dependencies I do not specify spring-web version, it is taken from BOM. However spring-test version was specified. Let's check how maven sees it.

Checking bom content by

mvn help:effective-pom

.....
      <dependency>
        <groupId>org.springframework</groupId>
        <artifactId>spring-test</artifactId>
        <version>4.3.8.RELEASE</version>
      </dependency>
      <dependency>
        <groupId>org.springframework</groupId>
        <artifactId>spring-web</artifactId>
        <version>4.3.8.RELEASE</version>
      </dependency>
    </dependencies>
  </dependencyManagement>
.....

So BOM version is 4.3.8

Let's check dependency managment to be sure that moduleA uses this version for web and overriden for test.

mvn dependency:tree

[INFO] bom.test:childA:jar:1.0-SNAPSHOT
[INFO] +- org.springframework:spring-web:jar:4.3.8.RELEASE:compile
[INFO] |  +- org.springframework:spring-aop:jar:4.3.8.RELEASE:compile
[INFO] \- org.springframework:spring-test:jar:3.0.0.RELEASE:compile


问:
function switching between singular and plural?
I'm looking for a function that given a string it switches the string to singular/plural. I need it to work for european languages other than English.

Are there any functions that can do the trick? (Given a string to convert and the language?)

Thanks

答:
There is no function built into PHP for this type of operation.  There are, however, some tools that you may be able to use to help accomplish your goal.

There is an unofficial Google Dictionary API which contains information on plurals.  You can read more about that method here.  You'll need to parse a JSON object to find the appropriate items and this method tends to be a little bit slow.

The other method that comes to mind is to use aspell, or one of its relatives.  I'm not sure how accurate the dictionaries are for languages other than English but I've used aspell to expand words into their various forms.

I know this is not the most helpful answer, but hopefully it gives you a general direction to search in.

ContentLicense: CC BY-SA 4.0

ContentLicense: CC BY-SA 2.5


问:
How can I create a user-friendly timestamp?
I am currently studying jQuery. What I am building now is called "twittler", which uses the jQuery and moment.js libraries.

I wrote the following code, but the time of twit creation is always "a few seconds ago". What is the problem?

```<code><script>
    $(document).ready(() => {
      let index = 0, lastIndex = streams.home.length;
      let showTweet = () => {
        for (; index < lastIndex; index++) {
          let tweet = streams.home[index];
          let $tweet = $(
            `<div class="w3-card-4 w3-section">` +
            `<footer class="w3-container w3-opacity w3-right-align">` +
            `<h6 class="time" id="${tweet.created_at.getTime()}"></h6>` +
            `</footer>` +
            `</div>`
          );
          $tweet.prependTo($(".main-contents"));
        }
      };
      let lastIndexUpdate = () => {
        lastIndex = streams.home.length;
      };
      let timeUpdate = () => {
        $("h6.time").text(moment($("h6.time").attr("id"), "x").fromNow());
      };
      showTweet();
      setInterval(showTweet, 1000);
      setInterval(lastIndexUpdate, 1000);
      setInterval(timeUpdate, 1000);
    });
  </script>
</code>```

答:
$("h6.time").attr("id") will always get value of first matching selector only.

You need instance specific values

You can use text(function) which will expose each instance in the callback

```<code>$("h6.time").text(function(){
    return moment(this.id, "x").fromNow();
});
</code>```

Body:
$("h6.time").attr("id") will always get value of first matching selector only.

You need instance specific values

You can use text(function) which will expose each instance in the callback

$("h6.time").text(function(){
    return moment(this.id, "x").fromNow();
});


问:
fill up empty values with same value of another column in pandas dataframe
i have a pandas dataframe like the following:

How do I fill up the empty cells with same policy numbers for same product type as they exist?

Any suggestion would be very much appreciated. Thank you

Sorry for the confusion, I am adding my sample dataframe now:

sample=[{'POLICY NUMBER':' ','PRODUCT TYPE':'MED'},{'POLICY NUMBER':' ','PRODUCT TYPE':'MED'},{'POLICY NUMBER':'433M49763','PRODUCT TYPE':'MED'},{'POLICY NUMBER':'433M86968','PRODUCT TYPE':'MED'},{'POLICY NUMBER':' ','PRODUCT TYPE':'TED'},{'POLICY NUMBER':'566D158635 ','PRODUCT TYPE':'TED'},{'POLICY NUMBER':'655D158635','PRODUCT TYPE':'TED'},{'POLICY NUMBER':'789D158635','PRODUCT TYPE':'TED'}]

pd.DataFrame(sample)

please note that the empty cells have " " in them too, they are not NaN across the whole dataframe

Adding to the question above. If I have the altered dataframe as above. How do i get to the following dataframe:

答:
I think you need groupby + transform:

If only one same category per group and no data are empty strings :

```<code>df['POLICY NUMBER'] = (df.groupby('PRODUCT TYPE')['POLICY NUMBER']
                         .transform(lambda x: x[x != ''].iat[0]))

print (df)
  POLICY NUMBER PRODUCT TYPE
0     433M86968          MED
1     433M86968          MED
2     433M86968          MED
3     433M86968          MED
4    566D158635          TED
5    566D158635          TED
6    566D158635          TED
7    566D158635          TED
</code>```

Or if posible there are not always empty stings, but sometimes there are wtrailing whitespaces, need strip:

```<code>df['POLICY NUMBER'] = (df['POLICY NUMBER'].str.strip().groupby(df['PRODUCT TYPE'])
                                  .transform(lambda x: x[x != ''].iat[0]))

print (df)
  POLICY NUMBER PRODUCT TYPE
0     433M86968          MED
1     433M86968          MED
2     433M86968          MED
3     433M86968          MED
4    566D158635          TED
5    566D158635          TED
6    566D158635          TED
7    566D158635          TED
</code>```

Solution with sorting and transform last value:

```<code>df['POLICY NUMBER'] = (df.sort_values(['PRODUCT TYPE','POLICY NUMBER'])
                         .groupby('PRODUCT TYPE')['POLICY NUMBER']
                         .transform('last'))
print (df)
  POLICY NUMBER PRODUCT TYPE
0     433M86968          MED
1     433M86968          MED
2     433M86968          MED
3     433M86968          MED
4    566D158635          TED
5    566D158635          TED
6    566D158635          TED
7    566D158635          TED
</code>```

EDIT: You need replace empty strings by NaNs and then use bfill for back forward filling NaNs with ffill for forward fillin NaNs:

```<code>df['POLICY NUMBER'] = (df['POLICY NUMBER'].str.strip()
                                          .replace('',np.nan)
                                          .groupby(df['PRODUCT TYPE'])
                                          .transform(lambda x: x.bfill().ffill()))

print (df)
  POLICY NUMBER PRODUCT TYPE
0     433M49763          MED
1     433M49763          MED
2     433M49763          MED
3     433M86968          MED
4    566D158635          TED
5    566D158635          TED
6    566D158635          TED
7    789D158635          TED
</code>```

Body:
I think you need groupby + transform:

If only one same category per group and no data are empty strings :

df['POLICY NUMBER'] = (df.groupby('PRODUCT TYPE')['POLICY NUMBER']
                         .transform(lambda x: x[x != ''].iat[0]))

print (df)
  POLICY NUMBER PRODUCT TYPE
0     433M86968          MED
1     433M86968          MED
2     433M86968          MED
3     433M86968          MED
4    566D158635          TED
5    566D158635          TED
6    566D158635          TED
7    566D158635          TED

Or if posible there are not always empty stings, but sometimes there are wtrailing whitespaces, need strip:

df['POLICY NUMBER'] = (df['POLICY NUMBER'].str.strip().groupby(df['PRODUCT TYPE'])
                                  .transform(lambda x: x[x != ''].iat[0]))

print (df)
  POLICY NUMBER PRODUCT TYPE
0     433M86968          MED
1     433M86968          MED
2     433M86968          MED
3     433M86968          MED
4    566D158635          TED
5    566D158635          TED
6    566D158635          TED
7    566D158635          TED

Solution with sorting and transform last value:

df['POLICY NUMBER'] = (df.sort_values(['PRODUCT TYPE','POLICY NUMBER'])
                         .groupby('PRODUCT TYPE')['POLICY NUMBER']
                         .transform('last'))
print (df)
  POLICY NUMBER PRODUCT TYPE
0     433M86968          MED
1     433M86968          MED
2     433M86968          MED
3     433M86968          MED
4    566D158635          TED
5    566D158635          TED
6    566D158635          TED
7    566D158635          TED

EDIT: You need replace empty strings by NaNs and then use bfill for back forward filling NaNs with ffill for forward fillin NaNs:

df['POLICY NUMBER'] = (df['POLICY NUMBER'].str.strip()
                                          .replace('',np.nan)
                                          .groupby(df['PRODUCT TYPE'])
                                          .transform(lambda x: x.bfill().ffill()))

print (df)
  POLICY NUMBER PRODUCT TYPE
0     433M49763          MED
1     433M49763          MED
2     433M49763          MED
3     433M86968          MED
4    566D158635          TED
5    566D158635          TED
6    566D158635          TED
7    789D158635          TED


问:
Node.JS Dynamodb memory issue with put
Right now I have this problem with using Dynamodb's put method on the document client. When I run my program right now with the put method commented out, the memory starts at 70MB, jumps to 90MB, then proceeds to settle down to around 65MB. Uncommented out the memory for my program jumps to 90MB and keeps growing constantly.

```<code>var params;

for (var i = 0; i < tuples.length; i++){
    if(tuples[i][1] != ""){
        params = {
            TableName: "wordTable2",
                Item:{
                    "word":tuples[i][1],
                    "url":tuples[i][0],
                    "info":tuples[i][2]
                }
            };

        var dynamobd = new AWS.DynamoDB.DocumentClient();
        dynamobd.put(params, function(err, data){
            //if(err) console.error("Unable to add item. Error JSON:", JSON.stringify(err, null, 2));
            //else    console.log("Added item:", JSON.stringify(data, null, 2));
        });
        dynamobd = null;
        delete dynamobd;
    }
    //console.log(tuples[i][0] + " " + tuples[i][1] + " " + tuples[i][2]);
}
delete params;
delete bodyText;
delete holder;
delete tuples;
</code>```

I do not know how to make an effective for loop to add all items to on parmas. If I could do that I would only have to send one put method for each URL instead of each word which might help. I also tried to put multiple items in the params, as much as 10, but that seems to make little difference.

For the full code go to
https://pastebin.com/iQ1h0jjN

答:
I'm using the DynamoDB api without any issue but what stands out to me in your code, and which has been mentioned by John Veldboom, is the memory management your doing. The 1st thing I would do is declare and initialize your DynamoDB client early on and never again. Its just a an HTTP rest client under the hood. You should be fine just setting it once along with your other require('.....') dependencies

I would also remove all the delete commands and variable assignments to null that your doing. Your for loop completes when its ran through every command but not necessarily after each DynamoDB has returned since those callbacks are being fired asynchronously.

```<code>var dynamobd = new AWS.DynamoDB.DocumentClient();

var params;

for (var i = 0; i < tuples.length; i++){
    if(tuples[i][1] != ""){
        params = {
            TableName: "wordTable2",
                Item:{
                    "word":tuples[i][1],
                    "url":tuples[i][0],
                    "info":tuples[i][2]
                }
            };

        dynamobd.put(params, function(err, data){
            if(err) console.error("Unable to add item. Error JSON:", JSON.stringify(err, null, 2));
            else    console.log("Added item:", JSON.stringify(data, null, 2));
        });
    }
    console.log(tuples[i][0] + " " + tuples[i][1] + " " + tuples[i][2]);
}
//Your for loop is done but that does not mean all the DynamoDB callbacks have returned yet.
</code>```

Title: Node.JS Dynamodb memory issue with put

Body:
Right now I have this problem with using Dynamodb's put method on the document client. When I run my program right now with the put method commented out, the memory starts at 70MB, jumps to 90MB, then proceeds to settle down to around 65MB. Uncommented out the memory for my program jumps to 90MB and keeps growing constantly.

var params;

for (var i = 0; i < tuples.length; i++){
    if(tuples[i][1] != ""){
        params = {
            TableName: "wordTable2",
                Item:{
                    "word":tuples[i][1],
                    "url":tuples[i][0],
                    "info":tuples[i][2]
                }
            };

        var dynamobd = new AWS.DynamoDB.DocumentClient();
        dynamobd.put(params, function(err, data){
            //if(err) console.error("Unable to add item. Error JSON:", JSON.stringify(err, null, 2));
            //else    console.log("Added item:", JSON.stringify(data, null, 2));
        });
        dynamobd = null;
        delete dynamobd;
    }
    //console.log(tuples[i][0] + " " + tuples[i][1] + " " + tuples[i][2]);
}
delete params;
delete bodyText;
delete holder;
delete tuples;

I do not know how to make an effective for loop to add all items to on parmas. If I could do that I would only have to send one put method for each URL instead of each word which might help. I also tried to put multiple items in the params, as much as 10, but that seems to make little difference.

For the full code go to
https://pastebin.com/iQ1h0jjN

Body:
I'm using the DynamoDB api without any issue but what stands out to me in your code, and which has been mentioned by John Veldboom, is the memory management your doing. The 1st thing I would do is declare and initialize your DynamoDB client early on and never again. Its just a an HTTP rest client under the hood. You should be fine just setting it once along with your other require('.....') dependencies

I would also remove all the delete commands and variable assignments to null that your doing. Your for loop completes when its ran through every command but not necessarily after each DynamoDB has returned since those callbacks are being fired asynchronously.

var dynamobd = new AWS.DynamoDB.DocumentClient();

var params;

for (var i = 0; i < tuples.length; i++){
    if(tuples[i][1] != ""){
        params = {
            TableName: "wordTable2",
                Item:{
                    "word":tuples[i][1],
                    "url":tuples[i][0],
                    "info":tuples[i][2]
                }
            };

        dynamobd.put(params, function(err, data){
            if(err) console.error("Unable to add item. Error JSON:", JSON.stringify(err, null, 2));
            else    console.log("Added item:", JSON.stringify(data, null, 2));
        });
    }
    console.log(tuples[i][0] + " " + tuples[i][1] + " " + tuples[i][2]);
}
//Your for loop is done but that does not mean all the DynamoDB callbacks have returned yet.


问:
C++: How does a getter return a pointer to a dynamically allocated array without giving direct acces to it?
So the question is:

If I have a program something like:

```<code>class Ticket
{
 private:
    char* concertName;
 public:
    Ticket(char* name="Concert");
    char* getConcertName();
}
int main()
{
   char* test;
   Ticket t1;
   test=t1.getConcertName();
   test[1]='A';
}
Ticket::Ticket(char* name)
{
   this->concertName=new char[strlen(Concert)+1];
   strcpy(this->concertName,name);
}
Ticket::getConcertName()
{
  return this->concertName;
}
</code>```

What would the getter return? My intuition says that it returns the pointer to the first element of the memory block that I allocated earlier for concertName, and so I can change the array's values without using the setter, directly from main like I did in the example.

It works to change it, but the idea of the private area is for restricting the access from outside the object to it's attributes if a setter or a getter isn't used.

What if we had a static field like: static unsigned int* arrayI; and a static method that worked like a getter returning the value from arrayI?

答:
I think you're asking for const:

Adding const to your getter will prevent the caller to modify the pointee.

```<code>#include <cstdio>
class Ticket
{
 private:
    char concertName[sizeof("Concert")];
 public:
    Ticket(const char *name = "Concert");
    const char* getConcertName() const;
};

int main()
{
   const char *test;
   Ticket t1;
   test = t1.getConcertName(); //OK with const
   //test[1]='A'; // would not compile
}
Ticket::Ticket(const char *name)
{
   snprintf(concertName, sizeof(concertName), "%s", name);
}
const char *Ticket::getConcertName() const
{
  return concertName;
}
</code>```

Body:
So the question is:

If I have a program something like:

class Ticket
{
 private:
    char* concertName;
 public:
    Ticket(char* name="Concert");
    char* getConcertName();
}
int main()
{
   char* test;
   Ticket t1;
   test=t1.getConcertName();
   test[1]='A';
}
Ticket::Ticket(char* name)
{
   this->concertName=new char[strlen(Concert)+1];
   strcpy(this->concertName,name);
}
Ticket::getConcertName()
{
  return this->concertName;
}

What would the getter return? My intuition says that it returns the pointer to the first element of the memory block that I allocated earlier for concertName, and so I can change the array's values without using the setter, directly from main like I did in the example.

It works to change it, but the idea of the private area is for restricting the access from outside the object to it's attributes if a setter or a getter isn't used.

What if we had a static field like: static unsigned int* arrayI; and a static method that worked like a getter returning the value from arrayI?

Body:
I think you're asking for const:

Adding const to your getter will prevent the caller to modify the pointee.

#include <cstdio>
class Ticket
{
 private:
    char concertName[sizeof("Concert")];
 public:
    Ticket(const char *name = "Concert");
    const char* getConcertName() const;
};

int main()
{
   const char *test;
   Ticket t1;
   test = t1.getConcertName(); //OK with const
   //test[1]='A'; // would not compile
}
Ticket::Ticket(const char *name)
{
   snprintf(concertName, sizeof(concertName), "%s", name);
}
const char *Ticket::getConcertName() const
{
  return concertName;
}


问:
Using filebeat with elasticsearch
I am not getting that how to run this filebeat in order to send output to elasticsearch.

This is from the filebeat.yml file,

```<code>- input_type: log

  # Paths that should be crawled and fetched. Glob based paths.
  paths:
    - /var/log/nginx/access.log

output.elasticsearch:
  # Array of hosts to connect to.
    hosts: ["localhost:9200"]
    index: 'filebeat_nginx'
</code>```

elasticsearch is up and running.

Now, how to run filebeat to send the log info to elasticsearch.

If I go to bin directory of filebeat, and run this command,

```<code>luvpreet@DHARI-Inspiron-3542:/usr/share/filebeat/bin$ sudo ./filebeat -configtest -e
</code>```

then it shows ,

```<code>filebeat2017/04/19 06:54:22.450440 beat.go:339: CRIT Exiting: error loading config file: stat filebeat.yml: no such file or directory
Exiting: error loading config file: stat filebeat.yml: no such file or directory
</code>```

The filebeat.yml file is in the /etc/filebeat folder. How to run it ?
Please clarify the process to run this with elasticsearch.

答: If you have made the necessary arrangements in /etc/filebeat/filebeat.yml file, you can use this command "service filebeat start". After the service is started you can control service this command "service filebeat status". If there is an error, you can see errors.</p>

Title: Using filebeat with elasticsearch

Body:
I am not getting that how to run this filebeat in order to send output to elasticsearch.

This is from the filebeat.yml file,

- input_type: log

  # Paths that should be crawled and fetched. Glob based paths.
  paths:
    - /var/log/nginx/access.log

output.elasticsearch:
  # Array of hosts to connect to.
    hosts: ["localhost:9200"]
    index: 'filebeat_nginx'

elasticsearch is up and running.

Now, how to run filebeat to send the log info to elasticsearch.

If I go to bin directory of filebeat, and run this command,

luvpreet@DHARI-Inspiron-3542:/usr/share/filebeat/bin$ sudo ./filebeat -configtest -e

then it shows ,

filebeat2017/04/19 06:54:22.450440 beat.go:339: CRIT Exiting: error loading config file: stat filebeat.yml: no such file or directory
Exiting: error loading config file: stat filebeat.yml: no such file or directory

The filebeat.yml file is in the /etc/filebeat folder. How to run it ?
Please clarify the process to run this with elasticsearch.


问:
How to save a DataFrame as compressed (gzipped) CSV?
I use Spark 1.6.0 and Scala.

I want to save a DataFrame as compressed CSV format.

Here is what I have so far (assume I already have df and sc as SparkContext):

```<code>//set the conf to the codec I want
sc.getConf.set("spark.hadoop.mapred.output.compress", "true")
sc.getConf.set("spark.hadoop.mapred.output.compression.codec", "true")
sc.getConf.set("spark.hadoop.mapred.output.compression.codec", "org.apache.hadoop.io.compress.GzipCodec")
sc.getConf.set("spark.hadoop.mapred.output.compression.type", "BLOCK")

df.write
  .format("com.databricks.spark.csv")
  .save(my_directory)
</code>```

The output is not in gz format.

答:
To write the CSV file with headers and rename the part-000 file to .csv.gzip

```<code>DF.coalesce(1).write.format("com.databricks.spark.csv").mode("overwrite")
.option("header","true")
.option("codec",org.apache.hadoop.io.compress.GzipCodec").save(tempLocationFileName)

copyRename(tempLocationFileName, finalLocationFileName)

def copyRename(srcPath: String, dstPath: String): Unit =  {
  val hadoopConfig = new Configuration()
  val hdfs = FileSystem.get(hadoopConfig)
  FileUtil.copyMerge(hdfs, new Path(srcPath), hdfs, new Path(dstPath), true, hadoopConfig, null)
  // the "true" setting deletes the source files once they are merged into the new output
}
</code>```

If you don't need the header then set it to false and you wouldn't need to do the coalesce either. It will be faster to write too.

Body:
I use Spark 1.6.0 and Scala.

I want to save a DataFrame as compressed CSV format.

Here is what I have so far (assume I already have df and sc as SparkContext):

//set the conf to the codec I want
sc.getConf.set("spark.hadoop.mapred.output.compress", "true")
sc.getConf.set("spark.hadoop.mapred.output.compression.codec", "true")
sc.getConf.set("spark.hadoop.mapred.output.compression.codec", "org.apache.hadoop.io.compress.GzipCodec")
sc.getConf.set("spark.hadoop.mapred.output.compression.type", "BLOCK")

df.write
  .format("com.databricks.spark.csv")
  .save(my_directory)

The output is not in gz format.

Body:
To write the CSV file with headers and rename the part-000 file to .csv.gzip

DF.coalesce(1).write.format("com.databricks.spark.csv").mode("overwrite")
.option("header","true")
.option("codec",org.apache.hadoop.io.compress.GzipCodec").save(tempLocationFileName)

copyRename(tempLocationFileName, finalLocationFileName)

def copyRename(srcPath: String, dstPath: String): Unit =  {
  val hadoopConfig = new Configuration()
  val hdfs = FileSystem.get(hadoopConfig)
  FileUtil.copyMerge(hdfs, new Path(srcPath), hdfs, new Path(dstPath), true, hadoopConfig, null)
  // the "true" setting deletes the source files once they are merged into the new output
}

If you don't need the header then set it to false and you wouldn't need to do the coalesce either. It will be faster to write too.


问:
Are fonts only white and transparent?
I am using Freetype to decode TTF files then render the glyphs onto a texture.
Should all pixels in a character be only white or transparent(255, 255, 255, 255 or 0, 0, 0, 0) or are they able to be gray or translucent(ex 140, 140, 140, 255 or 255, 255, 255, 130)? </p>

答:
This question doesn't make a lot of sense: an opentype font with ttf outlines gives you the vector outline for glyphs, and if there is no explicit colour information inside the font (in the form of a COLR table), there is literally no colour that the pixels of the rasterized vector "should be". Not in terms of colours, and not in terms of alpha blending (antialiasing).

These things are choices that you make, or users of your application make, and are passed to Freetype as instructions on how to go about the rasterizing operation.

Title: Are fonts only white and transparent?


问:
SQL: Filter equal and not equal queries
Tried below queries, but none of them works - result was blank. I want to filter the equal and not equal in one query, using SQL Server 2012.

Query #1

```<code>Select *
from MainDB
where STATES = 'CA'
  and FILECODE = 'WER'
  and not SOURCE = 'Export'
</code>```

Query #2

```<code>Select *
from MainDB
where STATES = 'CA'
  and FILECODE = 'WER'
  and SOURCE != 'Export'
</code>```

Query #3

```<code>Select *
from MainDB
where STATES = 'CA'
  and FILECODE = 'WER'
  and SOURCE <> 'Export'
</code>```

答:
Try using NOT IN

```<code>Select *
    from MainDB
    where STATES = 'CA'
      and FILECODE = 'WER'
      and SOURCE NOT IN ('Export')
</code>```

Title: SQL: Filter equal and not equal queries

Body:
Tried below queries, but none of them works - result was blank. I want to filter the equal and not equal in one query, using SQL Server 2012.

Query #1

Select *
from MainDB
where STATES = 'CA'
  and FILECODE = 'WER'
  and not SOURCE = 'Export'

Query #2

Select *
from MainDB
where STATES = 'CA'
  and FILECODE = 'WER'
  and SOURCE != 'Export'

Query #3

Select *
from MainDB
where STATES = 'CA'
  and FILECODE = 'WER'
  and SOURCE <> 'Export'

Body:
Try using NOT IN

Select *
    from MainDB
    where STATES = 'CA'
      and FILECODE = 'WER'
      and SOURCE NOT IN ('Export')


答:
The usual way to prevent changes of pointer referenced memory is to use the const keyword:

```<code>const char* getConcertName() const;
</code>```

The const after the member function indicates it can also be used with constant references to Ticket.

With this declaration the client is forced to use a const char* to receive the getter's result:

```<code>const char* test;
Ticket t1;
test=t1.getConcertName();
</code>```

And trying to change the value will result in an appropriate compiler error message:

```<code>test[1]='A'; // <<<<<<<<<<<<<<<<< Compiler error
</code>```

As a side note:

Don't manage memory allocation yourself. Instead of raw char* pointers use std::string.

Title: C++: How does a getter return a pointer to a dynamically allocated array without giving direct acces to it?

Body:
The usual way to prevent changes of pointer referenced memory is to use the const keyword:

const char* getConcertName() const;

The const after the member function indicates it can also be used with constant references to Ticket.

With this declaration the client is forced to use a const char* to receive the getter's result:

const char* test;
Ticket t1;
test=t1.getConcertName();

And trying to change the value will result in an appropriate compiler error message:

test[1]='A'; // <<<<<<<<<<<<<<<<< Compiler error

As a side note:

Don't manage memory allocation yourself. Instead of raw char* pointers use std::string.


问:
Implementing a simple product dropdown in ASP.NET MVC
What are the different or best ways I can implement a simple product dropdown in ASP.NET MVC, that redirect the user to a new product when they pick from the dropdown ?

I have currently have my primary mapping rule :

```<code> routes.MapRoute(
              "Product",
              "Products/{sku}",
              new { controller = "Products", action = "ViewProduct", sku = "1001" }
           );
</code>```

This allows me to enter a URL like this to view my product:

```<code>/Products/1002
</code>```

I have a dropdown on my page which represents a list of products, and allows you to select form the list. (The sku parameter is the same name as the parameter in my controller's ViewProduct method) :

```<code><% using (Html.BeginForm("ViewProduct", "Products"))
   { %>

    <%= Html.DropDownList("sku", ViewData.Model.ProductsList)%>
    <%= Html.SubmitButton() %>  <!-- just using a button now since its easier -->

<% } %>
</code>```

This form targets the 'ViewProduct' command that I have in my controller (which is a full view that renders a product's information page).

The problem is that the HTML generated (when I view the HTML for /Products/1002) looks like this:

```<code><form action="/Products/1002" method="post">

    <select id="sku" name="sku">
        <option value="1003">Product 1003</option>
        <option value="1002">Product 1002</option>
        <option value="2001">Product 2001</option>
    </select>

<input type="submit" />
</form>
</code>```

It has gone and created the action link based upon the current URL (i guess it really had no choice). The problem is that when my controller is called after clicking 'Submit' it just goes ahead and fetches product 1002 again - and doesnt get overridden by the 'sku' parameter from the form.

Now, the actual value is available in Request.Params["sku"], but obvously its a pretty horrible practice to go and try to get it from there.

One extremely convoluted solution is as follows - create a different routing rule which hits a different controller method RedirectProduct.

```<code>routes.MapRoute(
           "Product Redirect",
           "Products/RedirectProduct",
           new { controller = "Products", action = "RedirectProduct" }
        );
</code>```

Then the action to my form can simply be :

```<code><% using (Html.BeginForm("RedirectProduct", "Products")) { %>
</code>```

This hits my controller method, which has access to 'sku' (the correct one I want that is coming from the form params). The controller method just redirects to /Products/XXX .

```<code>public ActionResult RedirectProduct(string sku)
        {
            return new RedirectResult("/Products/" + sku);
        }
</code>```

I don't like this solution at all - but I wanted to at least present what I had so far. I dont like adding extra mapping rules like this, and having to create different action names when I really just have one.

I'm sure theres 50 different ways I could do this -- hence me asking the question on stackoverflow -- to try and figure which is best. Unfortunately at this time the documentation for Forms handling for MVC that I've found is pretty simple.

PS. I'm not primarily looking for a JQuery solution (I want to master 'pure MVC' first) but I'd welcome one.

答:
The problem arises because both your Route uses {sku} and your form field is called sku. The {sku} from the route supersedes the sku form field (it would seem). A (fairly pragmatic) solution could be to have them named differently, so your controller action would be something like:

```<code>public void ActionResult ViewProduct(string routeSku, string sku)
{
    sku = sku ?? routeSku;
    // same as before
}
</code>```

This would cause the "sku" parameter to be "null" in the initial get request (an routeSku will be whatever is in the URL), when using the submit button routeSku will be the same since you are posting back to the same URL but sku will be the form value. The logic will then select the sku value from the form if this was set.

OwnerDisplayName: Simon

Body:
What are the different or best ways I can implement a simple product dropdown in ASP.NET MVC, that redirect the user to a new product when they pick from the dropdown ?

I have currently have my primary mapping rule :

 routes.MapRoute(
              "Product",
              "Products/{sku}",
              new { controller = "Products", action = "ViewProduct", sku = "1001" }
           );

This allows me to enter a URL like this to view my product:

/Products/1002

I have a dropdown on my page which represents a list of products, and allows you to select form the list. (The sku parameter is the same name as the parameter in my controller's ViewProduct method) :

<% using (Html.BeginForm("ViewProduct", "Products"))
   { %>

    <%= Html.DropDownList("sku", ViewData.Model.ProductsList)%>
    <%= Html.SubmitButton() %>

<% } %>

This form targets the 'ViewProduct' command that I have in my controller (which is a full view that renders a product's information page).

The problem is that the HTML generated (when I view the HTML for /Products/1002) looks like this:

<form action="/Products/1002" method="post">

    <select id="sku" name="sku">
        <option value="1003">Product 1003</option>
        <option value="1002">Product 1002</option>
        <option value="2001">Product 2001</option>
    </select>

<input type="submit" />
</form>

It has gone and created the action link based upon the current URL (i guess it really had no choice). The problem is that when my controller is called after clicking 'Submit' it just goes ahead and fetches product 1002 again - and doesnt get overridden by the 'sku' parameter from the form.

Now, the actual value is available in Request.Params["sku"], but obvously its a pretty horrible practice to go and try to get it from there.

One extremely convoluted solution is as follows - create a different routing rule which hits a different controller method RedirectProduct.

routes.MapRoute(
           "Product Redirect",
           "Products/RedirectProduct",
           new { controller = "Products", action = "RedirectProduct" }
        );

Then the action to my form can simply be :

<% using (Html.BeginForm("RedirectProduct", "Products")) { %>

This hits my controller method, which has access to 'sku' (the correct one I want that is coming from the form params). The controller method just redirects to /Products/XXX .

public ActionResult RedirectProduct(string sku)
        {
            return new RedirectResult("/Products/" + sku);
        }

I don't like this solution at all - but I wanted to at least present what I had so far. I dont like adding extra mapping rules like this, and having to create different action names when I really just have one.

I'm sure theres 50 different ways I could do this -- hence me asking the question on stackoverflow -- to try and figure which is best. Unfortunately at this time the documentation for Forms handling for MVC that I've found is pretty simple.

PS. I'm not primarily looking for a JQuery solution (I want to master 'pure MVC' first) but I'd welcome one.

LastEditorDisplayName: Simon

Body:
The problem arises because both your Route uses {sku} and your form field is called sku. The {sku} from the route supersedes the sku form field (it would seem). A (fairly pragmatic) solution could be to have them named differently, so your controller action would be something like:

public void ActionResult ViewProduct(string routeSku, string sku)
{
    sku = sku ?? routeSku;
    // same as before
}

This would cause the "sku" parameter to be "null" in the initial get request (an routeSku will be whatever is in the URL), when using the submit button routeSku will be the same since you are posting back to the same URL but sku will be the form value. The logic will then select the sku value from the form if this was set.

OwnerDisplayName: veggerby


问:
Delete a dictionary item based on a value from a list iteration
I have tried the following:

```<code>losers = ['e', 'b']
candidates_and_fp_votes = {'a': 24, 'b': 0, 'c': 17, 'd': 23, 'e': 0}
for i in losers:
    del candidates_and_fp_votes[losers[i]]
print(candidates_and_fp_votes)
</code>```

This just returns the error:

TypeError: list indices must be integers or slices, not str

I would like to iterate over losers and delete every item in candidates_and_fp_votes which has a key in losers

I expect an output of:

```<code>{'a': 24, 'c': 17, 'd': 23}
</code>```

How can I solve this problem?

Thanks in advance.

答:
You can use dictionary comprehension:

```<code>losers = ['e', 'b']
candidates_and_fp_votes = {'a': 24, 'b': 0, 'c': 17, 'd': 23, 'e': 0}
final_dict = {a:b for a, b in candidates_and_fp_votes.items() if a not in losers}
</code>```

Output:

```<code>{'a': 24, 'c': 17, 'd': 23}
</code>```

Body:
I have tried the following:

losers = ['e', 'b']
candidates_and_fp_votes = {'a': 24, 'b': 0, 'c': 17, 'd': 23, 'e': 0}
for i in losers:
    del candidates_and_fp_votes[losers[i]]
print(candidates_and_fp_votes)

This just returns the error:

TypeError: list indices must be integers or slices, not str

I would like to iterate over losers and delete every item in candidates_and_fp_votes which has a key in losers

I expect an output of:

{'a': 24, 'c': 17, 'd': 23}

How can I solve this problem?

Thanks in advance.

Body:
You can use dictionary comprehension:

losers = ['e', 'b']
candidates_and_fp_votes = {'a': 24, 'b': 0, 'c': 17, 'd': 23, 'e': 0}
final_dict = {a:b for a, b in candidates_and_fp_votes.items() if a not in losers}

Output:

{'a': 24, 'c': 17, 'd': 23}


问:
jenkinsfile parameter properties not configured in jenkins server at initial branch creation
I have configured jenkinsfile with below properties, but it doesn't apply on jenkins server when creating a new branch from master branch.

```<code>#!groovy

properties([[$class: 'ParametersDefinitionProperty',
    parameterDefinitions: [
        [$class: 'StringParameterDefinition', name: 'isValid', defaultValue: 'false']
    ]
]])

node {
    stage 'Checkout'
        checkout scm
    .....
    .....
}
</code>```

After branch created in git, the branch is visible in the jenkins server with Build Now option.

Once I run the branch first time from the jenkins server, it is changed into Build with Parameters option.

Is there anything I missed to configure in jenkinsfile? Why the parameters not configured in the jenkins server at branch creation?

答:
Something I've used to get around this is to check if env.BUILD_NUMBER == "1" on a branch and then set some default values for my parameters to use on the initial run of that branch.  For example:

```<code>node {
  properties([
    buildDiscarder(logRotator(artifactDaysToKeepStr: '', artifactNumToKeepStr: '', daysToKeepStr: '15')),
    parameters([
      string(defaultValue: '', description: '', name: 'PLATFORM')
    ])
  ])

  stage("Testing") {
    // set a default for PLATFORM if it's the first build of a PR
    // as a workaround to parameters not being available on first run of build
    if (env.BUILD_NUMBER == "1") {
      PLATFORM = ''
    }

    if (PLATFORM.empty) {
      ....
    }
  }
}
</code>```

Body:
I have configured jenkinsfile with below properties, but it doesn't apply on jenkins server when creating a new branch from master branch.

#!groovy

properties([[$class: 'ParametersDefinitionProperty',
    parameterDefinitions: [
        [$class: 'StringParameterDefinition', name: 'isValid', defaultValue: 'false']
    ]
]])

node {
    stage 'Checkout'
        checkout scm
    .....
    .....
}

After branch created in git, the branch is visible in the jenkins server with Build Now option.

Once I run the branch first time from the jenkins server, it is changed into Build with Parameters option.

Is there anything I missed to configure in jenkinsfile? Why the parameters not configured in the jenkins server at branch creation?

Body:
Something I've used to get around this is to check if env.BUILD_NUMBER == "1" on a branch and then set some default values for my parameters to use on the initial run of that branch.  For example:

node {
  properties([
    buildDiscarder(logRotator(artifactDaysToKeepStr: '', artifactNumToKeepStr: '', daysToKeepStr: '15')),
    parameters([
      string(defaultValue: '', description: '', name: 'PLATFORM')
    ])
  ])

  stage("Testing") {
    // set a default for PLATFORM if it's the first build of a PR
    // as a workaround to parameters not being available on first run of build
    if (env.BUILD_NUMBER == "1") {
      PLATFORM = ''
    }

    if (PLATFORM.empty) {
      ....
    }
  }
}


问:
Redis still has data after Celery run
I have set up a Celery task that is using RabbitMQ as the broker and Redis as the backend. After running I noticed that my Redis server was still using a lot of memory. Upon inspection I found that there were still keys for each task that was created.

Is there a way to get Celery to clean up these keys only after the response has been received? I know some MessageBrokers use acks, is there an equivalent for a redis backend in Celery?

答: Unfortunately Celery doesn't have acks for its backend, so the best solution for my project was to call forget on my responses after I was done with them.</p>

Title: Redis still has data after Celery run


问:
jQuery positioning differences between Chrome(webkit) and Firefox
While working on a jQuery UI range slider, I was mainly debugging in chrome.  I needed to make the range have a limit so I would grab the left position of one of the handles like so:

$el.css('left');

Which would give me the left position as a percentage: 84%.  However, when I tested in Firefox, it was returning the value in pixels.

Has anyone experienced this before?  Based on looking at the DOM in Firebug, Firefox does recognize percent-based left positioning but it doesn't seem to return that as a value.  Is this default behavior for Firefox?  Is this the same in IE as well?

答: The css () function returns the value of the specified css property as reported by the browser. As a result, it's browser specific and shouldn't be used when dealing with lengths and positioning in this way.</p>


问:
Behavior of git and less in iTerm2 and Zsh - do not use separate view/alternate screen
Using less-like commands in Zsh with iTerm2, e.g. running git log --graph -n 3, git stash list, or less README.md, puts the output in a separate view. I would like the behavior to be more like cat where the output stays in the main window. E.g. when I am using git log, I want to be able to refer back to the commit hashes I just saw.

答: The fix is an iTerm2 setting "Disable save/restore alternate screen" found in iTerm2>Preferences>Terminal. Checking the associated box gives the desired behavior.</p>


问:
C++ vector equivalent in C
I have a code (C++) that looks like this

```<code>vector<int> values[10000];

int i, j;
while (.....) {
    scanf("%d%d", &i, &j);
    values[i].push_back(j);
    values[j].push_back(i);
}
</code>```

but I want to rewrite this code to C. How can I do this?

I researched the opportunity to make the own stack, but maybe have more lightweight way to rewrite this code, maybe  two-dimensional arrays. So far I can not think how this remake, I hope that someone more experienced tell me how to do it :)

Sorry guys, added a more advanced example...

答:
You can try something like this:</p>

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

struct vector
{
    int len;
    int allocated;
    int step;
    int *data;
};

#define INIT_SIZE 1

void init_vector(struct vector *v)
{
    v->len = 0;
    v->allocated = 0;
    v->step = 2;
    v->data = NULL;
}

int append(struct vector *v, int item)
{
    if (!v->data)
    {
        v->data = malloc(INIT_SIZE * sizeof(int));

        if (!v->data)
            return -1;

        v->allocated = INIT_SIZE;
    }
    else
        if (v->len >= v-vallocated)
        {
            int *tmp = realloc(v->data,
                        v->allocated * v->step * sizeof(int));

            if (!tmp)
                return -1;

            v->data = tmp;
            v->allocated *= v->step;
        }

    v->data[v->len] = item;
    v->len++;

    return 0;
}

int delete(struct vector *v, int index)
{
    if (index < 0 || index >= v->len)
        return -1;

    memmove(v->data + index, v->data + index + 1,
                      (v->len - index - 1) * sizeof(int));
    v->len--;

    return 0;
}

void print(const struct vector *v)
{
    printf("Array:\n");

    for (int i = 0; i < v->len; i++)
        printf("%d ", v->data[i]);

    printf("\n");
}

int main(void)
{
    struct vector v;
    int rc;

    init_vector(&v);

    rc = append(&v, 1);
    assert(rc == 0);

    rc = append(&v, 2);
    assert(rc == 0);

    rc = append(&v, 3);
    assert(rc == 0);

    rc = append(&v, 4);
    assert(rc == 0);

    rc = append(&v, 5);
    assert(rc == 0);

    print(&v);

    rc = delete(&v, 2);
    assert(rc == 0);

    print(&v);

    free(v.data);

    return 0;
}
</code>```

Title: C++ vector equivalent in C

Body:
I have a code (C++) that looks like this

vector<int> values[10000];

int i, j;
while (.....) {
    scanf("%d%d", &i, &j);
    values[i].push_back(j);
    values[j].push_back(i);
}

but I want to rewrite this code to C. How can I do this?

I researched the opportunity to make the own stack, but maybe have more lightweight way to rewrite this code, maybe  two-dimensional arrays. So far I can not think how this remake, I hope that someone more experienced tell me how to do it :)

Sorry guys, added a more advanced example...

Body:
You can try something like this:

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

struct vector
{
    int len;
    int allocated;
    int step;
    int *data;
};

#define INIT_SIZE 1

void init_vector(struct vector *v)
{
    v->len = 0;
    v->allocated = 0;
    v->step = 2;
    v->data = NULL;
}

int append(struct vector *v, int item)
{
    if (!v->data)
    {
        v->data = malloc(INIT_SIZE * sizeof(int));

        if (!v->data)
            return -1;

        v->allocated = INIT_SIZE;
    }
    else
        if (v->len >= v-vallocated)
        {
            int *tmp = realloc(v->data,
                        v->allocated * v->step * sizeof(int));

            if (!tmp)
                return -1;

            v->data = tmp;
            v->allocated *= v->step;
        }

    v->data[v->len] = item;
    v->len++;

    return 0;
}

int delete(struct vector *v, int index)
{
    if (index < 0 || index >= v->len)
        return -1;

    memmove(v->data + index, v->data + index + 1,
                      (v->len - index - 1) * sizeof(int));
    v->len--;

    return 0;
}

void print(const struct vector *v)
{
    printf("Array:\n");

    for (int i = 0; i < v->len; i++)
        printf("%d ", v->data[i]);

    printf("\n");
}

int main(void)
{
    struct vector v;
    int rc;

    init_vector(&v);

    rc = append(&v, 1);
    assert(rc == 0);

    rc = append(&v, 2);
    assert(rc == 0);

    rc = append(&v, 3);
    assert(rc == 0);

    rc = append(&v, 4);
    assert(rc == 0);

    rc = append(&v, 5);
    assert(rc == 0);

    print(&v);

    rc = delete(&v, 2);
    assert(rc == 0);

    print(&v);

    free(v.data);

    return 0;
}


问:
how python urlretrieve reporthook function handle the input argument
I am reading some codes which work nicely. In the codes, it use urlretrieve to download file from web. While it's downloading it can also report how much has been downloaded.

The urlretrieve calling is like below:

```<code>urlretrieve(url + filename, dest_filename, reporthook=download_progress_hook)
</code>```

And the download_progress_hook() is defined as below:

```<code>def download_progress_hook(count, blockSize, totalSize):
    print(count, blockSize, totalSize)
</code>```

When I gave some url and started to download sth. from web, it kept reporting count,blocksize and totalsize as below output

```<code>0 8192 8458043
1 8192 8458043
2 8192 8458043
3 8192 8458043
4 8192 8458043
5 8192 8458043
6 8192 8458043
7 8192 8458043
</code>```

The python documents described as "The hook will be passed three arguments; a count of blocks transferred so far, a block size in bytes, and the total size of the file. The third argument may be -1 on older FTP servers which do not return a file size in response to a retrieval request."
This looks strange for me. My understanding is when urlretrieve functions was calling, it used the output of download_progress_hook function as the input to urlretrieve and named it as reporthook variable.
But according to the results of this code, it looks like whenever urlretrieve is called with 3rd arguments, which should be defined as function, the urlretrieve will feedback the 3 information to that function. I know from other functions in urllib, we might get the file size by checking the header file. But I don't understand how this whole mechanism worked here. How the variable passed into function download_progress_hook. According to output, it's like the download_progress_hook function are keeping running during the lifetime of urlretrieve. This might be some concepts in python programming or urllib? Appreciating any thoughts and instructions.

答:
This is late reply but since i also was reading about this answered here https://stackoverflow.com/questions/43370284/why-function-works-properly-without-specifying-parameters/

summary:

urlretrieve doesn't call download_progress_hook. It merely gives that function object to the urlretrieve() function as reference and it is that code that'll call download_progress_hook somewhere (passing in the required arguments).

Body:
I am reading some codes which work nicely. In the codes, it use urlretrieve to download file from web. While it's downloading it can also report how much has been downloaded.

The urlretrieve calling is like below:

urlretrieve(url + filename, dest_filename, reporthook=download_progress_hook)

And the download_progress_hook() is defined as below:

def download_progress_hook(count, blockSize, totalSize):
    print(count, blockSize, totalSize)

When I gave some url and started to download sth. from web, it kept reporting count,blocksize and totalsize as below output

0 8192 8458043
1 8192 8458043
2 8192 8458043
3 8192 8458043
4 8192 8458043
5 8192 8458043
6 8192 8458043
7 8192 8458043

The python documents described as "The hook will be passed three arguments; a count of blocks transferred so far, a block size in bytes, and the total size of the file. The third argument may be -1 on older FTP servers which do not return a file size in response to a retrieval request."
This looks strange for me. My understanding is when urlretrieve functions was calling, it used the output of download_progress_hook function as the input to urlretrieve and named it as reporthook variable.
But according to the results of this code, it looks like whenever urlretrieve is called with 3rd arguments, which should be defined as function, the urlretrieve will feedback the 3 information to that function. I know from other functions in urllib, we might get the file size by checking the header file. But I don't understand how this whole mechanism worked here. How the variable passed into function download_progress_hook. According to output, it's like the download_progress_hook function are keeping running during the lifetime of urlretrieve. This might be some concepts in python programming or urllib? Appreciating any thoughts and instructions.


问:
Java convention--naming a local variable the same as field
Writing a program that interprets a line from a text file.

Wondering if I should be naming the local variables in method 'parseWordData' something like
scannedWord as oppposed to word, because word is already a class field.

as long as I am declaring a new variable instead of reassigning the old one, everything should be fine...right?

```<code>public class WordData {

private String word;
private int index;
private LinkedList<Integer> list;
private boolean pathFound;

public WordData(String word, int index, LinkedList<Integer> list, boolean pathFound) {
    this.word = word;
    this.index = index;
    this.list = list;
    this.pathFound = pathFound;
}

public WordData parseWordData(String line){
    Scanner scan = new Scanner(line);
    int index = scan.nextInt();
    String word = scan.next();
    //precond and subGoal
    LinkedList<Integer> list = new LinkedList<Integer>();
    while(scan.hasNextInt()){
        //add to LinkedList
    }
    return new WordData(word, index, list, false)
}
</code>```

dont worry about the logic, i just want to know if naming things like this will be confusing or is taboo in java

答:
In Java, it's standard practice to name parameters the same as fields in

constructors

setter methods

provided that these methods set the fields to have the same values as the parameters.  In this case, you see lines like

```<code>this.word = word;
</code>```

in your constructor or your setter method.

In all other cases you should avoid having parameter names or local variable names that are the same as field names.  It only leads to confusion.  This is standard practice.

So in your example, YES, you should use scannedWord or something similar for the word that's scanned from the input.

Body:
Writing a program that interprets a line from a text file.

Wondering if I should be naming the local variables in method 'parseWordData' something like
scannedWord as oppposed to word, because word is already a class field.

as long as I am declaring a new variable instead of reassigning the old one, everything should be fine...right?

public class WordData {

private String word;
private int index;
private LinkedList<Integer> list;
private boolean pathFound;

public WordData(String word, int index, LinkedList<Integer> list, boolean pathFound) {
    this.word = word;
    this.index = index;
    this.list = list;
    this.pathFound = pathFound;
}

public WordData parseWordData(String line){
    Scanner scan = new Scanner(line);
    int index = scan.nextInt();
    String word = scan.next();
    //precond and subGoal
    LinkedList<Integer> list = new LinkedList<Integer>();
    while(scan.hasNextInt()){
        //add to LinkedList
    }
    return new WordData(word, index, list, false)
}

dont worry about the logic, i just want to know if naming things like this will be confusing or is taboo in java

Body:
In Java, it's standard practice to name parameters the same as fields in

constructors

setter methods

provided that these methods set the fields to have the same values as the parameters.  In this case, you see lines like

this.word = word;

in your constructor or your setter method.

In all other cases you should avoid having parameter names or local variable names that are the same as field names.  It only leads to confusion.  This is standard practice.

So in your example, YES, you should use scannedWord or something similar for the word that's scanned from the input.