问:
Getting Data out of a container
I wrote a function that creates new Input fields based on the number of input fields needed. That code is below.

```<code>for (i=0;i<number;i++){
    container.appendChild(document.createTextNode("Guest " + (i+1)));
    var input = document.createElement("input");
    input.id = "Guest" + i;
    container.appendChild(input);
    container.appendChild(document.createElement("br"));
    console.log(i.value);
</code>```

It creates a new Id for each input field. In the function below,depending on the number you set for i, the function creates a generated message.

```<code>function sendInput ()
{
    var guestNames = document.getElementById("Guest").value
    var personName = document.getElementById("people").value;
    var eventType = document.getElementById("event").value;
    var date = document.getElementById("date").value;
    var output = "Dear " + guestNames + " You have been invited to " + personName + "'s " + eventType + " on " + date +  " Thank you for coming!!";
    document.getElementById('output').innerHTML = output.repeat(i);
}
</code>```

The problem is it is not collecting the data for guestNames. I am pretty new to JS but have searched and cannot find a solution to my problem. Any feedback wouls be helpful.

答:
Your code is incomplete (as far as I can tell).

You do not specify the following elements anywhere:
'container', 'guest', 'people', 'event', 'data' or 'output'
I assume they should be defined somewhere in the HTML section (not provided)

To be able to create the variable displays, you need to define the 'container' you wish to initialize it before it is used in the for() loop that follows.

Example: var container = document.getElementById('container');

Within the loop, console.log(i.value) is invalid as i is not an element that has been assigne a value to display.  It is a counter of the for() loop.

The function of sendInput(), I assume, is to collect the information from the user for each "Guest#" created by the first loop of your code.  However you try to collect from "Guest" which has not been defined.  For a number of 5, the collections should be for "Guest1", "Guest2", "Guest3", "Guest4", "Guest5".  "Guest" only can not be found anywhere in your loop creation.  Same goes for 'people, 'event' and 'date' which are referenced for value collection, but there are no elements named as such.

Not exactly sure why you are mixing DOM creation techniques (???).
You create the number of element for the guest, but then output the results with .innerHTML.  You should use the DOM creation method, but I have used your code as you indicated you are a beginner.

Here is some (partially) corrected code that you can continue on with.

```<code><!DOCTYPE html><html lang="en"><head><title> Test Page </title>
<meta charset="UTF-8">

<meta name="viewport" content="width-device-width,initial-scale=1.0, user-scalable=yes"/>

<!-- link rel="stylesheet" href="common.css" media="screen" -->
<style>

</style>

</head><body>
<input type="text" value="5/28/2020" id="date">
<pre id='container'>```
<button id="report">Report</button>

```

<script>
console.clear();

function init() {
  var number = 5;
  var container = document.getElementById('container');

  for (i=0;i<number;i++) {
    var value = "Guest " + (i+1)+' ';
    container.appendChild(document.createTextNode(value));

    var input = document.createElement("input");
    input.id = "Guest" + i;
    input.value = value;

    container.appendChild(input);
    container.appendChild(document.createElement("br"));
    console.log(i); // .value);
  }
  document.getElementById('report').addEventListener('click',sendInput);
} init();

  function sendInput () {
    var date = document.getElementById("date").value,
        output = document.getElementById('output'),
        info = '';
        var guestNames = [...document.querySelectorAll('#container input')];  // alert(guestNames.length);

    for (let i=0; i<guestNames.length; i++) {
      info = `Dear ${guestNames[i].value}:\nYou have been invited to XXX's EVENT on ${date}\nThank you for coming!!\n\n`;
      output.innerHTML += info;
    }
//    var guestNames = document.getElementById("Guest").value
//    var personName = document.getElementById("people").value;
//    var eventType = document.getElementById("event").value;
//    var output = "Dear " + guestNames + " You have been invited to " + personName + "'s " + eventType + " on " + date +  " Thank you for coming!!";
//    output = `Dear ${guestNames}:\nYou have been invided to XXX's EVENT on ${date}\nThank you for coming!!`;
//    document.getElementById('output').innerHTML = output.repeat(i);
  }

</script>

</body></html>
</code>```

Title: Getting Data out of a container

Body:
I wrote a function that creates new Input fields based on the number of input fields needed. That code is below.

for (i=0;i<number;i++){
    container.appendChild(document.createTextNode("Guest " + (i+1)));
    var input = document.createElement("input");
    input.id = "Guest" + i;
    container.appendChild(input);
    container.appendChild(document.createElement("br"));
    console.log(i.value);

It creates a new Id for each input field. In the function below,depending on the number you set for i, the function creates a generated message.

function sendInput ()
{
    var guestNames = document.getElementById("Guest").value
    var personName = document.getElementById("people").value;
    var eventType = document.getElementById("event").value;
    var date = document.getElementById("date").value;
    var output = "Dear " + guestNames + " You have been invited to " + personName + "'s " + eventType + " on " + date +  " Thank you for coming!!";
    document.getElementById('output').innerHTML = output.repeat(i);
}

The problem is it is not collecting the data for guestNames. I am pretty new to JS but have searched and cannot find a solution to my problem. Any feedback wouls be helpful.

Body:
Your code is incomplete (as far as I can tell).

You do not specify the following elements anywhere:
'container', 'guest', 'people', 'event', 'data' or 'output'
I assume they should be defined somewhere in the HTML section (not provided)

To be able to create the variable displays, you need to define the 'container' you wish to initialize it before it is used in the for() loop that follows.

Example: var container = document.getElementById('container');

Within the loop, console.log(i.value) is invalid as i is not an element that has been assigne a value to display.  It is a counter of the for() loop.

The function of sendInput(), I assume, is to collect the information from the user for each "Guest#" created by the first loop of your code.  However you try to collect from "Guest" which has not been defined.  For a number of 5, the collections should be for "Guest1", "Guest2", "Guest3", "Guest4", "Guest5".  "Guest" only can not be found anywhere in your loop creation.  Same goes for 'people, 'event' and 'date' which are referenced for value collection, but there are no elements named as such.

Not exactly sure why you are mixing DOM creation techniques (???).
You create the number of element for the guest, but then output the results with .innerHTML.  You should use the DOM creation method, but I have used your code as you indicated you are a beginner.

Here is some (partially) corrected code that you can continue on with.

<!DOCTYPE html><html lang="en"><head><title> Test Page </title>
<meta charset="UTF-8">

<meta name="viewport" content="width-device-width,initial-scale=1.0, user-scalable=yes"/>

<!-- link rel="stylesheet" href="common.css" media="screen" -->
<style>

</style>

</head><body>
<input type="text" value="5/28/2020" id="date">
<pre id='container'></pre>
<button id="report">Report</button>
<pre id='output'></pre>

<script>
console.clear();

function init() {
  var number = 5;
  var container = document.getElementById('container');

  for (i=0;i<number;i++) {
    var value = "Guest " + (i+1)+' ';
    container.appendChild(document.createTextNode(value));

    var input = document.createElement("input");
    input.id = "Guest" + i;
    input.value = value;

    container.appendChild(input);
    container.appendChild(document.createElement("br"));
    console.log(i); // .value);
  }
  document.getElementById('report').addEventListener('click',sendInput);
} init();

  function sendInput () {
    var date = document.getElementById("date").value,
        output = document.getElementById('output'),
        info = '';
        var guestNames = [...document.querySelectorAll('#container input')];  // alert(guestNames.length);

    for (let i=0; i<guestNames.length; i++) {
      info = `Dear ${guestNames[i].value}:\nYou have been invited to XXX's EVENT on ${date}\nThank you for coming!!\n\n`;
      output.innerHTML += info;
    }
//    var guestNames = document.getElementById("Guest").value
//    var personName = document.getElementById("people").value;
//    var eventType = document.getElementById("event").value;
//    var output = "Dear " + guestNames + " You have been invited to " + personName + "'s " + eventType + " on " + date +  " Thank you for coming!!";
//    output = `Dear ${guestNames}:\nYou have been invided to XXX's EVENT on ${date}\nThank you for coming!!`;
//    document.getElementById('output').innerHTML = output.repeat(i);
  }

</script>

</body></html>


来源: stackexchange

问:
working with high precision timestamps in python
Hey I am working in python with datetime and I am wondering what the best way to parse this timestamp is.

The timestamps are ISO standard, here is an example "2010-06-19T08:17:14.078685237Z"

Now so far I have used

```<code>time = datetime.datetime.strptime(timestamp.split(".")[0], "%Y-%m-%dT%H:%M:%S")
precisetime = time + datetime.timedelta(0,float("." + timestamp[:-1].split(".")[0]))
</code>```

This kind of works, but I feel like there should be a more streamlined way (I am very new to python, and I am sure I am doing this like an ass). Also, I have nanoseconds in my timestamp, but only microseconds in my datetime object, is there a better module to work with? I need to be able to do operations on the time such as subtracting times and putting them in the scheduler.

Any better way to go about this?

答:
Your code looks fine.  I don't know a better way, but I'm not a datetime expert.  Personally, I would wrap it in a function and do a little less work per line, but that's just my style:

```<code>def parse_iso_timestamp(timestamp)
    ts, partial_seconds = timestamp[:-1].split('.')
    partial_seconds = float("." + partial_seconds)
    time = datetime.datetime.strptime(ts, "%Y-%m-%dT%H:%M:%S")
    precisedatetime = time + datetime.timedelta(seconds=partial_seconds)
    return precisedatetime
</code>```

edit:  I agree with Rob Cowie's answer.  No need to reinvent the wheel.

ContentLicense: CC BY-SA 3.0

Body:
Hey I am working in python with datetime and I am wondering what the best way to parse this timestamp is.

The timestamps are ISO standard, here is an example "2010-06-19T08:17:14.078685237Z"

Now so far I have used

time = datetime.datetime.strptime(timestamp.split(".")[0], "%Y-%m-%dT%H:%M:%S")
precisetime = time + datetime.timedelta(0,float("." + timestamp[:-1].split(".")[0]))

This kind of works, but I feel like there should be a more streamlined way (I am very new to python, and I am sure I am doing this like an ass). Also, I have nanoseconds in my timestamp, but only microseconds in my datetime object, is there a better module to work with? I need to be able to do operations on the time such as subtracting times and putting them in the scheduler.

Any better way to go about this?

Body:
Your code looks fine.  I don't know a better way, but I'm not a datetime expert.  Personally, I would wrap it in a function and do a little less work per line, but that's just my style:

def parse_iso_timestamp(timestamp)
    ts, partial_seconds = timestamp[:-1].split('.')
    partial_seconds = float("." + partial_seconds)
    time = datetime.datetime.strptime(ts, "%Y-%m-%dT%H:%M:%S")
    precisedatetime = time + datetime.timedelta(seconds=partial_seconds)
    return precisedatetime

edit:  I agree with Rob Cowie's answer.  No need to reinvent the wheel.


问:
Tableview forms need to have keyboard appearing raise view when textfield is at the bottom but not when user scrolls so it is at the top
I need to make a form that is long, which entails having certain textFields either at the top or bottom depending on the user's behavior. When the textfield is tapped near the bottom, I have to raise the view. However, when that textField is at the top of the screen, the view needs to not be raised or it pushes the textField off the screen. I can't find anything online that addresses this problem besides third parties (where you lose control of the design usually).</p>

答: Have you looked at IQKeyboardManagerSwift, you need not write any code nor any setup required and it does not impact your design.</p>

ContentLicense: CC BY-SA 4.0


问:
How can I automatically generate a new input area when user started to enter text?
I want to generate input dynamically. Searched almost all samples and they generate inputs with button clicks. It is ok but i need something different. When user started to type in input then i want to create second input and when user typed to second then create third input like this..

My problem is when user typed inputs then it creates many inputs (letter counts=inputs). I must solve this issue immediately . I tried to some tricks but they could not work . Thanks for helping . You can check it in Codepen .

```<code>  <div class="container1">
      <button class="add_form_field">
        Add New Field
        <span style="font-size: 16px; font-weight: bold;">+ </span>
      </button>
      <div class="divInput firstChild">
        <input type="text" autocomplete="off" name="mytext[]" />
      </div>
    </div>
</code>```

```<code> $(document).ready(function () {
        var max_fields = 10;
        var wrapper = $(".container1");
        var add_button = $(".add_form_field");

        var inputs = document.querySelectorAll(".divInput");
        let xs = [];
        var x = 1;
        $(add_button).click(function (e) {
          e.preventDefault();
          if (x < max_fields) {
            x++;

            $(wrapper).append(
              '<div class="divInput"><input type="text" autocomplete="off" name="mytext[]"/><a href="#" class="delete"></a></div>'
            ); //add input box
          } else {
            alert("You Reached the limits");
          }
        });

        $(wrapper).on("keyup", "input", function (e) {
          e.preventDefault();

          if ($(this).val() == "") {
            //when user cleaned input then delete it
            $(this).parent("div").remove();
            x--;
            return;
          } else if ($(this).val() != "") {
            //dont use click check if length>0 then use this trick to add new input
            $(add_button).trigger("click");
            return;
          }

          if (x == 0) {
            //if user tries to delete last input then create a new one
            console.log("xx", x);
            $(wrapper).append(
              '<div class="divInput"><input type="text" autocomplete="off" name="mytext[]"/><a href="#" class="delete"></a></div>'
            ); //add input box
            x = 1;
            console.log("xx", x);
            return;
          }
        });
      });

</code>```

https://codepen.io/otontas11/pen/BaogrZR

答:
First, you need to store in the current id in the input, make an event when user types and check the input id and check if is already added, if not then you proceed.

You need to attach the event to the body since you are dynamically creating elements.

Is this what you are looking for?

```<code><div id="container">
    <div class="generatedChild">
        <input type="text" childId="1" autocomplete="off" name="mytext[]"/>
    </div>
</div>
<script>
$(function(){
    var max_fields = 10;
    var wrapper = $('#container');
    // attach the event to the Body, so all generated inputs will be listened by our event
    $('body').on('input','.generatedChild input' ,function(e){
        currentId = $(this).attr("childid");
        childId = parseInt(currentId) + 1;
        childOfThisInput = $(`input[childid=${childId}]`);

        // check if is already added or if exceeds the maximum fields number
        if(currentId > max_fields || childOfThisInput.length === 1) return;

        $div = $("<div>", {class: "generatedChild"});
        $input = $('<input>', {childid: childId, autocomplete:"off", name:"mytext[]", type: "text"});
        $div.append($input);
        wrapper.append($div);

    });
});
</script>
</code>```

Update:
If you need to let the user delete some of the generated inputs you can try something like this:

```<code>$(function(){
    var max_fields = 10;
    var wrapper = $('#container');
    var inputsLength = 1;
    // attach the event to the Body, so all generated inputs will be listened by our event
    $('body').on('keydown','.generatedChild input' ,function(e){
        currentId = $(this).attr("childid");
        childId = parseInt(currentId) + 1;
        childOfThisInput = $(`input[childid=${childId}]`);
        if($(this).val() === "" && e.key === 8 && inputsLength > 1 )
            return remove_input($(this));
        // check if is already added or if exceeds the maximum fields number
        if(inputsLength > max_fields || childOfThisInput.length === 1 || e.key === 8) return;
            add_input(childId);
    });
    function add_input(childId){
        $div = $("<div>", {class: "generatedChild"});
        $input = $('<input>', {childid: childId, autocomplete:"off", name:"mytext[]", type: "text"});
        $div.append($input);
        wrapper.append($div);
        ++inputsLength;
    }
    function remove_input(element){
        element.parent('.generatedChild').remove();
        // let's focus the last generated input, so user won't need focus the input again
        $('.generatedChild input:last').focus();
        --inputsLength;
    }
});
</code>```

Body:
I want to generate input dynamically. Searched almost all samples and they generate inputs with button clicks. It is ok but i need something different. When user started to type in input then i want to create second input and when user typed to second then create third input like this..

My problem is when user typed inputs then it creates many inputs (letter counts=inputs). I must solve this issue immediately . I tried to some tricks but they could not work . Thanks for helping . You can check it in Codepen .

      <button class="add_form_field">
        Add New Field
        +
      </button>

        <input type="text" autocomplete="off" name="mytext[]" />

 $(document).ready(function () {
        var max_fields = 10;
        var wrapper = $(".container1");
        var add_button = $(".add_form_field");

        var inputs = document.querySelectorAll(".divInput");
        let xs = [];
        var x = 1;
        $(add_button).click(function (e) {
          e.preventDefault();
          if (x < max_fields) {
            x++;

            $(wrapper).append(
              '
<input type="text" autocomplete="off" name="mytext[]"/>
'
            ); //add input box
          } else {
            alert("You Reached the limits");
          }
        });

        $(wrapper).on("keyup", "input", function (e) {
          e.preventDefault();

          if ($(this).val() == "") {
            //when user cleaned input then delete it
            $(this).parent("div").remove();
            x--;
            return;
          } else if ($(this).val() != "") {
            //dont use click check if length>0 then use this trick to add new input
            $(add_button).trigger("click");
            return;
          }

          if (x == 0) {
            //if user tries to delete last input then create a new one
            console.log("xx", x);
            $(wrapper).append(
              '
<input type="text" autocomplete="off" name="mytext[]"/>
'
            ); //add input box
            x = 1;
            console.log("xx", x);
            return;
          }
        });
      });

https://codepen.io/otontas11/pen/BaogrZR

Body:
First, you need to store in the current id in the input, make an event when user types and check the input id and check if is already added, if not then you proceed.

You need to attach the event to the body since you are dynamically creating elements.

Is this what you are looking for?

<div id="container">
    <div class="generatedChild">
        <input type="text" childId="1" autocomplete="off" name="mytext[]"/>
    </div>
</div>
<script>
$(function(){
    var max_fields = 10;
    var wrapper = $('#container');
    // attach the event to the Body, so all generated inputs will be listened by our event
    $('body').on('input','.generatedChild input' ,function(e){
        currentId = $(this).attr("childid");
        childId = parseInt(currentId) + 1;
        childOfThisInput = $(`input[childid=${childId}]`);

        // check if is already added or if exceeds the maximum fields number
        if(currentId > max_fields || childOfThisInput.length === 1) return;

        $div = $("<div>", {class: "generatedChild"});
        $input = $('<input>', {childid: childId, autocomplete:"off", name:"mytext[]", type: "text"});
        $div.append($input);
        wrapper.append($div);

    });
});
</script>

Update:
If you need to let the user delete some of the generated inputs you can try something like this:

$(function(){
    var max_fields = 10;
    var wrapper = $('#container');
    var inputsLength = 1;
    // attach the event to the Body, so all generated inputs will be listened by our event
    $('body').on('keydown','.generatedChild input' ,function(e){
        currentId = $(this).attr("childid");
        childId = parseInt(currentId) + 1;
        childOfThisInput = $(`input[childid=${childId}]`);
        if($(this).val() === "" && e.key === 8 && inputsLength > 1 )
            return remove_input($(this));
        // check if is already added or if exceeds the maximum fields number
        if(inputsLength > max_fields || childOfThisInput.length === 1 || e.key === 8) return;
            add_input(childId);
    });
    function add_input(childId){
        $div = $("<div>", {class: "generatedChild"});
        $input = $('<input>', {childid: childId, autocomplete:"off", name:"mytext[]", type: "text"});
        $div.append($input);
        wrapper.append($div);
        ++inputsLength;
    }
    function remove_input(element){
        element.parent('.generatedChild').remove();
        // let's focus the last generated input, so user won't need focus the input again
        $('.generatedChild input:last').focus();
        --inputsLength;
    }
});


问:
Exception in thread "main" java.lang.NoClassDefFoundError: com/google/common/collect/ImmutableMap
So while creating a new selenium java project and using the latest selenium version (3.141.59) form the website, i encountered the following exception:</p>

```<code>Exception in thread "main" java.lang.NoClassDefFoundError: com/google/common/collect/ImmutableMap
at org.openqa.selenium.remote.service.DriverService$Builder.<init>(DriverService.java:259)
at org.openqa.selenium.chrome.ChromeDriverService$Builder.<init>(ChromeDriverService.java:101)
at org.openqa.selenium.chrome.ChromeDriverService.createDefaultService(ChromeDriverService.java:94)
at org.openqa.selenium.chrome.ChromeDriver.<init>(ChromeDriver.java:123)
at test.src.main(src.java:11)

Caused by: java.lang.ClassNotFoundException: com.google.common.collect.ImmutableMap
at java.base/jdk.internal.loader.BuiltinClassLoader.loadClass(BuiltinClassLoader.java:602)
at java.base/jdk.internal.loader.ClassLoaders$AppClassLoader.loadClass(ClassLoaders.java:178)
at java.base/java.lang.ClassLoader.loadClass(ClassLoader.java:521)
... 5 more
</code>```

答:
It turn out that in the latest selenium (3.141.59) download available form the selenium website I couldn't find a standalone anymore.
Instead my problem was resolved by manually adding the client-combined-3.141.59.jar and all the jar files present in the lib folder to the Build Path of the project.</p>

Body:
So while creating a new selenium java project and using the latest selenium version (3.141.59) form the website, i encountered the following exception:

Exception in thread "main" java.lang.NoClassDefFoundError: com/google/common/collect/ImmutableMap
at org.openqa.selenium.remote.service.DriverService$Builder.<init>(DriverService.java:259)
at org.openqa.selenium.chrome.ChromeDriverService$Builder.<init>(ChromeDriverService.java:101)
at org.openqa.selenium.chrome.ChromeDriverService.createDefaultService(ChromeDriverService.java:94)
at org.openqa.selenium.chrome.ChromeDriver.<init>(ChromeDriver.java:123)
at test.src.main(src.java:11)

Caused by: java.lang.ClassNotFoundException: com.google.common.collect.ImmutableMap
at java.base/jdk.internal.loader.BuiltinClassLoader.loadClass(BuiltinClassLoader.java:602)
at java.base/jdk.internal.loader.ClassLoaders$AppClassLoader.loadClass(ClassLoaders.java:178)
at java.base/java.lang.ClassLoader.loadClass(ClassLoader.java:521)
... 5 more


问:
Jenkins auto deploying failed, when all settings are right. -- error in mapperLocations, Spring (illegalArgumentException, TomcatManagerException)
I want to share some Jenkins auto-deployment issue solutions, that I could not find on the internet including here.

But I'm almost a freshman in StackOverflow, so I'm just here to ask myself and answer myself right away.

// I have tried to share the solution public on GitHub issue, I could not use it well, too.

// asking to be excused...

I'm using Spring MVC 4.3.9, connected to CI/CD.
// GitHub branch -> Jenkins -> TestServer (Tomcat 8.5)

I allowed all the IP addresses, made and set the right Tomcat Manager account both in Jenkins credentials menu and tomcat.
But the same error always occurs -- TomcatManagerException and also the illegal argument exception (in the full log from Jenkins by maven build option, -X -e, not sure).
// Same results, with both Deploy war plugin and SSH_publish plugin.

Here is the Jenkins console output. (I don't think this one is the full log.)

```<code>[INFO] ------------------------------------------------------------------------
[INFO] BUILD SUCCESS
[INFO] ------------------------------------------------------------------------
[INFO] Total time:  7.895 s
[INFO] Finished at: ~~~Time~~~
[INFO] ------------------------------------------------------------------------
[DeployPublisher][INFO] Attempting to deploy 1 war file(s)
[DeployPublisher][INFO] Deploying ~~YourDIR&WAR~~ to container Tomcat 8.x Remote with context ~~YourContextName~~
  Redeploying [ ~~YourDIR&WAR~~]
  Undeploying  ~~YourDIR&WAR~~]
  Deploying [ ~~YourDIR&WAR~~]
ERROR: Build step failed with exception
org.codehaus.cargo.container.ContainerException: Failed to deploy [ ~~YourDIR&WAR~~]
    at org.codehaus.cargo.container.tomcat.internal.AbstractTomcatManagerDeployer.deploy(AbstractTomcatManagerDeployer.java:104)
    at org.codehaus.cargo.container.tomcat.internal.AbstractTomcatManagerDeployer.redeploy(AbstractTomcatManagerDeployer.java:180)
    at hudson.plugins.deploy.CargoContainerAdapter.deploy(CargoContainerAdapter.java:81)
    at hudson.plugins.deploy.CargoContainerAdapter$DeployCallable.invoke(CargoContainerAdapter.java:167)
    at hudson.plugins.deploy.CargoContainerAdapter$DeployCallable.invoke(CargoContainerAdapter.java:136)
    at hudson.FilePath.act(FilePath.java:1075)
    at hudson.FilePath.act(FilePath.java:1058)
    at hudson.plugins.deploy.CargoContainerAdapter.redeployFile(CargoContainerAdapter.java:133)
    at hudson.plugins.deploy.PasswordProtectedAdapterCargo.redeployFile(PasswordProtectedAdapterCargo.java:95)
    at hudson.plugins.deploy.DeployPublisher.perform(DeployPublisher.java:113)
    at hudson.tasks.BuildStepCompatibilityLayer.perform(BuildStepCompatibilityLayer.java:78)
    at hudson.tasks.BuildStepMonitor$3.perform(BuildStepMonitor.java:45)
    at hudson.model.AbstractBuild$AbstractBuildExecution.perform(AbstractBuild.java:741)
    at hudson.model.AbstractBuild$AbstractBuildExecution.performAllBuildSteps(AbstractBuild.java:690)
    at hudson.model.Build$BuildExecution.post2(Build.java:186)
    at hudson.model.AbstractBuild$AbstractBuildExecution.post(AbstractBuild.java:635)
    at hudson.model.Run.execute(Run.java:1905)
    at hudson.model.FreeStyleBuild.run(FreeStyleBuild.java:43)
    at hudson.model.ResourceController.execute(ResourceController.java:97)
    at hudson.model.Executor.run(Executor.java:428)
Caused by: org.codehaus.cargo.container.tomcat.internal.TomcatManagerException: The Tomcat Manager responded "FAIL - Deployed application at context path [~~YourContextName~~] but context failed to start
" instead of the expected "OK" message
    at org.codehaus.cargo.container.tomcat.internal.TomcatManager.invoke(TomcatManager.java:721)
    at org.codehaus.cargo.container.tomcat.internal.TomcatManager.deployImpl(TomcatManager.java:767)
    at org.codehaus.cargo.container.tomcat.internal.TomcatManager.deploy(TomcatManager.java:312)
    at org.codehaus.cargo.container.tomcat.internal.AbstractTomcatManagerDeployer.deploy(AbstractTomcatManagerDeployer.java:99)
    ... 19 more
org.codehaus.cargo.container.tomcat.internal.TomcatManagerException: The Tomcat Manager responded "FAIL - Deployed application at context path [~~YourContextName~~] but context failed to start
" instead of the expected "OK" message
    at org.codehaus.cargo.container.tomcat.internal.TomcatManager.invoke(TomcatManager.java:721)
    at org.codehaus.cargo.container.tomcat.internal.TomcatManager.deployImpl(TomcatManager.java:767)
    at org.codehaus.cargo.container.tomcat.internal.TomcatManager.deploy(TomcatManager.java:312)
    at org.codehaus.cargo.container.tomcat.internal.AbstractTomcatManagerDeployer.deploy(AbstractTomcatManagerDeployer.java:99)
    at org.codehaus.cargo.container.tomcat.internal.AbstractTomcatManagerDeployer.redeploy(AbstractTomcatManagerDeployer.java:180)
    at hudson.plugins.deploy.CargoContainerAdapter.deploy(CargoContainerAdapter.java:81)
    at hudson.plugins.deploy.CargoContainerAdapter$DeployCallable.invoke(CargoContainerAdapter.java:167)
    at hudson.plugins.deploy.CargoContainerAdapter$DeployCallable.invoke(CargoContainerAdapter.java:136)
    at hudson.FilePath.act(FilePath.java:1075)
    at hudson.FilePath.act(FilePath.java:1058)
    at hudson.plugins.deploy.CargoContainerAdapter.redeployFile(CargoContainerAdapter.java:133)
    at hudson.plugins.deploy.PasswordProtectedAdapterCargo.redeployFile(PasswordProtectedAdapterCargo.java:95)
    at hudson.plugins.deploy.DeployPublisher.perform(DeployPublisher.java:113)
    at hudson.tasks.BuildStepCompatibilityLayer.perform(BuildStepCompatibilityLayer.java:78)
    at hudson.tasks.BuildStepMonitor$3.perform(BuildStepMonitor.java:45)
    at hudson.model.AbstractBuild$AbstractBuildExecution.perform(AbstractBuild.java:741)
    at hudson.model.AbstractBuild$AbstractBuildExecution.performAllBuildSteps(AbstractBuild.java:690)
    at hudson.model.Build$BuildExecution.post2(Build.java:186)
    at hudson.model.AbstractBuild$AbstractBuildExecution.post(AbstractBuild.java:635)
    at hudson.model.Run.execute(Run.java:1905)
    at hudson.model.FreeStyleBuild.run(FreeStyleBuild.java:43)
    at hudson.model.ResourceController.execute(ResourceController.java:97)
    at hudson.model.Executor.run(Executor.java:428)
Build step 'Deploy war/ear to a container' marked build as failure
Finished: FAILURE
</code>```

* I also got illegal argument exception in maven console, in mapperLocations setting.

===> This is the key

答:
```<code>    <bean id="dataSource" class="org.apache.commons.dbcp.BasicDataSource">
        <property name="driverClassName" value="org.mysql.jdbc.Driver" />
        <property name="url" value="jdbc:mysql://yourDBurl:yourport/yourDBname" />
        <property name="username" value="youraccountname" />
        <property name="password" value="youraccountpassword" />
    </bean>

    <bean id="sqlSessionFactory" class="org.mybatis.spring.SqlSessionFactoryBean">
        <property name="dataSource" ref="dataSource" />
        <property name="mapperLocations" value="classpath:my/package/mapper/*.xml" />
    </bean>
<!--
// This is a part of the root-context.xml
// in `src/main/java/my/package/mapper`, there are XML mapper files. // "src/main/java"
// -- In my case, the mappers were in the classpath `src/main/java`
-->
</code>```

This was my original mapper setting (causing the error). This setting just worked all fine when I run the Spring project on the local server. Also in the case that I exported war file on eclipse then deploy the war with my own hand to the server manually. Also in the case that I exported war file on eclipse then deploy the war with Tomcat Manager to the server manually.

** But only not available on Jenkins. Maven build was always successful but only in deployment. **

* Solution *
=> I have changed the mapper setting in the Spring project, and migrated mappers from src/main/java to src/main/resources
=> The cause of the error I have guessed is that Jenkins cannot read, <property name="mapperLocations" value="classpath:my/package/mapper/*.xml" />, this configuration.
=> Same JDBC config, I only changed the mybatis setting like this.

```<code><!-- with same jdbc config -->
   <bean id="sqlSessionFactory" class="org.mybatis.spring.SqlSessionFactoryBean">
      <property name="dataSource" ref="dataSource" />
      <property name="configLocation" value="classpath:mybatis/mybatis-configuration.xml" />
   </bean>
<!--
// This is a part of the root-context.xml
// NOW in `src/main/resources/my/package/mapper`, there are XML mapper files. // "src/main/resources"
-->
</code>```

=> In  src/main/resources/mybatis-configuration.xml

```<code><?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE configuration PUBLIC "-//mybatis.org//DTD Config 3.0//EN" "http://mybatis.org/dtd/mybatis-3-config.dtd">
<configuration>
    <typeAliases>
        <!-- <typeAlias alias="yourDTO" type="my.package.dto.yourDTO"></typeAlias> -->
    </typeAliases>
    <mappers>
        <mapper resource="mybatis/mapper/yourmapper.xml" />
        <!-- mappers, and so on -->
    </mappers>
</configuration>
</code>```

=> Put the mybatis mappers in the directory, src/main/resources/mapper. Write yourmapper.xml like usual mybatis mapper XML file.

```<code><?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE mapper
  PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
  "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="my.package.dto.yourDTO">
    <!-- your mybatis tag with SQL query -->
</mapper>
</code>```

P.S.
-- I just have guessed that Jenkins cannot read the mappers in src/main/java.
-- I haven't actually understood or analyze the open-source code of Jenkins.
-- So the cause I pointed out might be wrong, but at least, the auto-deployment with Jenkins was available, in my mysterious case.
-- I hope this might be helpful.

Body:
I want to share some Jenkins auto-deployment issue solutions, that I could not find on the internet including here.

But I'm almost a freshman in StackOverflow, so I'm just here to ask myself and answer myself right away.

// I have tried to share the solution public on GitHub issue, I could not use it well, too.

// asking to be excused...

I'm using Spring MVC 4.3.9, connected to CI/CD.
// GitHub branch -> Jenkins -> TestServer (Tomcat 8.5)

I allowed all the IP addresses, made and set the right Tomcat Manager account both in Jenkins credentials menu and tomcat.
But the same error always occurs -- TomcatManagerException and also the illegal argument exception (in the full log from Jenkins by maven build option, -X -e, not sure).
// Same results, with both Deploy war plugin and SSH_publish plugin.

Here is the Jenkins console output. (I don't think this one is the full log.)

[INFO] ------------------------------------------------------------------------
[INFO] BUILD SUCCESS
[INFO] ------------------------------------------------------------------------
[INFO] Total time:  7.895 s
[INFO] Finished at: ~~~Time~~~
[INFO] ------------------------------------------------------------------------
[DeployPublisher][INFO] Attempting to deploy 1 war file(s)
[DeployPublisher][INFO] Deploying ~~YourDIR&WAR~~ to container Tomcat 8.x Remote with context ~~YourContextName~~
  Redeploying [ ~~YourDIR&WAR~~]
  Undeploying  ~~YourDIR&WAR~~]
  Deploying [ ~~YourDIR&WAR~~]
ERROR: Build step failed with exception
org.codehaus.cargo.container.ContainerException: Failed to deploy [ ~~YourDIR&WAR~~]
    at org.codehaus.cargo.container.tomcat.internal.AbstractTomcatManagerDeployer.deploy(AbstractTomcatManagerDeployer.java:104)
    at org.codehaus.cargo.container.tomcat.internal.AbstractTomcatManagerDeployer.redeploy(AbstractTomcatManagerDeployer.java:180)
    at hudson.plugins.deploy.CargoContainerAdapter.deploy(CargoContainerAdapter.java:81)
    at hudson.plugins.deploy.CargoContainerAdapter$DeployCallable.invoke(CargoContainerAdapter.java:167)
    at hudson.plugins.deploy.CargoContainerAdapter$DeployCallable.invoke(CargoContainerAdapter.java:136)
    at hudson.FilePath.act(FilePath.java:1075)
    at hudson.FilePath.act(FilePath.java:1058)
    at hudson.plugins.deploy.CargoContainerAdapter.redeployFile(CargoContainerAdapter.java:133)
    at hudson.plugins.deploy.PasswordProtectedAdapterCargo.redeployFile(PasswordProtectedAdapterCargo.java:95)
    at hudson.plugins.deploy.DeployPublisher.perform(DeployPublisher.java:113)
    at hudson.tasks.BuildStepCompatibilityLayer.perform(BuildStepCompatibilityLayer.java:78)
    at hudson.tasks.BuildStepMonitor$3.perform(BuildStepMonitor.java:45)
    at hudson.model.AbstractBuild$AbstractBuildExecution.perform(AbstractBuild.java:741)
    at hudson.model.AbstractBuild$AbstractBuildExecution.performAllBuildSteps(AbstractBuild.java:690)
    at hudson.model.Build$BuildExecution.post2(Build.java:186)
    at hudson.model.AbstractBuild$AbstractBuildExecution.post(AbstractBuild.java:635)
    at hudson.model.Run.execute(Run.java:1905)
    at hudson.model.FreeStyleBuild.run(FreeStyleBuild.java:43)
    at hudson.model.ResourceController.execute(ResourceController.java:97)
    at hudson.model.Executor.run(Executor.java:428)
Caused by: org.codehaus.cargo.container.tomcat.internal.TomcatManagerException: The Tomcat Manager responded "FAIL - Deployed application at context path [~~YourContextName~~] but context failed to start
" instead of the expected "OK" message
    at org.codehaus.cargo.container.tomcat.internal.TomcatManager.invoke(TomcatManager.java:721)
    at org.codehaus.cargo.container.tomcat.internal.TomcatManager.deployImpl(TomcatManager.java:767)
    at org.codehaus.cargo.container.tomcat.internal.TomcatManager.deploy(TomcatManager.java:312)
    at org.codehaus.cargo.container.tomcat.internal.AbstractTomcatManagerDeployer.deploy(AbstractTomcatManagerDeployer.java:99)
    ... 19 more
org.codehaus.cargo.container.tomcat.internal.TomcatManagerException: The Tomcat Manager responded "FAIL - Deployed application at context path [~~YourContextName~~] but context failed to start
" instead of the expected "OK" message
    at org.codehaus.cargo.container.tomcat.internal.TomcatManager.invoke(TomcatManager.java:721)
    at org.codehaus.cargo.container.tomcat.internal.TomcatManager.deployImpl(TomcatManager.java:767)
    at org.codehaus.cargo.container.tomcat.internal.TomcatManager.deploy(TomcatManager.java:312)
    at org.codehaus.cargo.container.tomcat.internal.AbstractTomcatManagerDeployer.deploy(AbstractTomcatManagerDeployer.java:99)
    at org.codehaus.cargo.container.tomcat.internal.AbstractTomcatManagerDeployer.redeploy(AbstractTomcatManagerDeployer.java:180)
    at hudson.plugins.deploy.CargoContainerAdapter.deploy(CargoContainerAdapter.java:81)
    at hudson.plugins.deploy.CargoContainerAdapter$DeployCallable.invoke(CargoContainerAdapter.java:167)
    at hudson.plugins.deploy.CargoContainerAdapter$DeployCallable.invoke(CargoContainerAdapter.java:136)
    at hudson.FilePath.act(FilePath.java:1075)
    at hudson.FilePath.act(FilePath.java:1058)
    at hudson.plugins.deploy.CargoContainerAdapter.redeployFile(CargoContainerAdapter.java:133)
    at hudson.plugins.deploy.PasswordProtectedAdapterCargo.redeployFile(PasswordProtectedAdapterCargo.java:95)
    at hudson.plugins.deploy.DeployPublisher.perform(DeployPublisher.java:113)
    at hudson.tasks.BuildStepCompatibilityLayer.perform(BuildStepCompatibilityLayer.java:78)
    at hudson.tasks.BuildStepMonitor$3.perform(BuildStepMonitor.java:45)
    at hudson.model.AbstractBuild$AbstractBuildExecution.perform(AbstractBuild.java:741)
    at hudson.model.AbstractBuild$AbstractBuildExecution.performAllBuildSteps(AbstractBuild.java:690)
    at hudson.model.Build$BuildExecution.post2(Build.java:186)
    at hudson.model.AbstractBuild$AbstractBuildExecution.post(AbstractBuild.java:635)
    at hudson.model.Run.execute(Run.java:1905)
    at hudson.model.FreeStyleBuild.run(FreeStyleBuild.java:43)
    at hudson.model.ResourceController.execute(ResourceController.java:97)
    at hudson.model.Executor.run(Executor.java:428)
Build step 'Deploy war/ear to a container' marked build as failure
Finished: FAILURE

* I also got illegal argument exception in maven console, in mapperLocations setting.

===> This is the key

Body:
    <bean id="dataSource" class="org.apache.commons.dbcp.BasicDataSource">
        <property name="driverClassName" value="org.mysql.jdbc.Driver" />
        <property name="url" value="jdbc:mysql://yourDBurl:yourport/yourDBname" />
        <property name="username" value="youraccountname" />
        <property name="password" value="youraccountpassword" />
    </bean>

    <bean id="sqlSessionFactory" class="org.mybatis.spring.SqlSessionFactoryBean">
        <property name="dataSource" ref="dataSource" />
        <property name="mapperLocations" value="classpath:my/package/mapper/*.xml" />
    </bean>
<!--
// This is a part of the root-context.xml
// in `src/main/java/my/package/mapper`, there are XML mapper files. // "src/main/java"
// -- In my case, the mappers were in the classpath `src/main/java`
-->

This was my original mapper setting (causing the error). This setting just worked all fine when I run the Spring project on the local server. Also in the case that I exported war file on eclipse then deploy the war with my own hand to the server manually. Also in the case that I exported war file on eclipse then deploy the war with Tomcat Manager to the server manually.

** But only not available on Jenkins. Maven build was always successful but only in deployment. **

* Solution *
=> I have changed the mapper setting in the Spring project, and migrated mappers from src/main/java to src/main/resources
=> The cause of the error I have guessed is that Jenkins cannot read, <property name="mapperLocations" value="classpath:my/package/mapper/*.xml" />, this configuration.
=> Same JDBC config, I only changed the mybatis setting like this.

<!-- with same jdbc config -->
   <bean id="sqlSessionFactory" class="org.mybatis.spring.SqlSessionFactoryBean">
      <property name="dataSource" ref="dataSource" />
      <property name="configLocation" value="classpath:mybatis/mybatis-configuration.xml" />
   </bean>
<!--
// This is a part of the root-context.xml
// NOW in `src/main/resources/my/package/mapper`, there are XML mapper files. // "src/main/resources"
-->

=> In  src/main/resources/mybatis-configuration.xml

<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE configuration PUBLIC "-//mybatis.org//DTD Config 3.0//EN" "http://mybatis.org/dtd/mybatis-3-config.dtd">
<configuration>
    <typeAliases>
        <!-- <typeAlias alias="yourDTO" type="my.package.dto.yourDTO"></typeAlias> -->
    </typeAliases>
    <mappers>
        <mapper resource="mybatis/mapper/yourmapper.xml" />
        <!-- mappers, and so on -->
    </mappers>
</configuration>

=> Put the mybatis mappers in the directory, src/main/resources/mapper. Write yourmapper.xml like usual mybatis mapper XML file.

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE mapper
  PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
  "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="my.package.dto.yourDTO">
    <!-- your mybatis tag with SQL query -->
</mapper>

P.S.
-- I just have guessed that Jenkins cannot read the mappers in src/main/java.
-- I haven't actually understood or analyze the open-source code of Jenkins.
-- So the cause I pointed out might be wrong, but at least, the auto-deployment with Jenkins was available, in my mysterious case.
-- I hope this might be helpful.


问:
Groovy: Create Object for add in LinkedHasMap
I novice in Groovy and Java.
I have function which returns LinkedHashMap from some Object. It works:

```<code>def get_map(Node) {
    nodeRootName = Node.name()
    if (Node.childNodes().size() == 0) {
        return [(nodeRootName): (Node.text())]
    } else {
        subMap = [(nodeRootName):[]]
        for (subNode in Node.childNodes()) {
            if (subNode.name() != "cryptoSigns") {
                subMap.(subMap.keySet()[0]).add(get_map(subNode))
            }
        }
        return subMap
    }
}
</code>```

Call this function in code:

```<code>    nodeMap = [(rootNodeName): [data:[]]]
    for (subNode in node.childNodes()[0].childNodes()) {
            nodeMap.position.data.add(get_map(subNode))
        }
    }
</code>```

Array [data:[]] of LinkedHashMap is formed.

Now, I need from array make one LinkedHasMap.
I try make one map in my function. It can be one map or a map array with a key. For exmple:

```<code>[data:[
 key1: value,
 key2:[
   [key: value],
   [key: [
    [key: value],
    [key: value]
   ]
 ]
]]
</code>```

I try:

```<code>def get_map(Node) {
    nodeRootName = Node.name()
    if (Node.childNodes().size() == 0) {
        Map map = new HashMap()
        map.put((nodeRootName), (Node.text()))
        return map
    } else {
        Map subMap = new HashMap()
        for (subNode in Node.childNodes()) {
            subMap.put((nodeRootName), (get_map(subNode)))
        }
        return subMap
    }
}
</code>```

Call function:

```<code> Map nodeMap = new HashMap()
 Map data = new HashMap()
 for (subNode in node.childNodes()[0].childNodes()) {
      data.put(get_map(subNode))
      nodeMap.put((rootNodeName): (data))
 }
 jsonObject.nsiKTRUs.add(nodeMap)
</code>```

But I have error:
groovy.lang.MissingMethodException: No signature of method: java.util.HashMap.put() is applicable for argument types: (HashMap) values: [[code:01.11.11.111-00001]] at data.put(get_map(subNode))

How correct add my values in map?
My input data:

```<code><xml>
 <data>
   <key>value</key>
     <key2>
       <key21>value</key>
       <key22>value</key>
       <key23>
         <key231>value</key>
       </key>
    </key2>
 </data>
<xml>
</code>```

Custom embedding.

Need output

```<code>[data:[
    key: value,
    key2:[
        key21: value,
        key22: value,
        key23:[
          key231: value
        ]
     ]
 ]
]
</code>```

and output data need add to another LinkedHashMap

答:
I would put it to something like:

```<code>import groovy.util.*
import groovy.json.*

def text = '''<xml>
<data>
  <key>value1</key>
    <key2>
      <key21>value21</key21>
      <key22>value22</key22>
      <key23>
        <key231>value</key231>
      </key23>
   </key2>
</data>
</xml>'''

def xml = new XmlParser().parseText( text )

def handle
handle = { node ->
  if( node in String )
    node
  else{
    def val = node.collect handle
    [ (node.name()):1 == val.size() ? val.first() : val.collectEntries{ it } ]
  }
}

def map = xml.collect handle

// this line is needed for pretty print only
JsonOutput.prettyPrint JsonOutput.toJson( map )
</code>```

outputs:

```<code>[
    {
        "data": {
            "key": "value1",
            "key2": {
                "key21": "value21",
                "key22": "value22",
                "key23": {
                    "key231": "value"
                }
            }
        }
    }
]
</code>```

Body:
I novice in Groovy and Java.
I have function which returns LinkedHashMap from some Object. It works:

def get_map(Node) {
    nodeRootName = Node.name()
    if (Node.childNodes().size() == 0) {
        return [(nodeRootName): (Node.text())]
    } else {
        subMap = [(nodeRootName):[]]
        for (subNode in Node.childNodes()) {
            if (subNode.name() != "cryptoSigns") {
                subMap.(subMap.keySet()[0]).add(get_map(subNode))
            }
        }
        return subMap
    }
}

Call this function in code:

    nodeMap = [(rootNodeName): [data:[]]]
    for (subNode in node.childNodes()[0].childNodes()) {
            nodeMap.position.data.add(get_map(subNode))
        }
    }

Array [data:[]] of LinkedHashMap is formed.

Now, I need from array make one LinkedHasMap.
I try make one map in my function. It can be one map or a map array with a key. For exmple:

[data:[
 key1: value,
 key2:[
   [key: value],
   [key: [
    [key: value],
    [key: value]
   ]
 ]
]]

I try:

def get_map(Node) {
    nodeRootName = Node.name()
    if (Node.childNodes().size() == 0) {
        Map map = new HashMap()
        map.put((nodeRootName), (Node.text()))
        return map
    } else {
        Map subMap = new HashMap()
        for (subNode in Node.childNodes()) {
            subMap.put((nodeRootName), (get_map(subNode)))
        }
        return subMap
    }
}

Call function:

 Map nodeMap = new HashMap()
 Map data = new HashMap()
 for (subNode in node.childNodes()[0].childNodes()) {
      data.put(get_map(subNode))
      nodeMap.put((rootNodeName): (data))
 }
 jsonObject.nsiKTRUs.add(nodeMap)

But I have error:
groovy.lang.MissingMethodException: No signature of method: java.util.HashMap.put() is applicable for argument types: (HashMap) values: [[code:01.11.11.111-00001]] at data.put(get_map(subNode))

How correct add my values in map?
My input data:

<xml>
 <data>
   <key>value</key>
     <key2>
       <key21>value</key>
       <key22>value</key>
       <key23>
         <key231>value</key>
       </key>
    </key2>
 </data>
<xml>

Custom embedding.

Need output

[data:[
    key: value,
    key2:[
        key21: value,
        key22: value,
        key23:[
          key231: value
        ]
     ]
 ]
]

and output data need add to another LinkedHashMap

Body:
I would put it to something like:

import groovy.util.*
import groovy.json.*

def text = '''<xml>
<data>
  <key>value1</key>
    <key2>
      <key21>value21</key21>
      <key22>value22</key22>
      <key23>
        <key231>value</key231>
      </key23>
   </key2>
</data>
</xml>'''

def xml = new XmlParser().parseText( text )

def handle
handle = { node ->
  if( node in String )
    node
  else{
    def val = node.collect handle
    [ (node.name()):1 == val.size() ? val.first() : val.collectEntries{ it } ]
  }
}

def map = xml.collect handle

// this line is needed for pretty print only
JsonOutput.prettyPrint JsonOutput.toJson( map )

outputs:

[
    {
        "data": {
            "key": "value1",
            "key2": {
                "key21": "value21",
                "key22": "value22",
                "key23": {
                    "key231": "value"
                }
            }
        }
    }
]


问:
How can I populate a ListView on a SecondActivity with data from FirstActivity in Android?
I'm working on a book-searching app project. The user enters a title, and the app searches Google Books for it.

I initially had one activity and layout. I decided to use two layouts (one for user to enter title, and the other displays results); had to create another activity because the results layout was throwing an exception about 'null' object reference.

After creating the second activity, I used an intent to transfer List data between the two activities; no sooner did I find out that I had to use a Serialize or Parcelable object for the purpose.

Following instructions at Pass list of objects from one activity to other activity in android & https://www.vogella.com/tutorials/AndroidParcelable/article.html, I failed at implementing both, because Serialize sent an empty ArrayList (thus, an empty results page, even though there're book hits) and Parcelable was throwing out different exceptions everytime I used it, probably because I'm using an ArrayAdapter to populate the ListView with books.

I don't think I'm ready to implement the API at https://www.vogella.com/tutorials/AutoValue/article.html and can't use Fragments as well. A better structure would be to use a single activity, View.GONE the background image I so much cherish, and display list of book objects under the search field. But it would be good to make a follow-up on Serialize & Parcelable -- for future projects.
So, fellow developers, what's the solution to this?

FirstActivity screenshot
SecondActivity screeenshot

Here's my code:
MainActivity:

```<code>package project.android.gbookslisting;

import android.app.LoaderManager;
import android.content.Intent;
import android.content.Loader;
import android.graphics.Color;
import android.os.Bundle;
import android.util.Log;
import android.view.View;
import android.widget.Button;
import android.widget.EditText;

import java.io.Serializable;
import java.util.ArrayList;
import java.util.List;

import androidx.appcompat.app.AppCompatActivity;

import static project.android.gbookslisting.ResultsActivity.adapter;

//import android.support.v4.content.AsyncTaskLoader;
//import android.support.v7.app.AppCompatActivity;

public class ParamsActivity extends AppCompatActivity implements LoaderManager.LoaderCallbacks<List<Book>>, Serializable {

    private static final int LOADER_ID = 0;
    private static String LOG_TAG = ParamsActivity.class.getName();
    EditText text;
    String query;
    private LoaderManager loaderManager = getLoaderManager();

    @Override
    protected void onCreate (Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.parameters);

        Button query = findViewById(R.id.search_button);
        text = findViewById(R.id.deets_field);

        query.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick (View view) {
                if (text.getText().toString().length() > 0) {                    loaderManager.initLoader(LOADER_ID, null, ParamsActivity.this);
                } else if (text.getText().length() < 1) {
                    text.setHint("Please enter book title/details");
                    text.setHintTextColor(Color.RED);
                }
            }
        });

    }

    @Override
    public Loader<List<Book>> onCreateLoader (int i, Bundle bundle) {
        query = text.getText().toString();
        return new BookLoader(this, query);
    }

    @Override
    public void onLoadFinished (Loader<List<Book>> loader, List<Book> data) {
        // If there is a valid list of {@link Book}s, then add them to the adapter's dataset. This will trigger the ListView to update.
        if (data != null && !data.isEmpty()) {

            data = new ArrayList<Book>();

            Intent i = new Intent(getApplicationContext(), ResultsActivity.class);
            i.putExtra("data", (Serializable) data);
            startActivity(i);
        }
    }

    @Override
    public void onLoaderReset (Loader loader) {
        adapter = new Adapt(this, new ArrayList<Book>());
        adapter.clear();
    }

}
</code>```

SecondActivity:

```<code>package project.android.gbookslisting;

import android.content.Intent;
import android.net.Uri;
import android.os.Bundle;
import android.util.Log;
import android.view.View;
import android.widget.AdapterView;
import android.widget.ListView;
import android.widget.TextView;

import java.io.Serializable;
import java.util.ArrayList;

import androidx.appcompat.app.AppCompatActivity;

public class ResultsActivity extends AppCompatActivity implements Serializable {

    static Adapt adapter;
    static TextView emptyResult;
    ListView bookEntries;
    String LOG_TAG = ResultsActivity.class.getName();

    @Override
    protected void onCreate (Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.hits_page);

        Intent i = getIntent();
        ArrayList<Book> books = (ArrayList<Book>) i.getSerializableExtra("data");

        emptyResult = findViewById(R.id.matches_nill);
        emptyResult.setText(R.string.matches0);

        if (!books.isEmpty()) {
            emptyResult.setVisibility(View.GONE);

            // Create a new adapter that takes a rich (or otherwise empty) list of books as input
            adapter = new Adapt(this, new ArrayList<Book>());

            // Get the list of books from {@link Search}
            bookEntries = findViewById(R.id.catalog);

            bookEntries.setAdapter(adapter);
            bookEntries.setEmptyView(emptyResult);

            bookEntries.setOnItemClickListener(new AdapterView.OnItemClickListener() {
                @Override
                public void onItemClick (AdapterView<?> adapterView, View view, int position, long l) {
                    // Find the current book that was clicked on
                    Book currentBook = adapter.getItem(position);

                    // Convert the String URL into a URI object (to pass into the Intent constructor)
                    Uri bookUri = Uri.parse(currentBook.getPage());

                    // Create a new intent to view the book URI
                    Intent websiteIntent = new Intent(Intent.ACTION_VIEW, bookUri);

                    // Send the intent to launch a new activity
                    startActivity(websiteIntent);
                }
            });

//            adapter.clear();

            adapter.addAll(books);
        } else {
            emptyResult.setVisibility(View.VISIBLE);
            emptyResult.setText(R.string.matches0);
        }

    }
}
</code>```

Book obj.:

```<code>package project.android.gbookslisting;

import java.io.Serializable;
import java.util.Date;

public class Book {

    private String book_title;
    private String author;
    private String publishing_year;
    private String page;

    public Book (String theTitle, String theAuthor, String theYear, String thePage) {
        this.book_title = theTitle;
        this.author = theAuthor;
        this.publishing_year = theYear;
        this.page = thePage;
    }

    public Book setBook_title (String book_title) {
        this.book_title = book_title;
        return this;
    }

    public Book setAuthor (String author) {
        this.author = author;
        return this;
    }

    public Book setPublishing_year (String publishing_year) {
        this.publishing_year = publishing_year;
        return this;
    }

    public Book setPage (String page) {
        this.page = page;
        return this;
    }

    protected String getAuthor () {
        return author;
    }

    protected String getPublishing_year () { return publishing_year; }

    protected String getPage () {
        return page;
    }

    protected String getBook_title () {
        return book_title;
    }
}
</code>```

答:
All right, so I was able to correct my implementation of the Parcelable interface and the FirstActivity now passes data to SecondActivity. This is it:

package project.android.gbookslisting;

import android.os.Parcel;
import android.os.Parcelable;

public class Book implements Parcelable {

    private String book_title;
    private String author;
    private String publishing_year;
    private String page;

    public Book (String theTitle, String theAuthor, String theYear, String thePage) {
        this.book_title = theTitle;
        this.author = theAuthor;
        this.publishing_year = theYear;
        this.page = thePage;
    }

    public Book(Parcel in) {
        this.book_title = in.readString();
        this.author = in.readString();
        this.publishing_year = in.readString();
        this.page = in.readString();
    }

    public static final Creator<Book> CREATOR = new Creator<Book>() {
        @Override
        public Book createFromParcel (Parcel in) {
            return new Book(in);
        }

        @Override
        public Book[] newArray (int size) {
            return new Book[size];
        }
    };

    protected String getAuthor () { return author; }

    protected String getPublishing_year () { return publishing_year; }

    protected String getPage () {
        return page;
    }

    protected String getBook_title () {
        return book_title;
    }

    @Override
    public int describeContents () {
        return 0;
    }

    @Override
    public void writeToParcel (Parcel parcel, int flags) {
        parcel.writeString(book_title);
        parcel.writeString(author);
        parcel.writeString(publishing_year);
        parcel.writeString(page);
    }

}
```

I've shared the repository on GitHub @GBooks Listing, pending more features/updates.

ResultsActivity
Sure looks lame, but I'll improve the theming & whatever affects appearance. Thanks.

Body:
I'm working on a book-searching app project. The user enters a title, and the app searches Google Books for it.

I initially had one activity and layout. I decided to use two layouts (one for user to enter title, and the other displays results); had to create another activity because the results layout was throwing an exception about 'null' object reference.

After creating the second activity, I used an intent to transfer List data between the two activities; no sooner did I find out that I had to use a Serialize or Parcelable object for the purpose.

Following instructions at Pass list of objects from one activity to other activity in android & https://www.vogella.com/tutorials/AndroidParcelable/article.html, I failed at implementing both, because Serialize sent an empty ArrayList (thus, an empty results page, even though there're book hits) and Parcelable was throwing out different exceptions everytime I used it, probably because I'm using an ArrayAdapter to populate the ListView with books.

I don't think I'm ready to implement the API at https://www.vogella.com/tutorials/AutoValue/article.html and can't use Fragments as well. A better structure would be to use a single activity, View.GONE the background image I so much cherish, and display list of book objects under the search field. But it would be good to make a follow-up on Serialize & Parcelable -- for future projects.
So, fellow developers, what's the solution to this?

FirstActivity screenshot
SecondActivity screeenshot

Here's my code:
MainActivity:

package project.android.gbookslisting;

import android.app.LoaderManager;
import android.content.Intent;
import android.content.Loader;
import android.graphics.Color;
import android.os.Bundle;
import android.util.Log;
import android.view.View;
import android.widget.Button;
import android.widget.EditText;

import java.io.Serializable;
import java.util.ArrayList;
import java.util.List;

import androidx.appcompat.app.AppCompatActivity;

import static project.android.gbookslisting.ResultsActivity.adapter;

//import android.support.v4.content.AsyncTaskLoader;
//import android.support.v7.app.AppCompatActivity;

public class ParamsActivity extends AppCompatActivity implements LoaderManager.LoaderCallbacks<List<Book>>, Serializable {

    private static final int LOADER_ID = 0;
    private static String LOG_TAG = ParamsActivity.class.getName();
    EditText text;
    String query;
    private LoaderManager loaderManager = getLoaderManager();

    @Override
    protected void onCreate (Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.parameters);

        Button query = findViewById(R.id.search_button);
        text = findViewById(R.id.deets_field);

        query.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick (View view) {
                if (text.getText().toString().length() > 0) {                    loaderManager.initLoader(LOADER_ID, null, ParamsActivity.this);
                } else if (text.getText().length() < 1) {
                    text.setHint("Please enter book title/details");
                    text.setHintTextColor(Color.RED);
                }
            }
        });

    }

    @Override
    public Loader<List<Book>> onCreateLoader (int i, Bundle bundle) {
        query = text.getText().toString();
        return new BookLoader(this, query);
    }

    @Override
    public void onLoadFinished (Loader<List<Book>> loader, List<Book> data) {
        // If there is a valid list of {@link Book}s, then add them to the adapter's dataset. This will trigger the ListView to update.
        if (data != null && !data.isEmpty()) {

            data = new ArrayList<Book>();

            Intent i = new Intent(getApplicationContext(), ResultsActivity.class);
            i.putExtra("data", (Serializable) data);
            startActivity(i);
        }
    }

    @Override
    public void onLoaderReset (Loader loader) {
        adapter = new Adapt(this, new ArrayList<Book>());
        adapter.clear();
    }

}

SecondActivity:

package project.android.gbookslisting;

import android.content.Intent;
import android.net.Uri;
import android.os.Bundle;
import android.util.Log;
import android.view.View;
import android.widget.AdapterView;
import android.widget.ListView;
import android.widget.TextView;

import java.io.Serializable;
import java.util.ArrayList;

import androidx.appcompat.app.AppCompatActivity;

public class ResultsActivity extends AppCompatActivity implements Serializable {

    static Adapt adapter;
    static TextView emptyResult;
    ListView bookEntries;
    String LOG_TAG = ResultsActivity.class.getName();

    @Override
    protected void onCreate (Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.hits_page);

        Intent i = getIntent();
        ArrayList<Book> books = (ArrayList<Book>) i.getSerializableExtra("data");

        emptyResult = findViewById(R.id.matches_nill);
        emptyResult.setText(R.string.matches0);

        if (!books.isEmpty()) {
            emptyResult.setVisibility(View.GONE);

            // Create a new adapter that takes a rich (or otherwise empty) list of books as input
            adapter = new Adapt(this, new ArrayList<Book>());

            // Get the list of books from {@link Search}
            bookEntries = findViewById(R.id.catalog);

            bookEntries.setAdapter(adapter);
            bookEntries.setEmptyView(emptyResult);

            bookEntries.setOnItemClickListener(new AdapterView.OnItemClickListener() {
                @Override
                public void onItemClick (AdapterView<?> adapterView, View view, int position, long l) {
                    // Find the current book that was clicked on
                    Book currentBook = adapter.getItem(position);

                    // Convert the String URL into a URI object (to pass into the Intent constructor)
                    Uri bookUri = Uri.parse(currentBook.getPage());

                    // Create a new intent to view the book URI
                    Intent websiteIntent = new Intent(Intent.ACTION_VIEW, bookUri);

                    // Send the intent to launch a new activity
                    startActivity(websiteIntent);
                }
            });

//            adapter.clear();

            adapter.addAll(books);
        } else {
            emptyResult.setVisibility(View.VISIBLE);
            emptyResult.setText(R.string.matches0);
        }

    }
}

Book obj.:

package project.android.gbookslisting;

import java.io.Serializable;
import java.util.Date;

public class Book {

    private String book_title;
    private String author;
    private String publishing_year;
    private String page;

    public Book (String theTitle, String theAuthor, String theYear, String thePage) {
        this.book_title = theTitle;
        this.author = theAuthor;
        this.publishing_year = theYear;
        this.page = thePage;
    }

    public Book setBook_title (String book_title) {
        this.book_title = book_title;
        return this;
    }

    public Book setAuthor (String author) {
        this.author = author;
        return this;
    }

    public Book setPublishing_year (String publishing_year) {
        this.publishing_year = publishing_year;
        return this;
    }

    public Book setPage (String page) {
        this.page = page;
        return this;
    }

    protected String getAuthor () {
        return author;
    }

    protected String getPublishing_year () { return publishing_year; }

    protected String getPage () {
        return page;
    }

    protected String getBook_title () {
        return book_title;
    }
}

Body:
All right, so I was able to correct my implementation of the Parcelable interface and the FirstActivity now passes data to SecondActivity. This is it:

package project.android.gbookslisting;

import android.os.Parcel;
import android.os.Parcelable;

public class Book implements Parcelable {

    private String book_title;
    private String author;
    private String publishing_year;
    private String page;

    public Book (String theTitle, String theAuthor, String theYear, String thePage) {
        this.book_title = theTitle;
        this.author = theAuthor;
        this.publishing_year = theYear;
        this.page = thePage;
    }

    public Book(Parcel in) {
        this.book_title = in.readString();
        this.author = in.readString();
        this.publishing_year = in.readString();
        this.page = in.readString();
    }

    public static final Creator<Book> CREATOR = new Creator<Book>() {
        @Override
        public Book createFromParcel (Parcel in) {
            return new Book(in);
        }

        @Override
        public Book[] newArray (int size) {
            return new Book[size];
        }
    };

    protected String getAuthor () { return author; }

    protected String getPublishing_year () { return publishing_year; }

    protected String getPage () {
        return page;
    }

    protected String getBook_title () {
        return book_title;
    }

    @Override
    public int describeContents () {
        return 0;
    }

    @Override
    public void writeToParcel (Parcel parcel, int flags) {
        parcel.writeString(book_title);
        parcel.writeString(author);
        parcel.writeString(publishing_year);
        parcel.writeString(page);
    }

}

I've shared the repository on GitHub @GBooks Listing, pending more features/updates.

ResultsActivity
Sure looks lame, but I'll improve the theming & whatever affects appearance. Thanks.


问:
Submitted a pull request, which was merged, now I need to update my fork
Here is what I did:

Forked a repo

Created new feature branch on my fork

Submitted PR to original repo master (accepted, merged)

Next How Do I:

Update "master" in my own fork?

答:
As suggested in the comments, the relevant operation is fork synchronization:

Add the upstream remote, call it "upstream"

git fetch from the upstream remote

```<code>git fetch upstream
</code>```

check out "master" from my fork

```<code>git checkout master
</code>```

merge the upstream master (which now has my accepted changes) into my master

```<code>git merge upstream/master
</code>```

Body:
As suggested in the comments, the relevant operation is fork synchronization:

Add the upstream remote, call it "upstream"

git fetch from the upstream remote

git fetch upstream

check out "master" from my fork

git checkout master

merge the upstream master (which now has my accepted changes) into my master

git merge upstream/master


问:
How to make network request only after the user stops typing
I know this question has been asked many times over but I can't get any of the solutions to work.

I am implementing a TextWatcher and I want to make a network request but only when the user has finished typing.
Here is my code.

```<code>val StartFragment.textWatcher: TextWatcher
    get() = object : TextWatcher {
        override fun onTextChanged(s: CharSequence?, start: Int, before: Int, count: Int) {
            searchPlaces(s)
        }

        override fun afterTextChanged(s: Editable?) {}
        override fun beforeTextChanged(s: CharSequence?, start: Int, count: Int, after: Int) {}
    }
</code>```

How do I wait to find out if the user is not typing anymore before performing searchPlaces(s).

答:
I have been able to solve the problem by setting up a Timer in the ViewModel thanks to user2340612's comment.

```<code> // In the ViewModel
 private var timer = Timer()
 private val delay: Long = 500L

 fun searchPlaces(placeName: String) {
        searchWord.value = placeName
        timer.cancel()
        timer = Timer()
        timer.schedule(object: TimerTask() {
            override fun run() {
                viewModelScope.launch {
                    repository.searchPlaces(placeName)
                }
            }
        }, delay)
    }
</code>```

Body:
I know this question has been asked many times over but I can't get any of the solutions to work.

I am implementing a TextWatcher and I want to make a network request but only when the user has finished typing.
Here is my code.

val StartFragment.textWatcher: TextWatcher
    get() = object : TextWatcher {
        override fun onTextChanged(s: CharSequence?, start: Int, before: Int, count: Int) {
            searchPlaces(s)
        }

        override fun afterTextChanged(s: Editable?) {}
        override fun beforeTextChanged(s: CharSequence?, start: Int, count: Int, after: Int) {}
    }

How do I wait to find out if the user is not typing anymore before performing searchPlaces(s).

Body:
I have been able to solve the problem by setting up a Timer in the ViewModel thanks to user2340612's comment.

 // In the ViewModel
 private var timer = Timer()
 private val delay: Long = 500L

 fun searchPlaces(placeName: String) {
        searchWord.value = placeName
        timer.cancel()
        timer = Timer()
        timer.schedule(object: TimerTask() {
            override fun run() {
                viewModelScope.launch {
                    repository.searchPlaces(placeName)
                }
            }
        }, delay)
    }


问:
Reference indicator from within a Pine script
Let's say I want to include the AO indicator as part of the criteria for my Pine script. How can a pine script access indicators? Can a strategy or study import a series generated by another Pine script or built-in indicators?</p>

答:
You can't access indicators if they're not provided by built-in functions.

In your specific case of the Awesome Oscillator, you could calculate it yourself to get the series values.

See Awesome Oscillator (AO) for how it's calculated.

edit:

I just found out that it does seem to be possible if the desired indicator is on your chart.

See How can I use one script’s output as an input into another?

Screenshot of example with the Awesome Oscillator:


问:
Append is overwriting existing data in list of classes
I'm making a sudoku solving program in Python.

I have a class, an inner class, a list, constructors and a function that would make the list of Row objects.

```<code>    class Table:

       rows = []

       def __init__(self):
          initRows()

       class Row:

          numbers = []

          def __init__(self):
             "stuff that stores a list of integers in **numbers** list"

       def initRows(self, numbers):
          for i in range(9):
             temp_row = self.Row(i, numbers)
             self.rows.append(temp_row)
</code>```

The program goes like this:

When a Table object is created it automatically tries to make a 9 length list of Row objects with the initRows() function.

In the initRows() function we just create a temporary object of class Row and instantly append() it to the rows list.

When we create a Row object it just stores the given numbers for the given row of the sudoku table.

If I print() the numbers list of each temporary Row object after it is created then it gives the correct values.

```<code>[0, 0, 0, 7, 4, 0, 0, 0, 6]
[4, 0, 6, 8, 0, 0, 5, 0, 7]
[7, 0, 0, 0, 9, 0, 0, 0, 4]
[0, 3, 0, 9, 8, 4, 7, 0, 0]
[8, 2, 0, 6, 1, 3, 4, 0, 9]
[0, 4, 0, 0, 0, 0, 3, 0, 0]
[0, 6, 2, 3, 7, 0, 0, 0, 5]
[0, 0, 5, 4, 0, 9, 0, 0, 0]
[0, 7, 0, 0, 6, 1, 2, 0, 8]
</code>```

But when I try to print() the values of each Row object after the for loop loops once or more or after the initialization is finished then the list is filled with only the last Row object

```<code>[0, 7, 0, 0, 6, 1, 2, 0, 8]
[0, 7, 0, 0, 6, 1, 2, 0, 8]
[0, 7, 0, 0, 6, 1, 2, 0, 8]
[0, 7, 0, 0, 6, 1, 2, 0, 8]
[0, 7, 0, 0, 6, 1, 2, 0, 8]
[0, 7, 0, 0, 6, 1, 2, 0, 8]
[0, 7, 0, 0, 6, 1, 2, 0, 8]
[0, 7, 0, 0, 6, 1, 2, 0, 8]
[0, 7, 0, 0, 6, 1, 2, 0, 8]
[0, 7, 0, 0, 6, 1, 2, 0, 8]
</code>```

I was searching on the internet for hours and found that people have issues with the append() function of the list class but nothing helped.

So my question is: How could I make this work?

(If any other information/part of code is needed: ask away!)

答: It turns out in the Row class the numbers list was a class attribute (means it's shared across all objects of the Row class) rather than an instance attribute.

Body:
I'm making a sudoku solving program in Python.

I have a class, an inner class, a list, constructors and a function that would make the list of Row objects.

    class Table:

       rows = []

       def __init__(self):
          initRows()

       class Row:

          numbers = []

          def __init__(self):
             "stuff that stores a list of integers in **numbers** list"

       def initRows(self, numbers):
          for i in range(9):
             temp_row = self.Row(i, numbers)
             self.rows.append(temp_row)

The program goes like this:

When a Table object is created it automatically tries to make a 9 length list of Row objects with the initRows() function.

In the initRows() function we just create a temporary object of class Row and instantly append() it to the rows list.

When we create a Row object it just stores the given numbers for the given row of the sudoku table.

If I print() the numbers list of each temporary Row object after it is created then it gives the correct values.

[0, 0, 0, 7, 4, 0, 0, 0, 6]
[4, 0, 6, 8, 0, 0, 5, 0, 7]
[7, 0, 0, 0, 9, 0, 0, 0, 4]
[0, 3, 0, 9, 8, 4, 7, 0, 0]
[8, 2, 0, 6, 1, 3, 4, 0, 9]
[0, 4, 0, 0, 0, 0, 3, 0, 0]
[0, 6, 2, 3, 7, 0, 0, 0, 5]
[0, 0, 5, 4, 0, 9, 0, 0, 0]
[0, 7, 0, 0, 6, 1, 2, 0, 8]

But when I try to print() the values of each Row object after the for loop loops once or more or after the initialization is finished then the list is filled with only the last Row object

[0, 7, 0, 0, 6, 1, 2, 0, 8]
[0, 7, 0, 0, 6, 1, 2, 0, 8]
[0, 7, 0, 0, 6, 1, 2, 0, 8]
[0, 7, 0, 0, 6, 1, 2, 0, 8]
[0, 7, 0, 0, 6, 1, 2, 0, 8]
[0, 7, 0, 0, 6, 1, 2, 0, 8]
[0, 7, 0, 0, 6, 1, 2, 0, 8]
[0, 7, 0, 0, 6, 1, 2, 0, 8]
[0, 7, 0, 0, 6, 1, 2, 0, 8]
[0, 7, 0, 0, 6, 1, 2, 0, 8]

I was searching on the internet for hours and found that people have issues with the append() function of the list class but nothing helped.

So my question is: How could I make this work?

(If any other information/part of code is needed: ask away!)


问:
Do I gain anything by using "proper" replicas for a read-only MongoDB database?
I have a web-app that depends on a read-only MongoDB database. Through trial and error, I discovered that by far the fastest way to run the ETL pipeline that populates the database is to run a local copy of MongoDB, populate the database, stop the database, and tarball the state directory.

To deploy a high-availability "cluster," I create multiple instances (or containers) running the app, each with access to a copy of the state in locally mounted storage. Putting these behind a load balancer with regular health checks and autoscaling (or in a Kubernetes cluster as a ReplicaSet), I get isolation, redundancy, easy rollbacks (using versioned storage), and easy setup in virtually any environment.

The key idea here is that because the database is read-only, it is in a sense a "stateless" application. Thus, I can treat it like any other static provider of information

There are many apparent advantages to this setup. Nevertheless, I have always had a nagging feeling that I was missing something. Given a read-only context, is there still some reason why it might be better to run a "proper" MongoDB cluster?

答: If you don't mind outages when the single node goes down and you don't mind taking the system down during upgrades then this is probably an ok deployment. You might get a safer dump and restore using mongodump and mongorestore rather than tar but apart from that this setup should work for a read-only deployment.


问:
Sklearn Model (Python) with NodeJS (Express): how to connect both?
I have a web server using NodeJS - Express and I have a Scikit-Learn (machine learning) model pickled (dumped) in the same machine.

What I need is to demonstrate the model by sending/receiving data from it to the server. I want to load the model on startup of the web server and keep "listening" for data inputs. When receive data, executes a prediction and send it back.

I am relatively new to Python. From what I've seen I could use a "Child Process" to execute that. I also saw some modules that run Python script from Node.

The problem is I want to load the model once and let it be for as long as the server is on. I don't want to keep loading the model every time due to it's size. How is the best way to perform that?

The idea is running everything in a AWS machine.

Thank you in advance.

答:
My recommendation: write a simple python web service (personally recommend flask) and deploy your ML model. Then you can easily send requests to your python web service from your node back-end. You wouldn't have a problem with the initial model loading. it is done once in the app startup, and then you're good to go

DO NOT GO FOR SCRIPT EXECUTIONS AND CHILD PROCESSES!!! I just wrote it in bold-italic all caps so to be sure you wouldn't do that. Believe me... it potentially go very very south, with all that zombie processes upon job termination and other stuff. let's just simply say it's not the standard way to do that.

You need to think about multi-request handling. I think flask now has it by default

I am just giving you general hints because your problem has been generally introduced.


问:
How to return elements of array matching criteria in MongoDB
I'm new to mongodb and I'm still trying to wrap my head around queries so forgive me if my question is too simple or have been answered elsewhere.

I have a collection like the one below

```<code>[
{"_id":1,
"data" :[{"a":1,"b":2},{"a":1,"b":3},{"a":2,"b":3},{"a":4,"b":1}]
},
{"_id":2,
"data" :[{"a":3,"b":2},{"a":2,"b":4},{"a":5,"b":3},{"a":7,"b":1}]
}
]
</code>```

How can I write a query that looks inside the data array of the first document and returns all elements where "a" is equal to one.

Something like this is the expected output:

```<code>[{"a":1,"b":2},{"a":1,"b":3}]
</code>```

This is my current attempt

```<code>db.myCollection.find({_id:1},{data: {$elemMatch: {a : 1}}})
</code>```

But this gives me

```<code>{"_id": 1, "data":
[{"a":1,"b":2},{"a":1,"b":3}]
}
</code>```

I don't need or want anything other than the results in "data".

Can someone give me a hand?

I'd also appreciate any pointers for sifting through an array in a document for elements matching more general conditions on a single document (ie for the example above finding the documents where a+b < 5, a > b, a>1 and b>2, a >3 or b<1, etc.)

Edit: I'm using mongodb version 4.2.6

答:
$filter is the general purpose way to, well, filter arrays inside of docs.   Expanding your input set to give a little more context and variety:

```<code>var r =
[
 {
     "_id": 0,
     "other":6,
     "data" :[{"a":1,"b":2,"c":"X"},
              {"a":1,"b":3,"c":"Y"},
              {"a":2,"b":3,"c":"Q"},
              {"a":4,"b":1,"c":"Z"}]
 },
 {
     "_id": 1,
     "other":7,
     "data" :[{"a":1,"b":2,"c":"A"},
              {"a":1,"b":3,"c":"B"},
              {"a":7,"b":7,"c":"C"},
              {"a":1,"b":8,"c":"D"}]
 }
];
db.foo.insert(r);
</code>```

Then these two pipelines demo the versatility of $filter:

```<code>c = db.foo.aggregate([
{$project: {_id:false,
            // Notice input is $data and output project is data; this
            // means overwrite the old data array with the filtered array.
            // Also:  The double dollar is how we reference the "as"
            // variable.  Single dollar variables refer to the fields
            // of the incoming doc; we show how to use $other in this
            // example.   $other remains constant for the doc as $filter
            // marches down the $data array:
            data: {$filter: {
                input: "$data",
                as: "z",
                cond: { $lt: [ {$add:["$$z.a","$$z.b"]} , "$other" ]}
            }}
    }}
                       ]);

c = db.foo.aggregate([
{$project: {_id:true,
            data: {$filter: {
                input: "$data",
                as: "z",
                cond: { $or: [ {$gt:["$$z.a",3]}, {$lt:["$$z.b",7]} ] }
            }}
    }}
                       ]);
</code>```

Body:
I'm new to mongodb and I'm still trying to wrap my head around queries so forgive me if my question is too simple or have been answered elsewhere.

I have a collection like the one below

[
{"_id":1,
"data" :[{"a":1,"b":2},{"a":1,"b":3},{"a":2,"b":3},{"a":4,"b":1}]
},
{"_id":2,
"data" :[{"a":3,"b":2},{"a":2,"b":4},{"a":5,"b":3},{"a":7,"b":1}]
}
]

How can I write a query that looks inside the data array of the first document and returns all elements where "a" is equal to one.

Something like this is the expected output:

[{"a":1,"b":2},{"a":1,"b":3}]

This is my current attempt

db.myCollection.find({_id:1},{data: {$elemMatch: {a : 1}}})

But this gives me

{"_id": 1, "data":
[{"a":1,"b":2},{"a":1,"b":3}]
}

I don't need or want anything other than the results in "data".

Can someone give me a hand?

I'd also appreciate any pointers for sifting through an array in a document for elements matching more general conditions on a single document (ie for the example above finding the documents where a+b < 5, a > b, a>1 and b>2, a >3 or b<1, etc.)

Edit: I'm using mongodb version 4.2.6

Body:
$filter is the general purpose way to, well, filter arrays inside of docs.   Expanding your input set to give a little more context and variety:

var r =
[
 {
     "_id": 0,
     "other":6,
     "data" :[{"a":1,"b":2,"c":"X"},
              {"a":1,"b":3,"c":"Y"},
              {"a":2,"b":3,"c":"Q"},
              {"a":4,"b":1,"c":"Z"}]
 },
 {
     "_id": 1,
     "other":7,
     "data" :[{"a":1,"b":2,"c":"A"},
              {"a":1,"b":3,"c":"B"},
              {"a":7,"b":7,"c":"C"},
              {"a":1,"b":8,"c":"D"}]
 }
];
db.foo.insert(r);

Then these two pipelines demo the versatility of $filter:

c = db.foo.aggregate([
{$project: {_id:false,
            // Notice input is $data and output project is data; this
            // means overwrite the old data array with the filtered array.
            // Also:  The double dollar is how we reference the "as"
            // variable.  Single dollar variables refer to the fields
            // of the incoming doc; we show how to use $other in this
            // example.   $other remains constant for the doc as $filter
            // marches down the $data array:
            data: {$filter: {
                input: "$data",
                as: "z",
                cond: { $lt: [ {$add:["$$z.a","$$z.b"]} , "$other" ]}
            }}
    }}
                       ]);

c = db.foo.aggregate([
{$project: {_id:true,
            data: {$filter: {
                input: "$data",
                as: "z",
                cond: { $or: [ {$gt:["$$z.a",3]}, {$lt:["$$z.b",7]} ] }
            }}
    }}
                       ]);


问:
How to run an async task for every x mins in android?
how to run the async task at specific time? (I want to run it every 2 mins)

I tried using  post delayed but it's not working?

```<code>    tvData.postDelayed(new Runnable(){

    @Override
    public void run() {
        readWebpage();

    }}, 100);
</code>```

In the above code readwebpage is function which calls the async task for me..

Right now below is the method which I am using

```<code>   public void onCreate(Bundle savedInstanceState) {

         readwebapage();

   }

   public void readWebpage() {
    DownloadWebPageTask task = new DownloadWebPageTask();
    task.execute("http://www.google.com");

   }

   private class DownloadWebPageTask extends AsyncTask<String, Void, String> {
    @Override
    protected String doInBackground(String... urls) {
        String response1 = "";
        response1=read();
                   //read is my another function which does the real work
        response1=read();
        super.onPostExecute(response1);
        return response1;
    }

      protected void onPostExecute(String result) {

         try {
                Thread.sleep(100);
            } catch (InterruptedException e) {
                // TODO Auto-generated catch block
                e.printStackTrace();
            }

            TextView tvData = (TextView) findViewById(R.id.TextView01);
            tvData.setText(result);

        DownloadWebPageTask task = new DownloadWebPageTask();
        task.execute(new String[] { "http://www.google.com" });

    }

    }
</code>```

This is what I  my code is and it works perfectly fine but the big problem I drains my battery?

答: Try extending the Thread class, set a sleep time of 2000 millis and place your call into the run method. That should do it.

Body:
how to run the async task at specific time? (I want to run it every 2 mins)

I tried using  post delayed but it's not working?

    tvData.postDelayed(new Runnable(){

    @Override
    public void run() {
        readWebpage();

    }}, 100);

In the above code readwebpage is function which calls the async task for me..

Right now below is the method which I am using

   public void onCreate(Bundle savedInstanceState) {

         readwebapage();

   }

   public void readWebpage() {
    DownloadWebPageTask task = new DownloadWebPageTask();
    task.execute("http://www.google.com");

   }

   private class DownloadWebPageTask extends AsyncTask<String, Void, String> {
    @Override
    protected String doInBackground(String... urls) {
        String response1 = "";
        response1=read();
                   //read is my another function which does the real work
        response1=read();
        super.onPostExecute(response1);
        return response1;
    }

      protected void onPostExecute(String result) {

         try {
                Thread.sleep(100);
            } catch (InterruptedException e) {
                // TODO Auto-generated catch block
                e.printStackTrace();
            }

            TextView tvData = (TextView) findViewById(R.id.TextView01);
            tvData.setText(result);

        DownloadWebPageTask task = new DownloadWebPageTask();
        task.execute(new String[] { "http://www.google.com" });

    }

    }

This is what I  my code is and it works perfectly fine but the big problem I drains my battery?


问:
How to print a string representation of myFirstCar using the _str_method?
I'm doing this question in a python book and I just stumbled across this question. As shown in the title I wrote above, it's asking me to use that variable with the _str_method and also, I should get the output:
Make = Honda, Model = Civic, Color = White, Price = 1500
How should I write the code? (Please help)

答:
```<code>class myFirstCar:
    def __init__(self, make, model, color, price):
        self.make = make
        self.model = model
        self.color = color
        self.price = price

    def __str__():
        s = 'Make = ' + self.make + ', Model = ' + self.model + ', Color = ' + self.color + ', Price = ' + self.Price
        return s
</code>```

Instantiate your class and call the __str__ method.

Body:
class myFirstCar:
    def __init__(self, make, model, color, price):
        self.make = make
        self.model = model
        self.color = color
        self.price = price

    def __str__():
        s = 'Make = ' + self.make + ', Model = ' + self.model + ', Color = ' + self.color + ', Price = ' + self.Price
        return s

Instantiate your class and call the __str__ method.


问:
How to use Optional in Java?
I have a Service which queries for a list of coupons from the database. This service returns an Optional to the client.

```<code>return listOfCoupons.isEmpty() ? Optional.empty() : Optional.of(listOfCoupons.get(listOfCoupons.size() - 1));
</code>```

And the client of this code uses Optional named 'coupons' in the following way:

```<code>if (coupons.isPresent) {
   save (coupons.get());
}
</code>```

Is this the correct use of Optional ?

答:
Your use of the Optional<T> API looks fine from afar as I cannot see any misuse of it. if I were to nitpick and suggest something I would change:

```<code>if (coupons.isPresent) {
   save (coupons.get());
}
</code>```

to:

```<code>coupons.ifPresent(c -> save(c)); //or method reference
</code>```

but then again that's down to taste really.

Title: How to use Optional in Java?

Body:
I have a Service which queries for a list of coupons from the database. This service returns an Optional to the client.

return listOfCoupons.isEmpty() ? Optional.empty() : Optional.of(listOfCoupons.get(listOfCoupons.size() - 1));

And the client of this code uses Optional named 'coupons' in the following way:

if (coupons.isPresent) {
   save (coupons.get());
}

Is this the correct use of Optional ?

Body:
Your use of the Optional<T> API looks fine from afar as I cannot see any misuse of it. if I were to nitpick and suggest something I would change:

if (coupons.isPresent) {
   save (coupons.get());
}

to:

coupons.ifPresent(c -> save(c)); //or method reference

but then again that's down to taste really.


问:
SSRS How to see multi value parameter in subscription
I tried to get value from query or to specify values, as soon as the parameter is multi value i can't see the data when i'm trying to make my subscription.

my request looks like :

```<code>select id from employee where canal in(@canal)
</code>```

what should i do, i'm totally stuck,

when i did research i saw data driven subscription but i don't have access to it apparently, don't know if that help

答:
I'll start by saying sorry this isn't a pleasant answer. You've run into a limitation with the built-in functionality. Thankfully there are workarounds.

The problem is that you can only pass 1 value into the data-driven subscription. So you have use a comma-separated list and get the query/report to parse out the values.

If you have or can create a Split function in your database, that is a good option. This would be a table-valued user defined function and there are some easy to find examples already. Also this function is generally good to have for other use cases anyway. With this your SQL would read:

where canal in Split(@canal)

SSRS works really well with SQL Server, but when you use an ODBC connection, the parameter support is limited. You can use the same multi-value parameter workaround that is required in those cases.

In the Dataset properties > parameters tab, use an expression like this to combine the values into a single comma-separated string surrounded by commas.

="," + Join(Parameters!canal.Value, ",") + ","

The SQL would look like this:

where @ like '%,' + canal + ',%'

Basically, this searches row-by-row for values that are contained in the string.

In either case, the query in your data-driven subscription settings will need to return the comma-separated string. Then you can select that column in the report parameters value field. Hope this helps!

Body:
I tried to get value from query or to specify values, as soon as the parameter is multi value i can't see the data when i'm trying to make my subscription.

my request looks like :

select id from employee where canal in(@canal)

what should i do, i'm totally stuck,

when i did research i saw data driven subscription but i don't have access to it apparently, don't know if that help