问:
chart.js label with if statement
for traduction purposes, I am trying to set up my chart.js labels based on html tag text. Being a beginner to javascript, this a bit of a challenge.

Here is what I am trying to do:

html code:

{% trans 'ITEMS IN DIFFICULTY' %}

    <canvas id="myChart3" height="175"></canvas>

```

<p>and my chart.js code:</p>

<pre class="lang-js prettyprint-override"><code>var myChart3 = new Chart(ctx3, {
  type: 'bar',
  data: {
    labels: labels3,
    datasets: [{
      label: if (document.getElementById('tag4').value == 'ITEMS IN DIFFICULTY') {
        'low performing items (quantity sold/week)'
      }
      else {
        'references en difficulté (quantité vendu/semaine)'
      },
      data: defaultData3,
      backgroundColor: [
        'rgba(255, 99, 132, 0.2)',
      ],
      borderColor: [
        'rgba(255, 99, 132, 1)',
      ],
      borderWidth: 1
    }],
    options: {
      scales: {
        yAxes: [{
          gridLines: {
            drawOnChartArea: false,
            ticks: {
              beginAtZero: true
            }
          }
        }],
      }
    }
  }
})
</code>```

the result is that the graph does not show up. I am not sure if the issue is because there is something wrong with my if statement or if its not something that can be done with chart.js labels. Any help is more than welcomed!

答:
What you need is a ternary operator, it works like this:

let isTrue = true
let a = isTrue ? 1 : 0
```

<p>if <code>isTrue</code> is true, then <code>a</code> is 1, if false, <code>a</code> is 0</p>

<p>In your case, you can pass following as a label:</p>

<pre class="lang-js prettyprint-override"><code>document.getElementById('tag4').textContent == 'ITEMS IN DIFFICULTY' ? 'label if true' : 'label if false'
</code>```

Title: chart.js label with if statement

Body:
for traduction purposes, I am trying to set up my chart.js labels based on html tag text. Being a beginner to javascript, this a bit of a challenge.

Here is what I am trying to do:

html code:

{% trans 'ITEMS IN DIFFICULTY' %}

    <canvas id="myChart3" height="175"></canvas>

and my chart.js code:

var myChart3 = new Chart(ctx3, {
  type: 'bar',
  data: {
    labels: labels3,
    datasets: [{
      label: if (document.getElementById('tag4').value == 'ITEMS IN DIFFICULTY') {
        'low performing items (quantity sold/week)'
      }
      else {
        'references en difficulté (quantité vendu/semaine)'
      },
      data: defaultData3,
      backgroundColor: [
        'rgba(255, 99, 132, 0.2)',
      ],
      borderColor: [
        'rgba(255, 99, 132, 1)',
      ],
      borderWidth: 1
    }],
    options: {
      scales: {
        yAxes: [{
          gridLines: {
            drawOnChartArea: false,
            ticks: {
              beginAtZero: true
            }
          }
        }],
      }
    }
  }
})

the result is that the graph does not show up. I am not sure if the issue is because there is something wrong with my if statement or if its not something that can be done with chart.js labels. Any help is more than welcomed!

Body:
What you need is a ternary operator, it works like this:

let isTrue = true
let a = isTrue ? 1 : 0

if isTrue is true, then a is 1, if false, a is 0

In your case, you can pass following as a label:

document.getElementById('tag4').textContent == 'ITEMS IN DIFFICULTY' ? 'label if true' : 'label if false'


来源: stackexchange

问:
How do I update my prod database with dotnet ef database cli command?
How do I get EF to build all the tables for the prod db?

So far I've been building and pushing all my .Net Core database migrations to the dev db

ex.

>dotnet ef migrations add InitialModsN -c Auto2Context

>dotnet ef database update -c Auto2Context

In my Appsettings.Development.json file I have my con string pointing to dev db 'source=DEV'

```<code>"ConnectionStrings": {
"DefaultConnection": "Data Source=Auto2.db",
"Auto2": "data source=DEV; initial catalog=Auto2; user id=auto2; password=12345;" }
</code>```

And my Appsettings.json I have the prod db con string pointing to the prod db 'source=LIVE'

```<code>"ConnectionStrings": {
"DefaultConnection": "Data Source=Auto2.db",
"Auto2": "data source=LIVE; initial catalog=Auto2; user id=auto2; password=12345;" }
</code>```

So far everything is being built and migrated to dev, how do I change this to build all the changes up to date in the prod db?

Do I have to re create an initial migration file and then update?
If yes, how do I point it to the prod db?
I tried a couple of different commands with no luck.
Here is what I tried.

>dotnet ef database update -c Auto2Context --connection "data source=LIVE; initial catalog=Auto2; user id=auto2; password=12345"

-received 'Unrecognized option '--connection''

>dotnet ef database update -c Auto2Context --configuration Release

no tables created in the prod db

答:
Set ASPNETCORE_ENVIRONMENT environment variable before executing the command:

$env:ASPNETCORE_ENVIRONMENT='Production'

ContentLicense: CC BY-SA 4.0

Body:
How do I get EF to build all the tables for the prod db?

So far I've been building and pushing all my .Net Core database migrations to the dev db

ex.

>dotnet ef migrations add InitialModsN -c Auto2Context

>dotnet ef database update -c Auto2Context

In my Appsettings.Development.json file I have my con string pointing to dev db 'source=DEV'

"ConnectionStrings": {
"DefaultConnection": "Data Source=Auto2.db",
"Auto2": "data source=DEV; initial catalog=Auto2; user id=auto2; password=12345;" }

And my Appsettings.json I have the prod db con string pointing to the prod db 'source=LIVE'

"ConnectionStrings": {
"DefaultConnection": "Data Source=Auto2.db",
"Auto2": "data source=LIVE; initial catalog=Auto2; user id=auto2; password=12345;" }

So far everything is being built and migrated to dev, how do I change this to build all the changes up to date in the prod db?

Do I have to re create an initial migration file and then update?
If yes, how do I point it to the prod db?
I tried a couple of different commands with no luck.
Here is what I tried.

>dotnet ef database update -c Auto2Context --connection "data source=LIVE; initial catalog=Auto2; user id=auto2; password=12345"

-received 'Unrecognized option '--connection''

>dotnet ef database update -c Auto2Context --configuration Release

no tables created in the prod db


问:
Printing to console when implementing a single Flutter page in iOS app?
What I am trying to do:
I am working on an app that is currently written in native iOS and Android (Swift and Kotlin). We are wanting to gradually migrate these two apps into one code base via replacing individual native app pages with Flutter pages until we have a full Flutter app. When building the current, mostly Swift project on Xcode, the iOS app is using FlutterEngines to present individual Flutter pages and the Dart and Swift files are communicating via MethodChannels.

I am wanting to print to the console from within the Dart file of the individual Flutter page that is displayed in my iOS app.

What I've tried:
I've tried printing to the console by making use of the print() and log() methods in my Dart files. I've also tried running flutter attach from the terminal while running the iOS project in question and am successfully attaching to the app (I'm able to hot restart/reload), but my Dart files are still not printing to the console. What methods have you all used to print to the console from Dart files being accessed in an iOS project via FlutterEngine?

答:
I have always used Print() to print to the console.

Maybe there is some issues with the data to be printed.
Just an opinion, I may be wrong.


问:
Pass ENV to Docker container running single command
This prints blank:

```<code>docker run --rm --env HELLO="world" ubuntu:18.04 bash -c "echo $HELLO"
</code>```

However this works:

```<code>docker run --rm -it --env HELLO="world" ubuntu:18.04 bash
# in the container
echo $HELLO
</code>```

HELLO seems passed to the container though:

```<code>docker run --rm --env HELLO="world" ubuntu:18.04 env
</code>```

Why is the first command not seeing HELLO? What am I missing?

答:
Because of the double quotes, $HELLO will be evaluated by the docker host itself once the command got executed before going inside the container. So you need to either escape the dollar sign ($) using Backslash (\) which tells the bash that the $ is a part of the command itself and no need to be evaluated by the current shell (which is the docker host in our case) or use single quotes ('') like this:

Using single quotes

$ docker run --rm --env HELLO="world" ubuntu:18.04 bash -c 'echo $HELLO'
world
```

<p><strong>Using Backslash to escape</strong></p>

<pre class="lang-sh prettyprint-override"><code>$ docker run --rm --env HELLO="world" ubuntu:18.04 bash -c "echo \$HELLO"
world
</code>```

Body:
This prints blank:

docker run --rm --env HELLO="world" ubuntu:18.04 bash -c "echo $HELLO"

However this works:

docker run --rm -it --env HELLO="world" ubuntu:18.04 bash
# in the container
echo $HELLO

HELLO seems passed to the container though:

docker run --rm --env HELLO="world" ubuntu:18.04 env

Why is the first command not seeing HELLO? What am I missing?

Body:
Because of the double quotes, $HELLO will be evaluated by the docker host itself once the command got executed before going inside the container. So you need to either escape the dollar sign ($) using Backslash (\) which tells the bash that the $ is a part of the command itself and no need to be evaluated by the current shell (which is the docker host in our case) or use single quotes ('') like this:

Using single quotes

$ docker run --rm --env HELLO="world" ubuntu:18.04 bash -c 'echo $HELLO'
world

Using Backslash to escape

$ docker run --rm --env HELLO="world" ubuntu:18.04 bash -c "echo \$HELLO"
world


问:
R: How do I match a column paired with a letter with another column paired with an empty column to fill in the empty column
I'm working in a dataframe that looks like

```<code>Word.  letter   Word2.  letter2

happy.  p.      SAD
sad.    n.      POTATO
potato  o.      HAPPY
</code>```

I want it to look like this

```<code>Word.  letter   Word2.  letter2

happy.  p.      SAD.     n
sad.    n.      POTATO.  o
potato  o.      HAPPY.   p
</code>```

Basically I want to make it so that I can identify "word" in "word2" and copy the "letter" and place it accordingly in "letter2". I need to make sure it matches regardless if case.

I have tried to use the match function in a variety of different manners but I am either making stupid syntax errors, it isn't matching case, or both. Any suggestions are much appreciated.

Data Visualization

```<code>df1 <- structure(list(Word = c("happy", "sad", "potato"), letter = c("p",
"n", "o"), Word2 = c("SAD", "POTATO", "HAPPY"), letter2 = c("n", "o", "p")),
    class = "data.frame", row.names = c(NA, -3L))
</code>```

One of my attempts:

```<code>df1<-(mydataframe)
df1$letter2<-with(df1, letter2[match(letter, letter2)])
</code>```

答:
We can convert to upper case and do a match</p>

```<code>df1$letter2 <- with(df1, letter[match(Word2, toupper(Word))])
df1$letter2
#[1] "n" "o" "p"
</code>```

Body:
I'm working in a dataframe that looks like

Word.  letter   Word2.  letter2

happy.  p.      SAD
sad.    n.      POTATO
potato  o.      HAPPY

I want it to look like this

Word.  letter   Word2.  letter2

happy.  p.      SAD.     n
sad.    n.      POTATO.  o
potato  o.      HAPPY.   p

Basically I want to make it so that I can identify "word" in "word2" and copy the "letter" and place it accordingly in "letter2". I need to make sure it matches regardless if case.

I have tried to use the match function in a variety of different manners but I am either making stupid syntax errors, it isn't matching case, or both. Any suggestions are much appreciated.

Data Visualization

df1 <- structure(list(Word = c("happy", "sad", "potato"), letter = c("p",
"n", "o"), Word2 = c("SAD", "POTATO", "HAPPY"), letter2 = c("n", "o", "p")),
    class = "data.frame", row.names = c(NA, -3L))

One of my attempts:

df1<-(mydataframe)
df1$letter2<-with(df1, letter2[match(letter, letter2)])

Body:
We can convert to upper case and do a match

df1$letter2 <- with(df1, letter[match(Word2, toupper(Word))])
df1$letter2
#[1] "n" "o" "p"


问:
List of imperceptible characters to use in a Java code to prevent it from been copied, pasted and compiled
it's an unusual question: I want to know a list of character that I could substitute on a Java code to prevent it from being copied, pasted and compiled.

Explanation: I'm teaching a course on Java and have to apply an online exam using Microsoft Forms. One of the question that I like to use is "Be The Compiler" (inspired in the Head First books), in which the student have to run the code in his head and write down the output. The problem is that, because of the Covid-19, it's been online from home, the student could just copy and paste the code and run it.

PS: Microsoft Form only accept one small image for each question. And accept nor HTML tag, nor LaTex tag, nor markdown tag.

PS: The idea is inspired by JavaScript Prank / Joke

答:
Thanks to that list (given by pafau) I was able to find some symbols:

202F ;   0020 ; (   →   ) NARROW NO-BREAK SPACE → SPACE

201A ;   002C ; ( ‚ → , ) SINGLE LOW-9 QUOTATION MARK → COMMA

037E ;   003B ; ( ; → ; ) GREEK QUESTION MARK → SEMICOLON

1400 ;   003D ; ( ᐀ → = ) CANADIAN SYLLABICS HYPHEN → EQUALS SIGN

The following code in python put the number of the line and replace those symbols:

```<code># -*- coding: utf-8 -*-

import sys

text_numbered = ''

with open(sys.argv[1], 'r') as my_file:
    for counter, line in enumerate(my_file, 1):
        text_numbered += '{:3d}'.format(counter) + ' - ' + str(line)

text = text_numbered
# 202F; 0020; (   →   ) NARROW NO-BREAK SPACE → SPACE
text = text.replace(' ', ' ')
# 201A; 002C; ( ‚ → , ) SINGLE LOW-9 QUOTATION MARK → COMMA
text = text.replace(',', '‚')
# 037E; 003B; ( ; → ; ) GREEK QUESTION MARK → SEMICOLON
text = text.replace(';', ';')
# 1400; 003D; ( ᐀ → = ) CANADIAN SYLLABICS HYPHEN → EQUALS SIGN
text = text.replace('=', '᐀')
print(text)

</code>```

Unfortunately I was not able to find a sequence of letters that is identical to "LATIN SMALL LETTER" or "LATIN CAPITAL LETTER"

Body:
Thanks to that list (given by pafau) I was able to find some symbols:

202F ;   0020 ; (   →   ) NARROW NO-BREAK SPACE → SPACE

201A ;   002C ; ( ‚ → , ) SINGLE LOW-9 QUOTATION MARK → COMMA

037E ;   003B ; ( ; → ; ) GREEK QUESTION MARK → SEMICOLON

1400 ;   003D ; ( ᐀ → = ) CANADIAN SYLLABICS HYPHEN → EQUALS SIGN

The following code in python put the number of the line and replace those symbols:

# -*- coding: utf-8 -*-

import sys

text_numbered = ''

with open(sys.argv[1], 'r') as my_file:
    for counter, line in enumerate(my_file, 1):
        text_numbered += '{:3d}'.format(counter) + ' - ' + str(line)

text = text_numbered
# 202F; 0020; (   →   ) NARROW NO-BREAK SPACE → SPACE
text = text.replace(' ', ' ')
# 201A; 002C; ( ‚ → , ) SINGLE LOW-9 QUOTATION MARK → COMMA
text = text.replace(',', '‚')
# 037E; 003B; ( ; → ; ) GREEK QUESTION MARK → SEMICOLON
text = text.replace(';', ';')
# 1400; 003D; ( ᐀ → = ) CANADIAN SYLLABICS HYPHEN → EQUALS SIGN
text = text.replace('=', '᐀')
print(text)

Unfortunately I was not able to find a sequence of letters that is identical to "LATIN SMALL LETTER" or "LATIN CAPITAL LETTER"


问:
Can my WebDriver script catch a event from the webpage?
I would like my WebDriver script to execute some test after the webpage fires specific event. Is this possible?

In the WebDriver script there would be some kind of event listener:

```<code>document.addEventListener("hello", function(){
    console.log("doing tests");
});
</code>```

That would run when the webpage would executes:

```<code>var ev = new Event("hello");
document.dispatchEvent(ev);
</code>```

Is this possible the other way around, so I could fire an event from WebDriver to the webpage?

答:
I know this an old question but I just want to add some information here, maybe it was not there when this question was asked. As mentioned in question and comments that it is for Javascript implementation of webdriver , which is webdriverjs

You should be able to use addEventListener command to add any browser supported events

Note, this is only supported in chrome currently

Also, this is an experimental feature in webdriver.js so  one has to add

```<code>var client = WebdriverJS.remote({
    logLevel: 'verbose',
    experimental: true, // <-- enables browser side eventhandling
    desiredCapabilities: {
        browserName: 'chrome'
    }
});
</code>```

And then register events like

```<code>client
    .url('http://google.com')
    .addEventListener('dblclick','#hplogo', function(e) {
        console.log(e.target); // -> 'id("hplogo")'
        console.log(e.type); // -> 'dblclick'
        console.log(e.clientX, e.clientY); // -> 239 524
    })
    .doubleClick('#hplogo') // triggers event
    .end();
</code>```

You can use removeEventListener to unregister any registered listeners

Evenhandling in Node.js environment is also supported as implied by this

WebdriverJS inherits several function from the NodeJS EventEmitter object

ContentLicense: CC BY-SA 3.0

Body:
I would like my WebDriver script to execute some test after the webpage fires specific event. Is this possible?

In the WebDriver script there would be some kind of event listener:

document.addEventListener("hello", function(){
    console.log("doing tests");
});

That would run when the webpage would executes:

var ev = new Event("hello");
document.dispatchEvent(ev);

Is this possible the other way around, so I could fire an event from WebDriver to the webpage?

Body:
I know this an old question but I just want to add some information here, maybe it was not there when this question was asked. As mentioned in question and comments that it is for Javascript implementation of webdriver , which is webdriverjs

You should be able to use addEventListener command to add any browser supported events

Note, this is only supported in chrome currently

Also, this is an experimental feature in webdriver.js so  one has to add

var client = WebdriverJS.remote({
    logLevel: 'verbose',
    experimental: true, // <-- enables browser side eventhandling
    desiredCapabilities: {
        browserName: 'chrome'
    }
});

And then register events like

client
    .url('http://google.com')
    .addEventListener('dblclick','#hplogo', function(e) {
        console.log(e.target); // -> 'id("hplogo")'
        console.log(e.type); // -> 'dblclick'
        console.log(e.clientX, e.clientY); // -> 239 524
    })
    .doubleClick('#hplogo') // triggers event
    .end();

You can use removeEventListener to unregister any registered listeners

Evenhandling in Node.js environment is also supported as implied by this

WebdriverJS inherits several function from the NodeJS EventEmitter object


问:
Shouldn't this fail without the use of locking? Simple producer consumer
I have a queue, a list with producer threads and a list with consumer threads.

My code looks like this

```<code>    public class Runner
{
    List<Thread> Producers;
    List<Thread> Consumers;
    Queue<int> queue;
    Random random;

    public Runner()
    {
        Producers = new List<Thread>();
        Consumers = new List<Thread>();

        for (int i = 0; i < 2; i++)
        {
            Thread thread = new Thread(Produce);
            Producers.Add(thread);
        }

        for (int i = 0; i < 2; i++)
        {
            Thread thread = new Thread(Consume);
            Consumers.Add(thread);
        }

        queue = new Queue<int>();
        random = new Random();

        Producers.ForEach(( thread ) => { thread.Start(); });
        Consumers.ForEach(( thread ) => { thread.Start(); });
    }

    protected void Produce()
    {
        while (true)
        {
                int number = random.Next(0, 99);
                queue.Enqueue(number);
                Console.WriteLine(Thread.CurrentThread.ManagedThreadId + " Produce: " + number);
        }
    }

    protected void Consume()
    {
        while (true)
        {
                if (queue.Any())
                {
                    int number = queue.Dequeue();
                    Console.WriteLine(Thread.CurrentThread.ManagedThreadId + " Consume: " + number);
                }
                else
                {
                    Console.WriteLine("No items to consume");
                }
        }
    }
}
</code>```

Shouldn't this fail miserable cause of the missing use of the lock keyword?
It failed once because it tried to dequeue when the queue was empty, using the lock keyword will fix that right?

If the lock keyword is not needed for the above code, when is it needed then?

Thank you in advance! =)

答:
To clarify the existing answers, if you have a multithreading problem (such as a race condition) then it isn't guaranteed to always fail - it may fail, in a very unpredictable manner.

The reason is that two (or more) threads that are accessing a resource may try to access it at different times - precisely when each of them tries to access it will depend on many factors (how fast your CPU is, how many processor cores it has available, what other programs are running at the time, whether you are running a release or debug build, or running under a debugger, etc). You could run it many times without the failure showing up, and then have it suddenly and "inexplicably" fail - this can make these errors extremely hard to track down because they don't often show up while you're writing the faulty code, but more often when you are writing a different unrelated piece of code.

If you are going to use multithreading it is vital that you read up on the subject and gain an understanding of what can go wrong, when, and how to handle it properly - bad use of locking can be just as dangerous (if not more so) than not using locks at all (locking can cause deadlocks where your program simply "locks up"). This are aof programming must be approached carefully!

Body:
I have a queue, a list with producer threads and a list with consumer threads.

My code looks like this

    public class Runner
{
    List<Thread> Producers;
    List<Thread> Consumers;
    Queue<int> queue;
    Random random;

    public Runner()
    {
        Producers = new List<Thread>();
        Consumers = new List<Thread>();

        for (int i = 0; i < 2; i++)
        {
            Thread thread = new Thread(Produce);
            Producers.Add(thread);
        }

        for (int i = 0; i < 2; i++)
        {
            Thread thread = new Thread(Consume);
            Consumers.Add(thread);
        }

        queue = new Queue<int>();
        random = new Random();

        Producers.ForEach(( thread ) => { thread.Start(); });
        Consumers.ForEach(( thread ) => { thread.Start(); });
    }

    protected void Produce()
    {
        while (true)
        {
                int number = random.Next(0, 99);
                queue.Enqueue(number);
                Console.WriteLine(Thread.CurrentThread.ManagedThreadId + " Produce: " + number);
        }
    }

    protected void Consume()
    {
        while (true)
        {
                if (queue.Any())
                {
                    int number = queue.Dequeue();
                    Console.WriteLine(Thread.CurrentThread.ManagedThreadId + " Consume: " + number);
                }
                else
                {
                    Console.WriteLine("No items to consume");
                }
        }
    }
}

Shouldn't this fail miserable cause of the missing use of the lock keyword?
It failed once because it tried to dequeue when the queue was empty, using the lock keyword will fix that right?

If the lock keyword is not needed for the above code, when is it needed then?

Thank you in advance! =)


问:
index.js:1 Warning: Encountered two children with the same key, `index`. Index is unique
I am trying to assign index to key of dynamic list component but it gives warning of duplicate keys. Here is the code below

```<code>function App() {
  const [userInput, setUserInput] = useState('');

  let calcLengthHandler = (event)=>{
    setUserInput(event.target.value);
  }

  let charArr = [...userInput.split('')];
  let charCmp = ( <div>
        {
          charArr.map((character,index)=>{
            return (
              <CharComponent onClick={deleteCharCmp} char={character} key='index'></CharComponent>
            )
          })
        }
    </div>)

  return (
    <div className="App">
      <div className='container'>
        <h1 className='container-output'>Dynamic List</h1>
        <input type='text' className='user-input' onChange={calcLengthHandler} value={userInput} placeholder='Enter user input'></input>
        <p className='container-output inline'>Length of user input: {userInput.length}</p>
        <ValidationComponent length={userInput.length}></ValidationComponent>
        {charCmp}
      </div>
    </div>
  );
}
</code>```

Every time a user enters some string, I am trying to create a component with each character. I have further functionality to achieve which I have not included.
On adding debugger just before .map function, I see its called twice which may be causing the issue. I guess 1. when the component is initialized and 2. when I call {charCmp}. How can I resolve duplicate keys problem here?

答:
This sets the key attribute to the string 'index':

```<code>key='index'
</code>```

This sets the key attribute to the value of the index variable:

```<code>key={index}
</code>```

Body:
I am trying to assign index to key of dynamic list component but it gives warning of duplicate keys. Here is the code below

function App() {
  const [userInput, setUserInput] = useState('');

  let calcLengthHandler = (event)=>{
    setUserInput(event.target.value);
  }

  let charArr = [...userInput.split('')];
  let charCmp = (

        {
          charArr.map((character,index)=>{
            return (
              <CharComponent onClick={deleteCharCmp} char={character} key='index'></CharComponent>
            )
          })
        }

)

  return (

Dynamic List

        <input type='text' className='user-input' onChange={calcLengthHandler} value={userInput} placeholder='Enter user input'></input>

Length of user input: {userInput.length}

        <ValidationComponent length={userInput.length}></ValidationComponent>
        {charCmp}

  );
}

Every time a user enters some string, I am trying to create a component with each character. I have further functionality to achieve which I have not included.
On adding debugger just before .map function, I see its called twice which may be causing the issue. I guess 1. when the component is initialized and 2. when I call {charCmp}. How can I resolve duplicate keys problem here?

Body:
This sets the key attribute to the string 'index':

key='index'

This sets the key attribute to the value of the index variable:

key={index}


问:
Electrum transaction using terminal
Hi i would like to send transactions to desired addresses. Since i launch my electrum wallet with ./electrum-3.3.8-x64 command and following the man page i came up with something like this:

```<code>./electrum-3.3.8-x86_64.AppImage -w /home/.electrum/wallets/wallet_with_segwit payto address amount
</code>```

But the following command returns:

```<code>Type 'electrum create' to create a new wallet, or provide a path to a wallet with the -w option
</code>```

Is it possible what i want to reach? And how do you specify the amount to pay(BTC,USD)?

Edit1:

as in man page you can only pay in BTC:

```<code>amount              Amount to be sent (in BTC). Type '!' to send the
                    maximum available.
</code>```

and after further checking i found:

```<code> ./electrum-3.3.8-x86_64.AppImage payto -w /home/.electrum/wallets/wallet_with_segwit -W passwd address amount
</code>```

but still i got same error...

答:
In terminal you need to start Electrum daemon at first, then load a wallet, then make your transaction:</p>

```<code>./electrum-3.3.8-x86_64.AppImage daemon start
./electrum-3.3.8-x86_64.AppImage load_wallet -w /home/.electrum/wallets/wallet_with_segwit
./electrum-3.3.8-x86_64.AppImage payto <address> <btc_amount>
</code>```

Title: Electrum transaction using terminal

Body:
Hi i would like to send transactions to desired addresses. Since i launch my electrum wallet with ./electrum-3.3.8-x64 command and following the man page i came up with something like this:

./electrum-3.3.8-x86_64.AppImage -w /home/.electrum/wallets/wallet_with_segwit payto address amount

But the following command returns:

Type 'electrum create' to create a new wallet, or provide a path to a wallet with the -w option

Is it possible what i want to reach? And how do you specify the amount to pay(BTC,USD)?

Edit1:

as in man page you can only pay in BTC:

amount              Amount to be sent (in BTC). Type '!' to send the
                    maximum available.

and after further checking i found:

 ./electrum-3.3.8-x86_64.AppImage payto -w /home/.electrum/wallets/wallet_with_segwit -W passwd address amount

but still i got same error...

Body:
In terminal you need to start Electrum daemon at first, then load a wallet, then make your transaction:

./electrum-3.3.8-x86_64.AppImage daemon start
./electrum-3.3.8-x86_64.AppImage load_wallet -w /home/.electrum/wallets/wallet_with_segwit
./electrum-3.3.8-x86_64.AppImage payto <address> <btc_amount>


问:
Split a table into multiple smaller tables based on a column's value-Power Query
I have a table like this that I got using "combine & edit" option in power query that has information from multiple sheets from multiple .xlsx files. Sheetnames never change and they'll stay the same, excel files can change.

Now, I want many tables splitting by column1's value firstkey. So, I can get multiple tables like this,

I have been Googling to find an answer, still no success. There are threads like this, that requires you to duplicate the original table and filter each value.

However, in my case, I want to automate in a way if I have new .xlsx files. So, if I get a value Brooklyn Park instead of Bursville, it should be filtered based on Column1's value.

How can I do this Power Query?

EDIT

As requested, original excel sheet for one file,

M code:

let
    Source = Excel_Export,
    #"Trimmed Text" = Table.TransformColumns(Source,{{"Column1", Text.Trim, type text}}),
    #"Cleaned Text" = Table.TransformColumns(#"Trimmed Text",{{"Column1", Text.Clean, type text}}),
    #"Filtered Rows" = Table.SelectRows(#"Cleaned Text", each ([Source.Name] = "Burnsville.xlsx")),
    #"Transposed Table" = Table.Transpose(#"Filtered Rows"),
    #"Removed Top Rows" = Table.Skip(#"Transposed Table",1),
    #"Promoted Headers" = Table.PromoteHeaders(#"Removed Top Rows", [PromoteAllScalars=true]),
    #"Renamed Columns" = Table.RenameColumns(#"Promoted Headers",{{"Address", "Address Number"}, {"Column3", "StreetName"}, {"Column4", "City"}})
in
    #"Renamed Columns"
```

I used this code to create a function to automate for each file.

答:
Seemed like a fun challenge. Here's a standalone example, I tried to make it succinct:</p>
```<code>let
    SourceTable = Table.FromRecords({
        [Cities = "City1", Info = "Info1"],[Cities = "City1", Info = "Info2"],
        [Cities = "City1", Info = "Info3"],[Cities = "City2", Info = "Info1"],
        [Cities = "City2", Info = "Info2"],[Cities = "City3", Info = "Info1"],
        [Cities = "City3", Info = "Info2"],[Cities = "City3", Info = "Info3"],
        [Cities = "City3", Info = "Info4"],[Cities = "City3", Info = "Info5"]
    }),

    SortedTable = Table.Sort(SourceTable,{{"Cities", Order.Ascending},{"Info", Order.Ascending}}),

    DistinctCities = List.Distinct(SortedTable[Cities]),

    DistinctCitiesAfterFirst = if List.Count(DistinctCities) > 1 then List.RemoveRange(DistinctCities,0) else {},

    CityOffsets = List.Transform(DistinctCitiesAfterFirst, each (List.PositionOf(SortedTable[Cities],_) + List.PositionOf(DistinctCitiesAfterFirst,_) - 1)),

    SortedTableWithBlankRows = List.Accumulate(
        CityOffsets,
        SortedTable,
        ((tableState, currentOffset) =>
            Table.InsertRows(
                tableState,
                currentOffset,
                {
                    Record.FromList(List.Repeat({""},Table.ColumnCount(SortedTable)),Table.ColumnNames(SortedTable))
                }
            )
        )
    )

in
    SortedTableWithBlankRows
</code>```

Body:
I have a table like this that I got using "combine & edit" option in power query that has information from multiple sheets from multiple .xlsx files. Sheetnames never change and they'll stay the same, excel files can change.

Now, I want many tables splitting by column1's value firstkey. So, I can get multiple tables like this,

I have been Googling to find an answer, still no success. There are threads like this, that requires you to duplicate the original table and filter each value.

However, in my case, I want to automate in a way if I have new .xlsx files. So, if I get a value Brooklyn Park instead of Bursville, it should be filtered based on Column1's value.

How can I do this Power Query?

EDIT

As requested, original excel sheet for one file,

M code:

let
    Source = Excel_Export,
    #"Trimmed Text" = Table.TransformColumns(Source,{{"Column1", Text.Trim, type text}}),
    #"Cleaned Text" = Table.TransformColumns(#"Trimmed Text",{{"Column1", Text.Clean, type text}}),
    #"Filtered Rows" = Table.SelectRows(#"Cleaned Text", each ([Source.Name] = "Burnsville.xlsx")),
    #"Transposed Table" = Table.Transpose(#"Filtered Rows"),
    #"Removed Top Rows" = Table.Skip(#"Transposed Table",1),
    #"Promoted Headers" = Table.PromoteHeaders(#"Removed Top Rows", [PromoteAllScalars=true]),
    #"Renamed Columns" = Table.RenameColumns(#"Promoted Headers",{{"Address", "Address Number"}, {"Column3", "StreetName"}, {"Column4", "City"}})
in
    #"Renamed Columns"

I used this code to create a function to automate for each file.

Body:
Seemed like a fun challenge. Here's a standalone example, I tried to make it succinct:

let
    SourceTable = Table.FromRecords({
        [Cities = "City1", Info = "Info1"],[Cities = "City1", Info = "Info2"],
        [Cities = "City1", Info = "Info3"],[Cities = "City2", Info = "Info1"],
        [Cities = "City2", Info = "Info2"],[Cities = "City3", Info = "Info1"],
        [Cities = "City3", Info = "Info2"],[Cities = "City3", Info = "Info3"],
        [Cities = "City3", Info = "Info4"],[Cities = "City3", Info = "Info5"]
    }),

    SortedTable = Table.Sort(SourceTable,{{"Cities", Order.Ascending},{"Info", Order.Ascending}}),

    DistinctCities = List.Distinct(SortedTable[Cities]),

    DistinctCitiesAfterFirst = if List.Count(DistinctCities) > 1 then List.RemoveRange(DistinctCities,0) else {},

    CityOffsets = List.Transform(DistinctCitiesAfterFirst, each (List.PositionOf(SortedTable[Cities],_) + List.PositionOf(DistinctCitiesAfterFirst,_) - 1)),

    SortedTableWithBlankRows = List.Accumulate(
        CityOffsets,
        SortedTable,
        ((tableState, currentOffset) =>
            Table.InsertRows(
                tableState,
                currentOffset,
                {
                    Record.FromList(List.Repeat({""},Table.ColumnCount(SortedTable)),Table.ColumnNames(SortedTable))
                }
            )
        )
    )

in
    SortedTableWithBlankRows


问:
Click on spam with Python Selenium
I want to click on the checkbox from the Google ReCAPTCHA-test. For that (I think) I have to click on the following span:

```<code><span class="recaptcha-checkbox goog-inline-block recaptcha-checkbox-unchecked rc-anchor-checkbox" role="checkbox" aria-checked="false" id="recaptcha-anchor" tabindex="0" dir="ltr" aria-labelledby="recaptcha-anchor-label"><div class="recaptcha-checkbox-border" role="presentation"></div><div class="recaptcha-checkbox-borderAnimation" role="presentation"></div><div class="recaptcha-checkbox-spinner" role="presentation"><div class="recaptcha-checkbox-spinner-overlay"></div></div><div class="recaptcha-checkbox-checkmark" role="presentation"></div></span>
</code>```

https://patrickhlauke.github.io/recaptcha/ Here the website is (it's just an empty website with an ReCAPTCHA in it).

I am using the latest version of the Chrome driver and it's defined as driver. I tried:

```<code>driver.find_element_by_tag_name("span").click()

driver.find_element_by_xpath('//*[@id="recaptcha-anchor"]').click()

driver.find_element_by_id('recaptcha-anchor').click()

driver.find_element_by_class_name('recaptcha-checkbox goog-inline-block recaptcha-checkbox-unchecked rc-anchor-checkbox').click()
</code>```

but i'm always getting following error:

```<code>selenium.common.exceptions.NoSuchElementException: Message: no such element: Unable to locate element: {*this is every try different*}
  (Session info: chrome=83.0.4103.61)
</code>```

I'm very new at Python and it's my first try with Selenium.

答:
The checkbox is in an iframe so you need to use selenium to switch to that first. Below should help you click the check box, and also allow you to get to the 9 boxes.

First ensure you have the following imports

```<code>from selenium.webdriver.common.by import By
from selenium.webdriver.support.ui import WebDriverWait
from selenium.webdriver.support import expected_conditions as EC
</code>```

Next:

```<code># Switch to iframe to click the checkbox
WebDriverWait(driver, 5).until(EC.frame_to_be_available_and_switch_to_it((By.CSS_SELECTOR, ".g-recaptcha>div>div>iframe")))

#click the checkbox
driver.find_element_by_id('recaptcha-anchor').click()

#switch back to the main content in order to switch to the next iframe we need
driver.switch_to.default_content()

#switch to the iframe that contains the 9 boxes
WebDriverWait(driver, 5).until(EC.frame_to_be_available_and_switch_to_it((By.CSS_SELECTOR, "iframe[title='recaptcha challenge']")))

#get the 9 boxes
boxes = driver.find_elements_by_css_selector('#rc-imageselect-target button')
</code>```

Title: Click on spam with Python Selenium

Body:
I want to click on the checkbox from the Google ReCAPTCHA-test. For that (I think) I have to click on the following span:

https://patrickhlauke.github.io/recaptcha/ Here the website is (it's just an empty website with an ReCAPTCHA in it).

I am using the latest version of the Chrome driver and it's defined as driver. I tried:

driver.find_element_by_tag_name("span").click()

driver.find_element_by_xpath('//*[@id="recaptcha-anchor"]').click()

driver.find_element_by_id('recaptcha-anchor').click()

driver.find_element_by_class_name('recaptcha-checkbox goog-inline-block recaptcha-checkbox-unchecked rc-anchor-checkbox').click()

but i'm always getting following error:

selenium.common.exceptions.NoSuchElementException: Message: no such element: Unable to locate element: {*this is every try different*}
  (Session info: chrome=83.0.4103.61)

I'm very new at Python and it's my first try with Selenium.

Body:
The checkbox is in an iframe so you need to use selenium to switch to that first. Below should help you click the check box, and also allow you to get to the 9 boxes.

First ensure you have the following imports

from selenium.webdriver.common.by import By
from selenium.webdriver.support.ui import WebDriverWait
from selenium.webdriver.support import expected_conditions as EC

Next:

# Switch to iframe to click the checkbox
WebDriverWait(driver, 5).until(EC.frame_to_be_available_and_switch_to_it((By.CSS_SELECTOR, ".g-recaptcha>div>div>iframe")))

#click the checkbox
driver.find_element_by_id('recaptcha-anchor').click()

#switch back to the main content in order to switch to the next iframe we need
driver.switch_to.default_content()

#switch to the iframe that contains the 9 boxes
WebDriverWait(driver, 5).until(EC.frame_to_be_available_and_switch_to_it((By.CSS_SELECTOR, "iframe[title='recaptcha challenge']")))

#get the 9 boxes
boxes = driver.find_elements_by_css_selector('#rc-imageselect-target button')


答:
Maybe this solution is not the efficent one but it is short. The idea is to iterate each list backward and put it in dict so if some keys are the same it leaves only the last ones.</p>

```<code>target = {k: list(dict(v[::-1]).items())[::-1] for k, v in d.items()}
</code>```

Title: How to delete same elements in different tuples

Body:
I have a dictionary like this and want to remove elements if the first item has already occurred in the tuple.

Original dictionary:

{85: [(88, 1), (89, 2), (89, 3), (89, 4)],
86: [(77, 1)],
112: [(35, 1), (36, 2)],
114: [(55, 1), (55, 2), (55, 3), (55, 4), (55, 5), (55, 6), (55, 7), (55, 8), (55, 9), (55, 10), (55, 11), (55, 12), (55, 13), (55, 14), (55, 15), (55, 16), (55, 17), (55, 18), (55, 19), (55, 20)],
122: [(72, 1), (72, 2), (72, 3), (72, 4), (72, 5), (72, 6), (72, 7), (72, 8)]}

Target:

{85: [(88, 1), (89, 2)],
86: [(77, 1)],
112: [(35, 1), (36, 2)],
114: [(55, 1)],
122: [(72, 1)]}

Body:
Maybe this solution is not the efficent one but it is short. The idea is to iterate each list backward and put it in dict so if some keys are the same it leaves only the last ones.

target = {k: list(dict(v[::-1]).items())[::-1] for k, v in d.items()}


问:
How to import modules from a folder and add them into a Python list?
I imported modules from plugins folder using importlib module:

```<code>plugin_files = os.listdir("plugins")
for plugin_file in plugin_files:
   importlib.import_module(plugin_file)
</code>```

How can I add those modules into a list plugins = list() so when I loop through them I can call their function that they share in common(interface)? For example:

```<code>for plugin in plugins:
   plugin.send_notification()
</code>```

I tried to look into documentation of importlib module, however, I see nothing about grouping and listing modules.

答:
I believe these should work.

plugin_files = os.listdir("plugins")
plugins = []
for plugin_file in plugin_files:
    plugins.append(importlib.import_module(plugin_file))

for plugin in plugins:
    plugin.send_notification()
```

<p>OR</p>

<pre class="lang-py prettyprint-override"><code>plugins = list(map(importlib.import_module,os.listdir("plugins")))
for plugin in plugins:
    plugin.send_notification()
</code>```

Quick test below:

class test:
    def __init__(self,name):
        self.name = name

plugins = list(map(test,['bob','jim']))

for plugin in plugins:
    print(plugin.name)
```

```bob
jim
```

Body:
I imported modules from plugins folder using importlib module:

plugin_files = os.listdir("plugins")
for plugin_file in plugin_files:
   importlib.import_module(plugin_file)

How can I add those modules into a list plugins = list() so when I loop through them I can call their function that they share in common(interface)? For example:

for plugin in plugins:
   plugin.send_notification()

I tried to look into documentation of importlib module, however, I see nothing about grouping and listing modules.

Body:
I believe these should work.

plugin_files = os.listdir("plugins")
plugins = []
for plugin_file in plugin_files:
    plugins.append(importlib.import_module(plugin_file))

for plugin in plugins:
    plugin.send_notification()

OR

plugins = list(map(importlib.import_module,os.listdir("plugins")))
for plugin in plugins:
    plugin.send_notification()

Quick test below:

class test:
    def __init__(self,name):
        self.name = name

plugins = list(map(test,['bob','jim']))

for plugin in plugins:
    print(plugin.name)

bob
jim


问:
Can Delphi created Soap server app run on linux?
I have been toying around with creating soap servers in Delphi then running and interacting with them being hosted on my localmachine via IIS.

I have a godaddy account that is linux hosting and I am curious if I'll be able to use the Delphi created Soap Servers on this hosting?

答: Free Pascal will be a good alternative. We have deployed several (commercial) applications that use the wst toolkit in Free Pascal to build soap services that run both on windows and linux. Steep learning curve, but once you 'get it' it works very good.</p>


问:
Returning the maximum of non-null columns from a table
I have a table with 4 columns, one of which is a non-null column, all others can be given a null value.
I just want a SELECT that returns results that have as many non-null columns as possible.
For example:
If I have 5 records in my Table, 1 of those records will have 3 columns with data, 2 of them will have 2 columns with data and 2 of them will have only 1 column with data. In my select, I want as a result only the first option: to bring me 3 columns with data. But it can be just 2 columns with data, it will be dynamic according to the table to be updated.

I'm using Oracle SQL.

答:
One option is a conditional sort based on the count of non-null values in each row, and then a row-limiting clause (available since Oracle 12c). Assuming that the 3 nullable columns are col1, col2 and col3, that would be:

```<code>select *
from mytable
order by
      case when col1 is null then 0 else 1 end
    + case when col2 is null then 0 else 1 end
    + case when col3 is null then 0 else 1 end desc
fetch first row with ties
</code>```

If you are running an older version of Oracle, you can get the same result with window function rank():

```<code>select *
from (
    select
        t.*,
        rank() over(order by
              case when col1 is null then 0 else 1 end
            + case when col2 is null then 0 else 1 end
            + case when col3 is null then 0 else 1 end desc
        ) rn
    from mytable t
) t
where rn = 1
</code>```

Body:
One option is a conditional sort based on the count of non-null values in each row, and then a row-limiting clause (available since Oracle 12c). Assuming that the 3 nullable columns are col1, col2 and col3, that would be:

select *
from mytable
order by
      case when col1 is null then 0 else 1 end
    + case when col2 is null then 0 else 1 end
    + case when col3 is null then 0 else 1 end desc
fetch first row with ties

If you are running an older version of Oracle, you can get the same result with window function rank():

select *
from (
    select
        t.*,
        rank() over(order by
              case when col1 is null then 0 else 1 end
            + case when col2 is null then 0 else 1 end
            + case when col3 is null then 0 else 1 end desc
        ) rn
    from mytable t
) t
where rn = 1


问:
Creating Relationships between Entities in Room
I am trying to implement searching of places by name in android. I have created two entities, Word and Place.

```<code>@Parcelize
@Entity
data class Place(
    @PrimaryKey
    val id: String,
    val name: String,
    val icon: String,
    val latitude: Double,
    val longitude: Double,
    val address: String
) : Parcelable
</code>```

```<code>@Entity
data class Word(
    @PrimaryKey(autoGenerate = true)
    val id: Int = 0,
    val searchWord: String,
    val placeId: String
)
</code>```

I have also created another data class to model a one-to-many relationship between Word and Place.

```<code>data class WordWithPlaces(
    @Embedded
    val word: Word,
    @Relation(parentColumn = "placeId", entityColumn = "id")
    val places: List<Place>
)
</code>```

The problem I am getting is that when I query the data I get null.

This is the query function in the dao.

```<code>  @Transaction
    @Query("SELECT * FROM Word WHERE searchWord = :searchWord")
    fun getWordsWithPlaces(searchWord: String): LiveData<WordWithPlaces>
</code>```

I need help getting the implementation to work.

答:
My mistake was in the architecture.

This was not a one-to-many relationship but a many-to-many relationship. I had to use two queries to implement the search.

```<code>    // search for places online based on a searchWord
    // create words consisting of each place's id and the searchWord
    // save the words and places in the database
    suspend fun searchPlaces(searchWord: String) {
        return try {
            val searchResults: PlaceTextSearch = getNetworkService().searchPlaces(searchWord)
            val places = searchResults.places
            val words = places.map { Word(word = searchWord, placeId = it.id) }
            dao.insertWords(words)
            dao.insertPlaces(places)
        } catch (e: Exception) {
            e.printStackTrace()
        }
    }

    // get the words matching a searchword
    // get all related places based on those words
    suspend fun getPlaces(searchWord: String): List<Place> {
        val words = dao.getWords(searchWord)
        val placeIds = words.map { it.placeId }.toTypedArray()
        return dao.getPlaces(placeIds)
    }

</code>```

Body:
I am trying to implement searching of places by name in android. I have created two entities, Word and Place.

@Parcelize
@Entity
data class Place(
    @PrimaryKey
    val id: String,
    val name: String,
    val icon: String,
    val latitude: Double,
    val longitude: Double,
    val address: String
) : Parcelable

@Entity
data class Word(
    @PrimaryKey(autoGenerate = true)
    val id: Int = 0,
    val searchWord: String,
    val placeId: String
)

I have also created another data class to model a one-to-many relationship between Word and Place.

data class WordWithPlaces(
    @Embedded
    val word: Word,
    @Relation(parentColumn = "placeId", entityColumn = "id")
    val places: List<Place>
)

The problem I am getting is that when I query the data I get null.

This is the query function in the dao.

  @Transaction
    @Query("SELECT * FROM Word WHERE searchWord = :searchWord")
    fun getWordsWithPlaces(searchWord: String): LiveData<WordWithPlaces>

I need help getting the implementation to work.

Body:
My mistake was in the architecture.

This was not a one-to-many relationship but a many-to-many relationship. I had to use two queries to implement the search.

    // search for places online based on a searchWord
    // create words consisting of each place's id and the searchWord
    // save the words and places in the database
    suspend fun searchPlaces(searchWord: String) {
        return try {
            val searchResults: PlaceTextSearch = getNetworkService().searchPlaces(searchWord)
            val places = searchResults.places
            val words = places.map { Word(word = searchWord, placeId = it.id) }
            dao.insertWords(words)
            dao.insertPlaces(places)
        } catch (e: Exception) {
            e.printStackTrace()
        }
    }

    // get the words matching a searchword
    // get all related places based on those words
    suspend fun getPlaces(searchWord: String): List<Place> {
        val words = dao.getWords(searchWord)
        val placeIds = words.map { it.placeId }.toTypedArray()
        return dao.getPlaces(placeIds)
    }


问:
Difference in Dates Based on Value of Separate Variable
I have a dataframe that looks like this:

```<code>        Date Value Value_Increase
1 2020-05-01     5          FALSE
2 2020-05-02     4          FALSE
3 2020-05-03    10           TRUE
4 2020-05-04     9          FALSE
5 2020-05-05     7          FALSE
6 2020-05-06    12           TRUE
7 2020-05-07     8          FALSE
</code>```

I want to create a new column that provides the numbers of days since the "Value" column increased.

The results would look like the dataframe below.

```<code>        Date Value Value_Increase Days_Since_Value_Increase
1 2020-05-01     5          FALSE                        NA
2 2020-05-02     4          FALSE                        NA
3 2020-05-03    10           TRUE                        NA
4 2020-05-04     9          FALSE                         1
5 2020-05-05     7          FALSE                         2
6 2020-05-06    12           TRUE                         3
7 2020-05-07     8          FALSE                         1
</code>```

Thanks for any help or suggestion, especially those that might use dplyr approach.

Code to create working example:

```<code>Date <- as.Date(c("2020-05-01", "2020-05-02", "2020-05-03", "2020-05-04", "2020-05-05", "2020-05-06", "2020-05-07"))
Value <- c(5, 4, 10, 9, 7, 12, 8)
Value_Increase <- c(FALSE, FALSE, TRUE, FALSE, FALSE, TRUE, FALSE)
df <- data.frame(Date, Value, Value_Increase, Days_Since_Value_Increase)
</code>```

答:
One approach with tidyverse is to group your results with cumsum so that the days since last value increase would be represented by the row_number() within the group. This assumes difference between rows of one day.

```<code>library(tidyverse)

df %>%
  group_by(g = cumsum(lag(Value_Increase, default = 0))) %>%
  mutate(Days_Since_Value_Increase = ifelse(g == 0, NA, row_number()))
</code>```

Output

```<code># A tibble: 7 x 5
# Groups:   g [3]
  Date       Value Value_Increase     g Days_Since_Value_Increase
  <date>     <dbl> <lgl>          <dbl>                     <int>
1 2020-05-01     5 FALSE              0                        NA
2 2020-05-02     4 FALSE              0                        NA
3 2020-05-03    10 TRUE               0                        NA
4 2020-05-04     9 FALSE              1                         1
5 2020-05-05     7 FALSE              1                         2
6 2020-05-06    12 TRUE               1                         3
7 2020-05-07     8 FALSE              2                         1
</code>```

Body:
I have a dataframe that looks like this:

        Date Value Value_Increase
1 2020-05-01     5          FALSE
2 2020-05-02     4          FALSE
3 2020-05-03    10           TRUE
4 2020-05-04     9          FALSE
5 2020-05-05     7          FALSE
6 2020-05-06    12           TRUE
7 2020-05-07     8          FALSE

I want to create a new column that provides the numbers of days since the "Value" column increased.

The results would look like the dataframe below.

        Date Value Value_Increase Days_Since_Value_Increase
1 2020-05-01     5          FALSE                        NA
2 2020-05-02     4          FALSE                        NA
3 2020-05-03    10           TRUE                        NA
4 2020-05-04     9          FALSE                         1
5 2020-05-05     7          FALSE                         2
6 2020-05-06    12           TRUE                         3
7 2020-05-07     8          FALSE                         1

Thanks for any help or suggestion, especially those that might use dplyr approach.

Code to create working example:

Date <- as.Date(c("2020-05-01", "2020-05-02", "2020-05-03", "2020-05-04", "2020-05-05", "2020-05-06", "2020-05-07"))
Value <- c(5, 4, 10, 9, 7, 12, 8)
Value_Increase <- c(FALSE, FALSE, TRUE, FALSE, FALSE, TRUE, FALSE)
df <- data.frame(Date, Value, Value_Increase, Days_Since_Value_Increase)

Body:
One approach with tidyverse is to group your results with cumsum so that the days since last value increase would be represented by the row_number() within the group. This assumes difference between rows of one day.

library(tidyverse)

df %>%
  group_by(g = cumsum(lag(Value_Increase, default = 0))) %>%
  mutate(Days_Since_Value_Increase = ifelse(g == 0, NA, row_number()))

Output

# A tibble: 7 x 5
# Groups:   g [3]
  Date       Value Value_Increase     g Days_Since_Value_Increase
  <date>     <dbl> <lgl>          <dbl>                     <int>
1 2020-05-01     5 FALSE              0                        NA
2 2020-05-02     4 FALSE              0                        NA
3 2020-05-03    10 TRUE               0                        NA
4 2020-05-04     9 FALSE              1                         1
5 2020-05-05     7 FALSE              1                         2
6 2020-05-06    12 TRUE               1                         3
7 2020-05-07     8 FALSE              2                         1


问:
How to restart scheduled task on runtime with EnableScheduling annotation in spring?
I have been investigating how to change the frequency of a job on runtime with Java 8 and spring. This question was very useful but it did not totally solve my issue.

I can now configure the date when to job should be executed next. But If set the delay to 1 year, then I need to wait 1 year before the new configuration in taken into account.

My idea would be to stop the scheduled task if the configuration value is changed (so from another class). Then recalculate the next time the task should be executed. Perhaps there is an easier way of doing this.

Here is the code I have so far.

```<code>@Configuration
@EnableScheduling
public class RequestSchedulerConfig implements SchedulingConfigurer {

    @Autowired
    SchedulerConfigService schedulerConfigService;

    @Bean
    public RequestScheduler myBean() {
        return new RequestScheduler();
    }

    @Bean(destroyMethod = "shutdown")
    public Executor taskExecutor() {
        return Executors.newScheduledThreadPool(100);
    }

    @Override
    public void configureTasks(ScheduledTaskRegistrar taskRegistrar) {
        taskRegistrar.setScheduler(taskExecutor());
        taskRegistrar.addTriggerTask(
                new Runnable() {
                    @Override public void run() {
                        myBean().startReplenishmentComputation();
                    }
                },
                new Trigger() {
                    @Override public Date nextExecutionTime(TriggerContext triggerContext) {
                        Duration d = schedulerConfigService.getIntervalFromDB();
                        return DateTime.now().plus(d).toDate();
                    }
                }
        );
    }
}
</code>```

This would be what I would like to do.

```<code>@RestController
@RequestMapping("/api/config/scheduler")
public class RequestSchedulerController {

    @Autowired
    ApplicationConfigWrapper applicationConfigWrapper;

    @RequestMapping("/set/")
    @ResponseBody
    public String setRequestSchedulerConfig(@RequestParam(value = "frequency", defaultValue = "") final String frequencyInSeconds){
        changeValueInDb(frequencyInSeconds);
        myJob.restart();
        return "Yeah";
    }

}
</code>```

答:
The following, an improved version of this code, seems a working POC based on Spring Boot. You can start and stop the scheduled tasks any number of times based on a table configuration. But you can't start a stopped job from where it was stopped.

1) In the main class, make sure scheduling is enabled, and perhaps configure a ThreadPoolTaskScheduler with size more than one so scheduled tasks may run in parallel.

```<code>@SpringBootApplication
@EnableScheduling

 @Bean
public TaskScheduler poolScheduler() {
    ThreadPoolTaskScheduler scheduler = new ThreadPoolTaskScheduler();
    scheduler.setThreadNamePrefix("ThreadPoolTaskScheduler");
    scheduler.setPoolSize(10);
    scheduler.initialize();
    return scheduler;
}
</code>```

2) an object that contains the schedule configuration, e.g. a cron like configuration in this case:

```<code>public class ScheduleConfigVo {
//some constructors, getter/setters
    private String  taskName;
    private String  configValue; // like */10 * * * * * for cron

    @Override
    public boolean equals(Object o) {
        if (this == o) return true;
        if (o == null || getClass() != o.getClass()) return false;
        ScheduleConfigVo that = (ScheduleConfigVo) o;
        return taskName.equals(that.taskName) &&
            configValue.equals(that.configValue) ;
    }

    @Override
    public int hashCode() {
        return Objects.hash(taskName, configValue);
    }
}
</code>```

equals and hashCode are needed since object comparison will be conducted.

3) I use mybatis, so the sheduled selection is something like:

```<code>@Mapper
public interface ScheduleConfigMapper {
    List<ScheduleConfigVo> getAllConfigure();
}
</code>```

and

```<code>public class ScheduleConfigMapperImpl implements ScheduleConfigMapper {
    @Override
    public List<ScheduleConfigVo>getAllConfigure() {
        return getAllConfigure();
    }
}
</code>```

with a simple companion mybatis xml configuration (not shown here but can find it anywhere in the internet).

4) create a table and populate it with a record

```<code>CREATE TABLE "SCHEDULER"
( "CLASS_NAME" VARCHAR2(100), --PK
"VALUE" VARCHAR2(20 BYTE) --not null
)
</code>```

and populated it with a record class_name=Task1, value=*/10 * * * * *  etc.  => run like a cron every ten seconds

5) the scheduler part:

```<code>@Service
public class DynamicScheduler implements SchedulingConfigurer {

@Autowired
private ScheduleConfigMapper repo;

@Autowired
private Runnable [] tsks;

@Autowired
private TaskScheduler tsch;

private ScheduledTaskRegistrar scheduledTaskRegistrar;
private ScheduledFuture future;

private Map<String, ScheduledFuture> futureMap = new ConcurrentHashMap<>(); // for the moment it has only class name
List<ScheduleConfigVo> oldList = new ArrayList<>();
List<ScheduleConfigVo> newList;
List<ScheduleConfigVo> addList = new ArrayList<>();
List<ScheduleConfigVo> removeList = new ArrayList<>();

@Override
public void configureTasks(ScheduledTaskRegistrar taskRegistrar) {
    if (scheduledTaskRegistrar == null) {
        scheduledTaskRegistrar = taskRegistrar;
    }
    if (taskRegistrar.getScheduler() == null) {
        taskRegistrar.setScheduler(tsch);
    }
    updateJobList();

}

@Scheduled(fixedDelay = 5000)
public void updateJobList() {
    newList = repo.getConfigure()== null ? new ArrayList<>() : repo.getConfigure();
    addList.clear();
    removeList.clear();

    if (!newList.isEmpty()) {
        //compare new List with oldList
        if (!oldList.isEmpty()) {
            addList = newList.stream().filter(e -> !oldList.contains(e)).collect(Collectors.toList());
            removeList = oldList.stream().filter(e -> !newList.contains(e)).collect(Collectors.toList());
        } else {
            addList = new ArrayList<>(newList); // nothing to remove
        }
    } else { // nothing to add
        if (!oldList.isEmpty()) {
            removeList = new ArrayList<>(oldList);
        } // else removeList = 0
    }
    log.info("addList="+ addList.toString());
    log.info("removeList="+ removeList.toString());
    //re-schedule here

    for ( ScheduleConfigVo conf : removeList ) {
        if ( !futureMap.isEmpty()){
            future = futureMap.get(conf.getTaskName());
            if (future != null) {
                log.info("cancelling task "+conf.getTaskName() +" ...");
                future.cancel(true);
                log.info(conf.getTaskName() + " isCancelled = " + future.isCancelled());
                futureMap.remove(conf.getTaskName());
            }
        }
    }
    for ( ScheduleConfigVo conf : addList ) {
        for (Runnable o: tsks) {
            if (o.getClass().getName().contains(conf.getTaskName())) { // o has fqn whereas conf has class name only
                log.info("find " + o.getClass().getName() + " to add to scheduler");
                future = scheduledTaskRegistrar.getScheduler().schedule(o, (TriggerContext a) -> {
                    CronTrigger crontrigger = new CronTrigger(conf.getConfigValue());
                    return crontrigger.nextExecutionTime(a);
                });
                futureMap.put(o.getClass().getName().substring(o.getClass().getName().lastIndexOf('.')+1), future);
            }
        }
    }

    oldList.clear();
    oldList= newList;
}
</code>```

6) one or more Runnable tasks that actually does the cron work, for instance:

```<code>@Slf4j
@Service
public class Task1 implements Runnable {
    @Override
    public void run() {
        log.info("Task1 is running...");
    }
}
</code>```

Once the application is started, the cron job will run. The running interval changes as the value in the table changes, and the job stops as the table entry is removed.

Note that if the job runs longer than the cron interval, the next run is after the previous job finishes. You can simulate this situation by adding, for instance, sleep 15 seconds in Task1 above to test it. Sometimes after being cancelled, a job maybe still run till it's done.

***Just edit to add that if folks like lambda to save some lines, the above removeList and addList can be modified as:

```<code>removeList.stream().filter(conf -> {
        future = futureMap.get(conf.getTaskName());
        return future != null;
    }).forEach((conf) -> {
        log.info("cancelling task " + conf.getTaskName() + " ...");
        future.cancel(true);
        log.info(conf.getTaskName() + " isCancelled = " + future.isCancelled());
    });
</code>```

and

```<code>Arrays.stream(tsks).forEach(task -> {
        addList.stream().filter(conf -> task.getClass().getName().contains(conf.getTaskName())).forEach(conf -> {
            log.info("find " + task.getClass().getName() + " to add to scheduler");
            future = scheduledTaskRegistrar.getScheduler().schedule(task, (TriggerContext a) -> {
                CronTrigger crontrigger = new CronTrigger(conf.getConfigValue());
                return crontrigger.nextExecutionTime(a);
            });
            futureMap.put(task.getClass().getName().substring(task.getClass().getName().lastIndexOf('.') + 1), future);
        });
    });
</code>```

Body:
I have been investigating how to change the frequency of a job on runtime with Java 8 and spring. This question was very useful but it did not totally solve my issue.

I can now configure the date when to job should be executed next. But If set the delay to 1 year, then I need to wait 1 year before the new configuration in taken into account.

My idea would be to stop the scheduled task if the configuration value is changed (so from another class). Then recalculate the next time the task should be executed. Perhaps there is an easier way of doing this.

Here is the code I have so far.

@Configuration
@EnableScheduling
public class RequestSchedulerConfig implements SchedulingConfigurer {

    @Autowired
    SchedulerConfigService schedulerConfigService;

    @Bean
    public RequestScheduler myBean() {
        return new RequestScheduler();
    }

    @Bean(destroyMethod = "shutdown")
    public Executor taskExecutor() {
        return Executors.newScheduledThreadPool(100);
    }

    @Override
    public void configureTasks(ScheduledTaskRegistrar taskRegistrar) {
        taskRegistrar.setScheduler(taskExecutor());
        taskRegistrar.addTriggerTask(
                new Runnable() {
                    @Override public void run() {
                        myBean().startReplenishmentComputation();
                    }
                },
                new Trigger() {
                    @Override public Date nextExecutionTime(TriggerContext triggerContext) {
                        Duration d = schedulerConfigService.getIntervalFromDB();
                        return DateTime.now().plus(d).toDate();
                    }
                }
        );
    }
}

This would be what I would like to do.

@RestController
@RequestMapping("/api/config/scheduler")
public class RequestSchedulerController {

    @Autowired
    ApplicationConfigWrapper applicationConfigWrapper;

    @RequestMapping("/set/")
    @ResponseBody
    public String setRequestSchedulerConfig(@RequestParam(value = "frequency", defaultValue = "") final String frequencyInSeconds){
        changeValueInDb(frequencyInSeconds);
        myJob.restart();
        return "Yeah";
    }

}

Body:
The following, an improved version of this code, seems a working POC based on Spring Boot. You can start and stop the scheduled tasks any number of times based on a table configuration. But you can't start a stopped job from where it was stopped.

1) In the main class, make sure scheduling is enabled, and perhaps configure a ThreadPoolTaskScheduler with size more than one so scheduled tasks may run in parallel.

@SpringBootApplication
@EnableScheduling

 @Bean
public TaskScheduler poolScheduler() {
    ThreadPoolTaskScheduler scheduler = new ThreadPoolTaskScheduler();
    scheduler.setThreadNamePrefix("ThreadPoolTaskScheduler");
    scheduler.setPoolSize(10);
    scheduler.initialize();
    return scheduler;
}

2) an object that contains the schedule configuration, e.g. a cron like configuration in this case:

public class ScheduleConfigVo {
//some constructors, getter/setters
    private String  taskName;
    private String  configValue; // like */10 * * * * * for cron

    @Override
    public boolean equals(Object o) {
        if (this == o) return true;
        if (o == null || getClass() != o.getClass()) return false;
        ScheduleConfigVo that = (ScheduleConfigVo) o;
        return taskName.equals(that.taskName) &&
            configValue.equals(that.configValue) ;
    }

    @Override
    public int hashCode() {
        return Objects.hash(taskName, configValue);
    }
}

equals and hashCode are needed since object comparison will be conducted.

3) I use mybatis, so the sheduled selection is something like:

@Mapper
public interface ScheduleConfigMapper {
    List<ScheduleConfigVo> getAllConfigure();
}

and

public class ScheduleConfigMapperImpl implements ScheduleConfigMapper {
    @Override
    public List<ScheduleConfigVo>getAllConfigure() {
        return getAllConfigure();
    }
}

with a simple companion mybatis xml configuration (not shown here but can find it anywhere in the internet).

4) create a table and populate it with a record

CREATE TABLE "SCHEDULER"
( "CLASS_NAME" VARCHAR2(100), --PK
"VALUE" VARCHAR2(20 BYTE) --not null
)

and populated it with a record class_name=Task1, value=*/10 * * * * *  etc.  => run like a cron every ten seconds

5) the scheduler part:

@Service
public class DynamicScheduler implements SchedulingConfigurer {

@Autowired
private ScheduleConfigMapper repo;

@Autowired
private Runnable [] tsks;

@Autowired
private TaskScheduler tsch;

private ScheduledTaskRegistrar scheduledTaskRegistrar;
private ScheduledFuture future;

private Map<String, ScheduledFuture> futureMap = new ConcurrentHashMap<>(); // for the moment it has only class name
List<ScheduleConfigVo> oldList = new ArrayList<>();
List<ScheduleConfigVo> newList;
List<ScheduleConfigVo> addList = new ArrayList<>();
List<ScheduleConfigVo> removeList = new ArrayList<>();

@Override
public void configureTasks(ScheduledTaskRegistrar taskRegistrar) {
    if (scheduledTaskRegistrar == null) {
        scheduledTaskRegistrar = taskRegistrar;
    }
    if (taskRegistrar.getScheduler() == null) {
        taskRegistrar.setScheduler(tsch);
    }
    updateJobList();

}

@Scheduled(fixedDelay = 5000)
public void updateJobList() {
    newList = repo.getConfigure()== null ? new ArrayList<>() : repo.getConfigure();
    addList.clear();
    removeList.clear();

    if (!newList.isEmpty()) {
        //compare new List with oldList
        if (!oldList.isEmpty()) {
            addList = newList.stream().filter(e -> !oldList.contains(e)).collect(Collectors.toList());
            removeList = oldList.stream().filter(e -> !newList.contains(e)).collect(Collectors.toList());
        } else {
            addList = new ArrayList<>(newList); // nothing to remove
        }
    } else { // nothing to add
        if (!oldList.isEmpty()) {
            removeList = new ArrayList<>(oldList);
        } // else removeList = 0
    }
    log.info("addList="+ addList.toString());
    log.info("removeList="+ removeList.toString());
    //re-schedule here

    for ( ScheduleConfigVo conf : removeList ) {
        if ( !futureMap.isEmpty()){
            future = futureMap.get(conf.getTaskName());
            if (future != null) {
                log.info("cancelling task "+conf.getTaskName() +" ...");
                future.cancel(true);
                log.info(conf.getTaskName() + " isCancelled = " + future.isCancelled());
                futureMap.remove(conf.getTaskName());
            }
        }
    }
    for ( ScheduleConfigVo conf : addList ) {
        for (Runnable o: tsks) {
            if (o.getClass().getName().contains(conf.getTaskName())) { // o has fqn whereas conf has class name only
                log.info("find " + o.getClass().getName() + " to add to scheduler");
                future = scheduledTaskRegistrar.getScheduler().schedule(o, (TriggerContext a) -> {
                    CronTrigger crontrigger = new CronTrigger(conf.getConfigValue());
                    return crontrigger.nextExecutionTime(a);
                });
                futureMap.put(o.getClass().getName().substring(o.getClass().getName().lastIndexOf('.')+1), future);
            }
        }
    }

    oldList.clear();
    oldList= newList;
}

6) one or more Runnable tasks that actually does the cron work, for instance:

@Slf4j
@Service
public class Task1 implements Runnable {
    @Override
    public void run() {
        log.info("Task1 is running...");
    }
}

Once the application is started, the cron job will run. The running interval changes as the value in the table changes, and the job stops as the table entry is removed.

Note that if the job runs longer than the cron interval, the next run is after the previous job finishes. You can simulate this situation by adding, for instance, sleep 15 seconds in Task1 above to test it. Sometimes after being cancelled, a job maybe still run till it's done.

***Just edit to add that if folks like lambda to save some lines, the above removeList and addList can be modified as:

removeList.stream().filter(conf -> {
        future = futureMap.get(conf.getTaskName());
        return future != null;
    }).forEach((conf) -> {
        log.info("cancelling task " + conf.getTaskName() + " ...");
        future.cancel(true);
        log.info(conf.getTaskName() + " isCancelled = " + future.isCancelled());
    });

and

Arrays.stream(tsks).forEach(task -> {
        addList.stream().filter(conf -> task.getClass().getName().contains(conf.getTaskName())).forEach(conf -> {
            log.info("find " + task.getClass().getName() + " to add to scheduler");
            future = scheduledTaskRegistrar.getScheduler().schedule(task, (TriggerContext a) -> {
                CronTrigger crontrigger = new CronTrigger(conf.getConfigValue());
                return crontrigger.nextExecutionTime(a);
            });
            futureMap.put(task.getClass().getName().substring(task.getClass().getName().lastIndexOf('.') + 1), future);
        });
    });


问:
Jpa not saving or updating table during multiple query
I have 4 update queries and I am running them in the same method. I want the table to be updated on every update query but the table is getting updated after all 4 queries are executed.
Usecase:
I am continuously fetching the AWS EMR cluster details and I want to update the dB table as soon as I get a changed status. For this I have created a table with 5 columns and want to update the column as soon as I get the changed status. I have 4 update queries in my custom repository. Now my table is getting updated but only after all the 4 queries are executed but I want the table to be updated after each update query</p>

答:
It seems like you are executing all queries from a single transaction, and when that transaction is committed, you are able to see the result.

Try executing each query in separate transactions.

Check where you are using the @Transactional annotation.

Note: Even you are not seeing update in DB after all 4 queries, the update of the first query will be visible to second query from transaction context.

Assumption: I am assuming you are checking into DB from outside an application (from db client).


问:
Convert number to month name in PHP
I have this PHP code:

```<code>$monthNum = sprintf("%02s", $result["month"]);
$monthName = date("F", strtotime($monthNum));

echo $monthName;
</code>```

But it's returning December rather than August.

$result["month"] is equal to 8, so the sprintf function is adding a 0 to make it 08.

答:
```<code>$days = ['', 'Jan', 'Feb', 'Mar', 'Apr', 'Mai', 'Jun', 'Jul', 'Aug', 'Sep', 'Oct', 'Nov', 'Dec'];
$month = ( date('m') < 10 ) ? date('m')[1] : date('m');
</code>```

That extracts the months.

Title: Convert number to month name in PHP

Body:
I have this PHP code:

$monthNum = sprintf("%02s", $result["month"]);
$monthName = date("F", strtotime($monthNum));

echo $monthName;

But it's returning December rather than August.

$result["month"] is equal to 8, so the sprintf function is adding a 0 to make it 08.

Body:
$days = ['', 'Jan', 'Feb', 'Mar', 'Apr', 'Mai', 'Jun', 'Jul', 'Aug', 'Sep', 'Oct', 'Nov', 'Dec'];
$month = ( date('m') < 10 ) ? date('m')[1] : date('m');

That extracts the months.


问:
ActionController::InvalidAuthenticityToken Error since re cloned git repo
I have locally deleted my Rails GitHub Project and re-cloned it but since then I am getting the error "ActionController::InvalidAuthenticityToken" when trying to login through Devise.
Image Here

```<code> def handle_unverified_request
      raise ActionController::InvalidAuthenticityToken
    end
  end
end
</code>```

Does it ring a bell for anybody? Maybe some sort of encrypting key have been changed?

I have tried with a different browser, deleting my cookies but same issue.

Thanks

答:
You need to enable the dev cache.

Run rails dev:cache, then restart the dev server.

Body:
I have locally deleted my Rails GitHub Project and re-cloned it but since then I am getting the error "ActionController::InvalidAuthenticityToken" when trying to login through Devise.
Image Here

 def handle_unverified_request
      raise ActionController::InvalidAuthenticityToken
    end
  end
end

Does it ring a bell for anybody? Maybe some sort of encrypting key have been changed?

I have tried with a different browser, deleting my cookies but same issue.

Thanks


答:
We can use case_when from dplyr after creating a grouping variable with cumsum and lag of 'Value_Increase'

```<code>library(dplyr)
df %>%
  group_by(g = cumsum(lag(Value_Increase, default = 0))) %>%
  mutate(Days_Since_Value_Increase = case_when(g != 0 ~  row_number())) %>%
  ungroup %>%
  select(-g)
# A tibble: 7 x 5
#  Date       Value Value_Increase Drop_From_Prev_Value Days_Since_Value_Increase
#  <date>     <dbl> <lgl>                         <dbl>                     <int>
#1 2020-05-01     5 FALSE                            NA                        NA
#2 2020-05-02     4 FALSE                             1                        NA
#3 2020-05-03    10 TRUE                             -6                        NA
#4 2020-05-04     9 FALSE                             1                         1
#5 2020-05-05     7 FALSE                             2                         2
#6 2020-05-06    12 TRUE                             -5                         3
#7 2020-05-07     8 FALSE                             4                         1
</code>```

Or with rowid from data.table

```<code>library(data.table)
df %>%
  mutate(Days_Since_Value_Increase = replace(rowid(cumsum(lag(Value_Increase,
            default = 0))),
             seq_len(which.max(Value_Increase)), NA))
</code>```

Title: Difference in Dates Based on Value of Separate Variable

Body:
We can use case_when from dplyr after creating a grouping variable with cumsum and lag of 'Value_Increase'

library(dplyr)
df %>%
  group_by(g = cumsum(lag(Value_Increase, default = 0))) %>%
  mutate(Days_Since_Value_Increase = case_when(g != 0 ~  row_number())) %>%
  ungroup %>%
  select(-g)
# A tibble: 7 x 5
#  Date       Value Value_Increase Drop_From_Prev_Value Days_Since_Value_Increase
#  <date>     <dbl> <lgl>                         <dbl>                     <int>
#1 2020-05-01     5 FALSE                            NA                        NA
#2 2020-05-02     4 FALSE                             1                        NA
#3 2020-05-03    10 TRUE                             -6                        NA
#4 2020-05-04     9 FALSE                             1                         1
#5 2020-05-05     7 FALSE                             2                         2
#6 2020-05-06    12 TRUE                             -5                         3
#7 2020-05-07     8 FALSE                             4                         1

Or with rowid from data.table

library(data.table)
df %>%
  mutate(Days_Since_Value_Increase = replace(rowid(cumsum(lag(Value_Increase,
            default = 0))),
             seq_len(which.max(Value_Increase)), NA))


问:
Delete item from subcollection array in Firestore Firebase
I am trying to delete item from array in  profile collection named items subcollection. Function should be triggered whenever item is deleted from main items collection. Problem with below function is that when triggered it deletes all items from profile instead of deleted one only. How I could iterate over items array and perform check of deleted item id.

exports.updateDeletedItemOnProfile = functions.firestore
.document('items/{itemId}')
.onDelete((snap, context) => {
    const { itemId } = context.params
    const deletedItem = snap.data()

    if(deletedItem){
      db.collection('profiles')
        .doc(deletedItem.user.id)
        .update({
          items: admin.firestore.FieldValue.delete({
              id: itemId,
              title: deletedItem.title,
              price: deletedItem.price,
              image: deletedItem.image
          })
        })
      }
    return true
})```

答:
onDelete triggers only fire when an entire document was deleted.  By this time, it's too late - the document is simply gone.  Something chose to delete it, and you won't be able to tell what did that.

If you want a function to trigger when any part of a document is modified, you should use an onUpdate trigger instead.  That will give you the entire contents of the document before and after the change.  You will have to compare them to figure out what specifically changed.


问:
PHP ORM with full composite primary/foreign key support
I'm looking for PHP5 ORM which fully supports composite (multi-column) relations based on composite primary keys and foreign keys.

I hoped that Doctrine 2 would solve this problem but it doesn't. It's a basic feature in relational data modelling but none of PHP ORM software I know supports it.

I've recently found that SQLAlchemy has full support but I need something for PHP, not Python.

答: Doctrine 2.1 solves this problem completely.</p>

ContentLicense: CC BY-SA 2.5


问:
Pass ENV to Docker container running single command
This prints blank:

```<code>docker run --rm --env HELLO="world" ubuntu:18.04 bash -c "echo $HELLO"
</code>```

However this works:

```<code>docker run --rm -it --env HELLO="world" ubuntu:18.04 bash
# in the container
echo $HELLO
</code>```

HELLO seems passed to the container though:

```<code>docker run --rm --env HELLO="world" ubuntu:18.04 env
</code>```

Why is the first command not seeing HELLO? What am I missing?

答:
The reason you are not seeing what you expect is because things are being evaluated before you expect them to be evaluated.

When you run:

```<code>docker run --rm --env HELLO="world" ubuntu:18.04 bash -c "echo $HELLO"
</code>```

The "echo $HELLO" really isn't any different to bash than:

```<code>echo "echo $HELLO"
</code>```

The shell (bash) parses double quotes (") and things inside them. It sees "echo $HELLO" and replaces the variable $HOME with it's value. If $HOME is not defined, this evaluates to echo.

So,

```<code>echo "echo $HELLO"
</code>```

is parsed and evaluted by your shell. Which then just runs this at the end:

```<code>echo "echo "
</code>```

So the "echo $HELLO" in your docker command is evaluated to "echo " and that's what gets passed to the docker command.

What you want to do is to prevent your shell from evaluating the variable. You can do it a couple of ways:

You can use single quotes instead of double quotes. Your shell doesn't parse it; it will be passed to the bash inside the container as is:

```<code>docker run --rm --env HELLO="world" ubuntu:18.04 bash -c 'echo $HELLO'
</code>```

You can escape the $ to avoid evaluating it in this shell and let the bash inside the docker container evaluate it:

```<code>docker run --rm --env HELLO="world" ubuntu:18.04 bash -c "echo \$HELLO"
</code>```

Body:
This prints blank:

docker run --rm --env HELLO="world" ubuntu:18.04 bash -c "echo $HELLO"

However this works:

docker run --rm -it --env HELLO="world" ubuntu:18.04 bash
# in the container
echo $HELLO

HELLO seems passed to the container though:

docker run --rm --env HELLO="world" ubuntu:18.04 env

Why is the first command not seeing HELLO? What am I missing?

Body:
The reason you are not seeing what you expect is because things are being evaluated before you expect them to be evaluated.

When you run:

docker run --rm --env HELLO="world" ubuntu:18.04 bash -c "echo $HELLO"

The "echo $HELLO" really isn't any different to bash than:

echo "echo $HELLO"

The shell (bash) parses double quotes (") and things inside them. It sees "echo $HELLO" and replaces the variable $HOME with it's value. If $HOME is not defined, this evaluates to echo.

So,

echo "echo $HELLO"

is parsed and evaluted by your shell. Which then just runs this at the end:

echo "echo "

So the "echo $HELLO" in your docker command is evaluated to "echo " and that's what gets passed to the docker command.

What you want to do is to prevent your shell from evaluating the variable. You can do it a couple of ways:

You can use single quotes instead of double quotes. Your shell doesn't parse it; it will be passed to the bash inside the container as is:

docker run --rm --env HELLO="world" ubuntu:18.04 bash -c 'echo $HELLO'

You can escape the $ to avoid evaluating it in this shell and let the bash inside the docker container evaluate it:

docker run --rm --env HELLO="world" ubuntu:18.04 bash -c "echo \$HELLO"


问:
JMESPath or Ansible flatten dictionaries
I would like to transform an input like this:

```<code>{
    "cluster1": {
        "services": {
            "service1": {
                "name": "foo",
                "version": 1.0
            },
            "service2": {
                "name": "bar",
                "version": 2.0
            }
        }
    },
    "cluster2": {
        "services": {
            "service3": {
                "name": "test",
                "version": 3.0
            },
            "service4": {
                "name": "s4",
                "version": 4.0
            }
        }
    },
    "cluster3": {
        "services": {
            "service5": {
                "name": "s5",
                "version": 5.0
            }
        }
    },
    "clusterx": {
        "name": "value"
    }
}
</code>```

or this (doesn't matter which one):

```<code>[
    {
        "key": "cluster1",
        "value": {
            "services": {
                "service1": {
                    "name": "foo",
                    "version": 1.0
                },
                "service2": {
                    "name": "bar",
                    "version": 2.0
                }
            }
        }
    },
    {
        "key": "cluster2",
        "value": {
            "services": {
                "service3": {
                    "name": "test",
                    "version": 3.0
                },
                "service4": {
                    "name": "s4",
                    "version": 4.0
                }
            }
        }
    },
    {
        "key": "cluster3",
        "value": {
            "services": {
                "service5": {
                    "name": "s5",
                    "version": 5.0
                }
            }
        }
    },
    {
        "key": "clusterx",
        "value": {
            "name": "value"
        }
    }
]
</code>```

into this:

```<code>[
  { "name": "service1", "value": {
    "name": "foo",
    "version": 1
  },
  { "name": "service2", "value": {
    "name": "bar",
    "version": 2
  },
  { "name": "service3", "value": {
    "name": "test",
    "version": 3
  },
  { "name": "service4", "value": {
    "name": "s4",
    "version": 4
  },
  { "name": "service5", "value": {
    "name": "s5",
    "version": 5
  }
]
</code>```

So basically I would like to see a list of all the services flattened.

Is it possible to do this with JMESPath?

What I have so far for the 2nd input type is this: [?value.services].value.services which transforms my input into this:

```<code>[
  {
    "service1": {
      "name": "foo",
      "version": 1
    },
    "service2": {
      "name": "bar",
      "version": 2
    }
  },
  {
    "service3": {
      "name": "test",
      "version": 3
    },
    "service4": {
      "name": "s4",
      "version": 4
    }
  },
  {
    "service5": {
      "name": "s5",
      "version": 5
    }
  }
]
</code>```

So I guess I need another level of flattening, but I'm not sure how to do it.

I'm using Ansible by the way where json_query is very similar to JMESPath.
So if we can achieve this with Ansible / json_query, that's also perfect.

In Ansible I tried something like this which is almost there, but not quite:

```<code>all_services: |
  {{ input | dict2items | json_query('[?value.services].value.services') }}
</code>```

答:
Let's combine a flat dictionary of the services first. For example

    - set_fact:
        all_services_dict: "{{ all_services_dict|default({})|combine(item) }}"
      loop: "{{ input|json_query('*.services') }}"
    - debug:
        var: all_services_dict
```

<p>gives</p>

<pre class="lang-yaml prettyprint-override"><code>
    "all_services_dict": {
        "service1": {
            "name": "foo",
            "version": 1.0
        },
        "service2": {
            "name": "bar",
            "version": 2.0
        },
        "service3": {
            "name": "test",
            "version": 3.0
        },
        "service4": {
            "name": "s4",
            "version": 4.0
        },
        "service5": {
            "name": "s5",
            "version": 5.0
        }
    }
</code>```

Then concatenate the services into a list. For example

    - set_fact:
        all_services_list: "{{ all_services_list|default([]) +
                               [{'name': item.key,
                                 'value': item.value}] }}"
      loop: "{{ all_services_dict|dict2items }}"
    - debug:
        var: all_services_list
```

<p>gives</p>

<pre class="lang-yaml prettyprint-override"><code>
    "all_services_list": [
        {
            "name": "service1",
            "value": {
                "name": "foo",
                "version": 1.0
            }
        },
        {
            "name": "service2",
            "value": {
                "name": "bar",
                "version": 2.0
            }
        },
        {
            "name": "service3",
            "value": {
                "name": "test",
                "version": 3.0
            }
        },
        {
            "name": "service4",
            "value": {
                "name": "s4",
                "version": 4.0
            }
        },
        {
            "name": "service5",
            "value": {
                "name": "s5",
                "version": 5.0
            }
        }
    ]
</code>```

Body:
I would like to transform an input like this:

{
    "cluster1": {
        "services": {
            "service1": {
                "name": "foo",
                "version": 1.0
            },
            "service2": {
                "name": "bar",
                "version": 2.0
            }
        }
    },
    "cluster2": {
        "services": {
            "service3": {
                "name": "test",
                "version": 3.0
            },
            "service4": {
                "name": "s4",
                "version": 4.0
            }
        }
    },
    "cluster3": {
        "services": {
            "service5": {
                "name": "s5",
                "version": 5.0
            }
        }
    },
    "clusterx": {
        "name": "value"
    }
}

or this (doesn't matter which one):

[
    {
        "key": "cluster1",
        "value": {
            "services": {
                "service1": {
                    "name": "foo",
                    "version": 1.0
                },
                "service2": {
                    "name": "bar",
                    "version": 2.0
                }
            }
        }
    },
    {
        "key": "cluster2",
        "value": {
            "services": {
                "service3": {
                    "name": "test",
                    "version": 3.0
                },
                "service4": {
                    "name": "s4",
                    "version": 4.0
                }
            }
        }
    },
    {
        "key": "cluster3",
        "value": {
            "services": {
                "service5": {
                    "name": "s5",
                    "version": 5.0
                }
            }
        }
    },
    {
        "key": "clusterx",
        "value": {
            "name": "value"
        }
    }
]

into this:

[
  { "name": "service1", "value": {
    "name": "foo",
    "version": 1
  },
  { "name": "service2", "value": {
    "name": "bar",
    "version": 2
  },
  { "name": "service3", "value": {
    "name": "test",
    "version": 3
  },
  { "name": "service4", "value": {
    "name": "s4",
    "version": 4
  },
  { "name": "service5", "value": {
    "name": "s5",
    "version": 5
  }
]

So basically I would like to see a list of all the services flattened.

Is it possible to do this with JMESPath?

What I have so far for the 2nd input type is this: [?value.services].value.services which transforms my input into this:

[
  {
    "service1": {
      "name": "foo",
      "version": 1
    },
    "service2": {
      "name": "bar",
      "version": 2
    }
  },
  {
    "service3": {
      "name": "test",
      "version": 3
    },
    "service4": {
      "name": "s4",
      "version": 4
    }
  },
  {
    "service5": {
      "name": "s5",
      "version": 5
    }
  }
]

So I guess I need another level of flattening, but I'm not sure how to do it.

I'm using Ansible by the way where json_query is very similar to JMESPath.
So if we can achieve this with Ansible / json_query, that's also perfect.

In Ansible I tried something like this which is almost there, but not quite:

all_services: |
  {{ input | dict2items | json_query('[?value.services].value.services') }}

Body:
Let's combine a flat dictionary of the services first. For example

    - set_fact:
        all_services_dict: "{{ all_services_dict|default({})|combine(item) }}"
      loop: "{{ input|json_query('*.services') }}"
    - debug:
        var: all_services_dict

gives

    "all_services_dict": {
        "service1": {
            "name": "foo",
            "version": 1.0
        },
        "service2": {
            "name": "bar",
            "version": 2.0
        },
        "service3": {
            "name": "test",
            "version": 3.0
        },
        "service4": {
            "name": "s4",
            "version": 4.0
        },
        "service5": {
            "name": "s5",
            "version": 5.0
        }
    }

Then concatenate the services into a list. For example

    - set_fact:
        all_services_list: "{{ all_services_list|default([]) +
                               [{'name': item.key,
                                 'value': item.value}] }}"
      loop: "{{ all_services_dict|dict2items }}"
    - debug:
        var: all_services_list

gives

    "all_services_list": [
        {
            "name": "service1",
            "value": {
                "name": "foo",
                "version": 1.0
            }
        },
        {
            "name": "service2",
            "value": {
                "name": "bar",
                "version": 2.0
            }
        },
        {
            "name": "service3",
            "value": {
                "name": "test",
                "version": 3.0
            }
        },
        {
            "name": "service4",
            "value": {
                "name": "s4",
                "version": 4.0
            }
        },
        {
            "name": "service5",
            "value": {
                "name": "s5",
                "version": 5.0
            }
        }
    ]