问:
ASP NET Core Web API disable TLS 1.0 and TLS 1.1 support
I am trying to disable the TLS 1.0 and TLS 1.1 support for an API running on docker (Debian OS) and .NET 5. I found this code related to this specific problem:

```<code>     public static IHostBuilder CreateHostBuilder(string[] args) =>
        Host.CreateDefaultBuilder(args)
            .ConfigureWebHostDefaults(webBuilder =>
                {
                    webBuilder.ConfigureKestrel(opt =>
                    {
                        opt.ConfigureHttpsDefaults(s =>
                        {
                            s.SslProtocols = SslProtocols.Tls12 | SslProtocols.Tls13;
                        });
                    }).UseStartup<Startup>();
                }
            );
</code>```

However, when publishing the changes, I am running a script to determine if the TLS1.0 and TLS1.1 are still supported by the server, and surprisingly although I am explicitly setting the HTTPS defaults to TLS1.2 and TLS1.3 I get the following results:

here is the Powershell script:

```<code> $HostName = 'YOUR_URL'
 $Port = '443'

 $RetValue = New-Object psobject -Property @{
            Host = $HostName
            Port = $Port
            SSLv2 = $false
            SSLv3 = $false
            TLSv1_0 = $false
            TLSv1_1 = $false
            TLSv1_2 = $false
            TLSv1_3 = $false
            KeyExhange = $null
            HashAlgorithm = $null
        }
        "ssl2", "ssl3", "tls", "tls11", "tls12","tls13" | %{
            $TcpClient = New-Object Net.Sockets.TcpClient
            $TcpClient.Connect($RetValue.Host, $RetValue.Port)
            $SslStream = New-Object Net.Security.SslStream $TcpClient.GetStream(),
                $true,
                ([System.Net.Security.RemoteCertificateValidationCallback]{ $true })
            $SslStream.ReadTimeout = 15000
            $SslStream.WriteTimeout = 15000
            try {
                $SslStream.AuthenticateAsClient($RetValue.Host,$null,$_,$false)
                $RetValue.KeyExhange = $SslStream.KeyExchangeAlgorithm
                $RetValue.HashAlgorithm = $SslStream.HashAlgorithm
                $status = $true
            } catch {
                $status = $false
            }
            switch ($_) {
                "ssl2" {$RetValue.SSLv2 = $status}
                "ssl3" {$RetValue.SSLv3 = $status}
                "tls" {$RetValue.TLSv1_0 = $status}
                "tls11" {$RetValue.TLSv1_1 = $status}
                "tls12" {$RetValue.TLSv1_2 = $status}
                "tls13" {$RetValue.TLSv1_3 = $status}
            }
            # dispose objects to prevent memory leaks
            $TcpClient.Dispose()
            $SslStream.Dispose()
        }
        $RetValue
</code>```

Is this a bug on Kestrel Configuration? Can I do something else to disable TLS1.0 and TLS1.1 encryptions?

EDIT This is the original issue that I am trying to solve:

The remote service accepts connections encrypted using TLS 1.0. TLS 1.0 has a number of cryptographic design flaws. Newer versions of TLS are designed against these flaws and should be used whenever possible.
PCI DSS v3.1 requires that TLS 1.0 be disabled entirely by June 2018, except for point-of-sale terminals and their termination points.
As of March 31, 2020, Endpoints that aren't enabled for TLS 1.2 and higher will no longer function properly with major web browsers and major vendors.

答:
Since .net 5 it seems that the option to disable TLS version was removed, instead it has to be disabled in the OS.

Kestrel now uses the system default TLS protocol versions rather than
restricting connections to the TLS 1.1 and TLS 1.2 protocols like it
did previously.

https://learn.microsoft.com/en-us/dotnet/core/compatibility/aspnet-core/5.0/kestrel-default-supported-tls-protocol-versions-changed

Then the question might become: how do you disable that in a docker image using Debian, it seems that it can be done by a docker RUN OpenSSL command in the dockerfile, to disable it in OpenSSL or in the config file of OpenSSL.

How to disable TLS v1.0 and TLS v1.1 in OpenSSL

In /etc/ssl/openssl.cnf after oid_section add:

```<code>openssl_conf = default_conf

[default_conf]
ssl_conf = ssl_sect

[ssl_sect]
system_default = system_default_sect

[system_default_sect]
MinProtocol = TLSv1.2
CipherString = DEFAULT@SECLEVEL=2
</code>```

https://blog.surgut.co.uk/2019/08/how-to-disable-tls-10-and-tls-11-on.html

Body:
I am trying to disable the TLS 1.0 and TLS 1.1 support for an API running on docker (Debian OS) and .NET 5. I found this code related to this specific problem:

     public static IHostBuilder CreateHostBuilder(string[] args) =>
        Host.CreateDefaultBuilder(args)
            .ConfigureWebHostDefaults(webBuilder =>
                {
                    webBuilder.ConfigureKestrel(opt =>
                    {
                        opt.ConfigureHttpsDefaults(s =>
                        {
                            s.SslProtocols = SslProtocols.Tls12 | SslProtocols.Tls13;
                        });
                    }).UseStartup<Startup>();
                }
            );

However, when publishing the changes, I am running a script to determine if the TLS1.0 and TLS1.1 are still supported by the server, and surprisingly although I am explicitly setting the HTTPS defaults to TLS1.2 and TLS1.3 I get the following results:

here is the Powershell script:

 $HostName = 'YOUR_URL'
 $Port = '443'

 $RetValue = New-Object psobject -Property @{
            Host = $HostName
            Port = $Port
            SSLv2 = $false
            SSLv3 = $false
            TLSv1_0 = $false
            TLSv1_1 = $false
            TLSv1_2 = $false
            TLSv1_3 = $false
            KeyExhange = $null
            HashAlgorithm = $null
        }
        "ssl2", "ssl3", "tls", "tls11", "tls12","tls13" | %{
            $TcpClient = New-Object Net.Sockets.TcpClient
            $TcpClient.Connect($RetValue.Host, $RetValue.Port)
            $SslStream = New-Object Net.Security.SslStream $TcpClient.GetStream(),
                $true,
                ([System.Net.Security.RemoteCertificateValidationCallback]{ $true })
            $SslStream.ReadTimeout = 15000
            $SslStream.WriteTimeout = 15000
            try {
                $SslStream.AuthenticateAsClient($RetValue.Host,$null,$_,$false)
                $RetValue.KeyExhange = $SslStream.KeyExchangeAlgorithm
                $RetValue.HashAlgorithm = $SslStream.HashAlgorithm
                $status = $true
            } catch {
                $status = $false
            }
            switch ($_) {
                "ssl2" {$RetValue.SSLv2 = $status}
                "ssl3" {$RetValue.SSLv3 = $status}
                "tls" {$RetValue.TLSv1_0 = $status}
                "tls11" {$RetValue.TLSv1_1 = $status}
                "tls12" {$RetValue.TLSv1_2 = $status}
                "tls13" {$RetValue.TLSv1_3 = $status}
            }
            # dispose objects to prevent memory leaks
            $TcpClient.Dispose()
            $SslStream.Dispose()
        }
        $RetValue

Is this a bug on Kestrel Configuration? Can I do something else to disable TLS1.0 and TLS1.1 encryptions?

EDIT This is the original issue that I am trying to solve:

The remote service accepts connections encrypted using TLS 1.0. TLS 1.0 has a number of cryptographic design flaws. Newer versions of TLS are designed against these flaws and should be used whenever possible.
PCI DSS v3.1 requires that TLS 1.0 be disabled entirely by June 2018, except for point-of-sale terminals and their termination points.
As of March 31, 2020, Endpoints that aren't enabled for TLS 1.2 and higher will no longer function properly with major web browsers and major vendors.

Body:
Since .net 5 it seems that the option to disable TLS version was removed, instead it has to be disabled in the OS.

Kestrel now uses the system default TLS protocol versions rather than
restricting connections to the TLS 1.1 and TLS 1.2 protocols like it
did previously.

https://learn.microsoft.com/en-us/dotnet/core/compatibility/aspnet-core/5.0/kestrel-default-supported-tls-protocol-versions-changed

Then the question might become: how do you disable that in a docker image using Debian, it seems that it can be done by a docker RUN OpenSSL command in the dockerfile, to disable it in OpenSSL or in the config file of OpenSSL.

How to disable TLS v1.0 and TLS v1.1 in OpenSSL

In /etc/ssl/openssl.cnf after oid_section add:

openssl_conf = default_conf

[default_conf]
ssl_conf = ssl_sect

[ssl_sect]
system_default = system_default_sect

[system_default_sect]
MinProtocol = TLSv1.2
CipherString = DEFAULT@SECLEVEL=2

https://blog.surgut.co.uk/2019/08/how-to-disable-tls-10-and-tls-11-on.html


来源: stackexchange

问:
JSON: How to grab value that has key value in an array?
I have a JSON response in python like this:

```<code>{
   "response" : [
      {
         "section1" : [
            {
               "test1" : "324d",
               "test2" : "433",
            },
            {
               "item" : "trousers",
               "color" : "red",
               "apply" : [ "never", "exclude" ]
            },
            {
               "price" : "277",
               "tax" : "29",
               "apply" : [ "all", "single" ]
            }
         ],
         "site_id" : "38477d",
      }
   ]
}
</code>```

How can I get the price from the part that has apply value of all?

I have been able to manually grab it like this..

```<code>result['response']['section1'][2]['price']
</code>```

But it changes position in the section each time, how can I search for it instead so that the position does not matter?

UPDATE
To clarify, the all will only ever appear once and it will always be in section1

答:
Search in the list for dicts that have a key called "apply" and then check that key "all" is in that dict:</p>
```<code>[dic['price'] for dic in test['response'][0]['section1'] if 'apply' in dic and 'all' in dic['apply']][0]
</code>```

ContentLicense: CC BY-SA 4.0

Body:
I have a JSON response in python like this:

{
   "response" : [
      {
         "section1" : [
            {
               "test1" : "324d",
               "test2" : "433",
            },
            {
               "item" : "trousers",
               "color" : "red",
               "apply" : [ "never", "exclude" ]
            },
            {
               "price" : "277",
               "tax" : "29",
               "apply" : [ "all", "single" ]
            }
         ],
         "site_id" : "38477d",
      }
   ]
}

How can I get the price from the part that has apply value of all?

I have been able to manually grab it like this..

result['response']['section1'][2]['price']

But it changes position in the section each time, how can I search for it instead so that the position does not matter?

UPDATE
To clarify, the all will only ever appear once and it will always be in section1

Body:
Search in the list for dicts that have a key called "apply" and then check that key "all" is in that dict:

[dic['price'] for dic in test['response'][0]['section1'] if 'apply' in dic and 'all' in dic['apply']][0]


问:
jQuery/JavaScript "this" pointer confusion
The behavior of "this" when function bar is called is baffling me. See the code below. Is there any way to arrange for "this" to be a plain old js object instance when bar is called from a click handler, instead of being the html element?

```<code>// a class with a method

function foo() {

    this.bar();  // when called here, "this" is the foo instance

    var barf = this.bar;
    barf();   // when called here, "this" is the global object

    // when called from a click, "this" is the html element
    $("#thing").after($("<div>click me</div>").click(barf));
}

foo.prototype.bar = function() {
    alert(this);
}
</code>```

答: There's a good explanation on this keyword in JavaScript available at QuirksMode.

OwnerDisplayName: I. J. Kennedy

ContentLicense: CC BY-SA 2.5

Body:
The behavior of "this" when function bar is called is baffling me. See the code below. Is there any way to arrange for "this" to be a plain old js object instance when bar is called from a click handler, instead of being the html element?

// a class with a method

function foo() {

    this.bar();  // when called here, "this" is the foo instance

    var barf = this.bar;
    barf();   // when called here, "this" is the global object

    // when called from a click, "this" is the html element
    $("#thing").after($("
click me
").click(barf));
}

foo.prototype.bar = function() {
    alert(this);
}

OwnerDisplayName: Pawel Krakowiak


问:
Trying to use select2 with Importmaps on Rails 7
I am trying to use Select2 on a new Rails 7 app and am struggling as follows:

I have pinned it into my import maps and imported it like so:

```<code>pin "application", preload: true
pin "@hotwired/turbo-rails", to: "turbo.min.js", preload: true
pin "@hotwired/stimulus", to: "stimulus.min.js", preload: true
pin "@hotwired/stimulus-loading", to: "stimulus-loading.js", preload: true
pin_all_from "app/javascript/controllers", under: "controllers"
pin "trix"
pin "@rails/actiontext", to: "actiontext.js"
pin "select2", to: "https://ga.jspm.io/npm:select2@4.1.0-rc.0/dist/js/select2.js"
pin "jquery", to: "https://ga.jspm.io/npm:jquery@3.6.0/dist/jquery.js"
</code>```

(the two last lines were added when I run bin/importmap pin select2)

```<code>import "jquery";
import "select2";
import "@hotwired/turbo-rails";
import "controllers";
import "trix";
import "@rails/actiontext";
</code>```

(have moved both jquery and select2 to the end as well as to the beginning - didn't change a thing).

When I am in a form, I can access an element with $ like so:

```<code>$('#book_genre_ids');
...(returns the element)
</code>```

But when I manually try - in the console - to run select2() on an element, here's what happens:

```<code>$('#book_genre_ids').select2();
VM574:1 Uncaught TypeError: $(...).select2 is not a function
    at <anonymous>:1:22
</code>```

I did check the network sources (chrome console), and I could find npm:jquery@3.6.0/dist and npm:select2@4.1.0-rc.0/dist from gap.jspm.io.
I found some resources that pointed at multiple jquery libraries being loaded, but I didn't find more than the above in the network sources in the console...

Body:
I am trying to use Select2 on a new Rails 7 app and am struggling as follows:

I have pinned it into my import maps and imported it like so:

pin "application", preload: true
pin "@hotwired/turbo-rails", to: "turbo.min.js", preload: true
pin "@hotwired/stimulus", to: "stimulus.min.js", preload: true
pin "@hotwired/stimulus-loading", to: "stimulus-loading.js", preload: true
pin_all_from "app/javascript/controllers", under: "controllers"
pin "trix"
pin "@rails/actiontext", to: "actiontext.js"
pin "select2", to: "https://ga.jspm.io/npm:select2@4.1.0-rc.0/dist/js/select2.js"
pin "jquery", to: "https://ga.jspm.io/npm:jquery@3.6.0/dist/jquery.js"

(the two last lines were added when I run bin/importmap pin select2)

import "jquery";
import "select2";
import "@hotwired/turbo-rails";
import "controllers";
import "trix";
import "@rails/actiontext";

(have moved both jquery and select2 to the end as well as to the beginning - didn't change a thing).

When I am in a form, I can access an element with $ like so:

$('#book_genre_ids');
...(returns the element)

But when I manually try - in the console - to run select2() on an element, here's what happens:

$('#book_genre_ids').select2();
VM574:1 Uncaught TypeError: $(...).select2 is not a function
    at <anonymous>:1:22

I did check the network sources (chrome console), and I could find npm:jquery@3.6.0/dist and npm:select2@4.1.0-rc.0/dist from gap.jspm.io.
I found some resources that pointed at multiple jquery libraries being loaded, but I didn't find more than the above in the network sources in the console...

Body:
Select2 will register itself as a jQuery function .select2(), so in order to using this method, the select2 lib must be loaded after the jquery lib, otherwise it could not find jquery reference, hence it could not register jquery function, hence the error $(...).select2 is not a function will be throw.

<script src="https://ajax.googleapis.com/ajax/libs/jquery/3.5.1/jquery.min.js" />
<script src="https://cdnjs.cloudflare.com/ajax/libs/select2/4.0.3/js/select2.min.js" />

However, the import is asynchronous loading so it's not guarantee that when select2 look for jquery, this lib is loaded. So although you setup import them in order as below:

import "jquery";
import "select2";

The select2 is still not found the jquery when it needed.

Fortunately, the gem importmap-rails support preloading pin modules (modulepreload), so base on that i come up with a solution: preload jquery before select2

# config/importmap.rb
pin "jquery", to: "https://ga.jspm.io/npm:jquery@3.6.0/dist/jquery.js", preload: true
pin "select2", to: "https://cdn.jsdelivr.net/npm/select2@4.1.0-rc.0/dist/js/select2.min.js"

Then i follow the way Rails7 setup "@hotwired/stimulus" to setup "jquery"

// app/javascript/controllers/application.js
import { Application } from "@hotwired/stimulus"
...
import jQuery from "jquery"
window.jQuery = jQuery // <- "select2" will check this
window.$ = jQuery
...

now on stimulus controllers where "select2" is needed, you could load "select2"

// app/javascript/controllers/demo_controller.js
import { Controller } from "@hotwired/stimulus"
import "select2"

export default class extends Controller {
  initialize() {
    $('.js-example-basic-multiple').select2();
  }
// ...

Note: your "select2" CDN "https://ga.jspm.io/npm:select2@4.1.0-rc.0/dist/js/select2.js" source contain import e from"jquery"; at the first line hence it'll not work in this solution, so i recommend using the official cdn link: "https://cdn.jsdelivr.net/npm/select2@4.1.0-rc.0/dist/js/select2.min.js" instead.

update

In case you don't want to use stimulus, you could pin another js file to setup "select2" and load it in your layout views

// app/javascript/utils.js
import "select2"

$(document).ready(function () {
  $('.js-example-basic-multiple').select2();
});

# config/importmap.rb
...
pin "utils"

# app/views/products/show.html.erb
<%= javascript_import_module_tag("utils") %>
...

Note: you have to use javascript_import_module_tag, not javascript_importmap_tags, reference


问:
XCOPY - How to exclude a certain file name?
This is my current xcopy command:

```<code>xcopy C:\SourceCodeOld\Release\"Source Code"\*.vb C:\SourceCodeNew\"Source Code"\ /S /Y /R
</code>```

In several subfolders, I have a file named "AssemblyInfo.vb". How can I exclude it from being copied?

答:
Create a file excludes.txt and add the files to exclude to it (each in a new line)

```<code>AssemblyInfo.vb
anotherfile.vb
</code>```

Then run your xcopy command using the /EXCLUDE parameter pointing to the file that contains the files to exclude:

```<code>xcopy "C:\SourceCodeOld\Release\Source Code\*.vb" "C:\SourceCodeNew\Source Code\" /EXCLUDE:excludes.txt /S /Y /R
</code>```

To see the various options available for the /EXCLUDE parameter, run xcopy /?

Body:
This is my current xcopy command:

xcopy C:\SourceCodeOld\Release\"Source Code"\*.vb C:\SourceCodeNew\"Source Code"\ /S /Y /R

In several subfolders, I have a file named "AssemblyInfo.vb". How can I exclude it from being copied?

Body:
Create a file excludes.txt and add the files to exclude to it (each in a new line)

AssemblyInfo.vb
anotherfile.vb

Then run your xcopy command using the /EXCLUDE parameter pointing to the file that contains the files to exclude:

xcopy "C:\SourceCodeOld\Release\Source Code\*.vb" "C:\SourceCodeNew\Source Code\" /EXCLUDE:excludes.txt /S /Y /R

To see the various options available for the /EXCLUDE parameter, run xcopy /?


问:
Why does my Descending Bubble Sort not work for an input in ascending order?
This code works for most inputs except for when the input is in ascending order.

e.g.  input is [1,2,3,4,5], output is [5,1,4,2,3], expected is [5,4,3,2,1]

```<code>DescBubbleSort(A)
    for i from n downto 1 do
        for j from n downto i + 1 do
            if A[j] > A[j − 1] then
                A[j] swap A[j-1]
    return A
</code>```

答:
You do the operations in the wrong order.

According to this Wiki-Entry, the correct code is:

```<code> for (n=A.size; n>1; --n){
    for (i=0; i<n-1; ++i){
      if (A[i] > A[i+1]){
        A.swap(i, i+1)
      }
    }
  }
</code>```

EDIT:

Sorry that I was not detailed enough (although SO does not like questions like "find my bug").

Anyway: I assume your code is in Pascal. I hope I corrected your code correctly as follows:

```<code>for i from n downto 1 do
  for j from n downto n-i+1 do
    if A[j] > A[j-1] then
      A[j] swap A[j-1]
return A
</code>```

The same in Swift (that I tested):

```<code>var a = [1,2,3,4,5]
print(a) // Prints [1, 2, 3, 4, 5]
for i in stride(from: 4, through: 1, by: -1) {
  for j in stride(from: 4, through: 4-i+1, by: -1) {
    if a[j] > a[j-1] {
      a.swapAt(j, j-1)
    }
  }
}
print(a) // Prints [5, 4, 3, 2, 1]
</code>```

As you see, your bug is in the 2nd line at downto i + 1.

Body:
This code works for most inputs except for when the input is in ascending order.

e.g.  input is [1,2,3,4,5], output is [5,1,4,2,3], expected is [5,4,3,2,1]

DescBubbleSort(A)
    for i from n downto 1 do
        for j from n downto i + 1 do
            if A[j] > A[j − 1] then
                A[j] swap A[j-1]
    return A

Body:
You do the operations in the wrong order.

According to this Wiki-Entry, the correct code is:

 for (n=A.size; n>1; --n){
    for (i=0; i<n-1; ++i){
      if (A[i] > A[i+1]){
        A.swap(i, i+1)
      }
    }
  }

EDIT:

Sorry that I was not detailed enough (although SO does not like questions like "find my bug").

Anyway: I assume your code is in Pascal. I hope I corrected your code correctly as follows:

for i from n downto 1 do
  for j from n downto n-i+1 do
    if A[j] > A[j-1] then
      A[j] swap A[j-1]
return A

The same in Swift (that I tested):

var a = [1,2,3,4,5]
print(a) // Prints [1, 2, 3, 4, 5]
for i in stride(from: 4, through: 1, by: -1) {
  for j in stride(from: 4, through: 4-i+1, by: -1) {
    if a[j] > a[j-1] {
      a.swapAt(j, j-1)
    }
  }
}
print(a) // Prints [5, 4, 3, 2, 1]

As you see, your bug is in the 2nd line at downto i + 1.


问:
wicket 6 custom error message instead of The value of x is not a valid int
I am using Wicket 6, I want to add custom error message for a specific component (TextField).

This field should only accept number within specific value (0-59). This validation works perfectly. However, when the user enters a non-number... it seems to return a default validation error message. Something like The value of x is not a valid int.

Below is the sample code on how I set the validation/error message when the entered value is greater than 59 or less than zero:

```<code>    ...

    form.add(new ReportErrorControlGroup("minutesLateGroup", new TextField("minutesLate",
            new PropertyModel<String>(m_attendanceInfo, "minutesLate")).setRequired(false).add(new IValidator<Integer>() {
        private static final long serialVersionUID = 1L;

        @Override
        public void validate(IValidatable<Integer> validatable) {
            Integer input = validatable.getValue();
            if (input < 0 || input >= 60) {
                validatable.error(new ValidationError("Please enter a valid minute(s) value, a value between 0 to 59."));
            }
        }
    })));

    ...
</code>```

When the user entered a non-number value, it will return a validation/error message The value of 'minutesLate' is not a valid int.

What I want is to replace this error with something like Please enter valid minute value. and to be applied only to minutesLate.

In my other project, I can set this via messages.properties then something like field.error.incorrect.expected.values={0} is not a valid value.

But this project is Apache Wicket 6 and I have no idea on how to setup/configure messages.properties and use specific message to be displayed when validation fails.

I am thinking of using minutesLate.value.invalid=Please enter valid minute value.

How can I make it see the added messages.properties and use minutesLate.value.invalid for invalid (non-number) values.

答:
The default messages are defined at https://github.com/apache/wicket/blob/c6fde82ce9637c43753b59620b2f5551ad7f20fe/wicket-core/src/main/java/org/apache/wicket/Application.properties#L16

So, you need to override it in MyApplication.properties (must be next to MyApplication.class)

```<code>minutesLate.IConverter=Please enter valid minute value.
</code>```

Body:
I am using Wicket 6, I want to add custom error message for a specific component (TextField).

This field should only accept number within specific value (0-59). This validation works perfectly. However, when the user enters a non-number... it seems to return a default validation error message. Something like The value of x is not a valid int.

Below is the sample code on how I set the validation/error message when the entered value is greater than 59 or less than zero:

    ...

    form.add(new ReportErrorControlGroup("minutesLateGroup", new TextField("minutesLate",
            new PropertyModel<String>(m_attendanceInfo, "minutesLate")).setRequired(false).add(new IValidator<Integer>() {
        private static final long serialVersionUID = 1L;

        @Override
        public void validate(IValidatable<Integer> validatable) {
            Integer input = validatable.getValue();
            if (input < 0 || input >= 60) {
                validatable.error(new ValidationError("Please enter a valid minute(s) value, a value between 0 to 59."));
            }
        }
    })));

    ...

When the user entered a non-number value, it will return a validation/error message The value of 'minutesLate' is not a valid int.

What I want is to replace this error with something like Please enter valid minute value. and to be applied only to minutesLate.

In my other project, I can set this via messages.properties then something like field.error.incorrect.expected.values={0} is not a valid value.

But this project is Apache Wicket 6 and I have no idea on how to setup/configure messages.properties and use specific message to be displayed when validation fails.

I am thinking of using minutesLate.value.invalid=Please enter valid minute value.

How can I make it see the added messages.properties and use minutesLate.value.invalid for invalid (non-number) values.

Body:
The default messages are defined at https://github.com/apache/wicket/blob/c6fde82ce9637c43753b59620b2f5551ad7f20fe/wicket-core/src/main/java/org/apache/wicket/Application.properties#L16

So, you need to override it in MyApplication.properties (must be next to MyApplication.class)

minutesLate.IConverter=Please enter valid minute value.


问:
c# splitting and retrieving values from a string
I have a string like this:

```<code>"http://localhost:55164/Images/photos/2/2.jpg"
</code>```

I need to retrieve the filename and the 2 out of the /2/ and put them into their own strings. I've been messing around with StringBuilder and replace and substr to no avail since the filename length is variable.  Anyone have a quick way to do this?

Thanks

答:
```<code>string link = "http://localhost:55164/Images/photos/2/2.jpg"; // your link
string[] x = link.Split('/'); // split it into pieces at the slash
string filename = (x.Length >= 1) ? x[x.Length - 1] : null; // get the last part
string dir = (x.Length >= 2) ? x[x.Length - 2] : null; // get the 2nd last part
</code>```

Edit, checked the array length before trying to access it's pieces like someone suggested below in the comments.

ContentLicense: CC BY-SA 3.0

Body:
I have a string like this:

"http://localhost:55164/Images/photos/2/2.jpg"

I need to retrieve the filename and the 2 out of the /2/ and put them into their own strings. I've been messing around with StringBuilder and replace and substr to no avail since the filename length is variable.  Anyone have a quick way to do this?

Thanks

Body:
string link = "http://localhost:55164/Images/photos/2/2.jpg"; // your link
string[] x = link.Split('/'); // split it into pieces at the slash
string filename = (x.Length >= 1) ? x[x.Length - 1] : null; // get the last part
string dir = (x.Length >= 2) ? x[x.Length - 2] : null; // get the 2nd last part

Edit, checked the array length before trying to access it's pieces like someone suggested below in the comments.


问:
How to send service emails via Gmail (machine-2-machine) with secure restrictions?
How to send service emails

from my backend with smtp.google.com or Gmail API while making sure

the secret stored on the backend server can only be used to send emails from a specific sender?

Goal

send user account activation emails from my backend

use smtp.google.com or Gmail API (i.e. no own SMTP server)

authenticate with OAuth2.0 (i.e. don't enable "less secure apps")

Current state

implemented the email sending part

for testing, I created a noreply@**.** Google Suite account

for testing, I generated an accessToken via OAuth2 Playground

using the accessToken I can send emails via smtp.googl.com

Problem

Google suggests to use a service account for this

But to send emails from no-reply@x.y I have to enable Domain-wide Delegation

Domain-wide delegation allows to impersonate every domain account

the secret stored on the backend should only allow to send mails from no-reply@**.**

答:
Lets start with send user account activation emails from my server I am gong to assume that you have a web app.  This web app allows users to register with your system. Now when a user registers with your system you want to automatically send them an account creation email.   Your idea is to use Google rather than setting up your own smtp server and sending these emails from your own system.  Not a bad idea really.

Lets think about this for a minute the emails would need to be sent automatically so you need some kind of service sending them.  To do that you want to use a service account.  Again this is a great idea using a pre authorized service account that you will not need to have a user to authorize the app.

The only issue is that service accounts do not work with normal gmail accounts. To use a service account with Gmail api you need to use a google workspace domain account. The workspace domain admin would then be able to add permissions to the service account letting it act like a user on the domain. In this case your idea of no-reply.

So your workspace domain account would have a user called no-reply.  The domain admin would then configure domain wide delegation to the service account allowing it to pretend that it is the user called no-reply.  For all intents and purposes the service account is the no-reply user.  It will be able to send mails as if they are coming from that user.

For all this to work you will need the workspace account with that user.

Have a look at the following link, it's actually one of Google's better examples it shows how to set up the delegation.

Perform Google Workspace Domain-Wide Delegation of Authority

Here you create a service account with credentials, allow this account to impersonate other users (e.g. the no-reply user), to only use the Gmail API and to only use it to send emails.

the documentation is a bit outdated, you can skip the step Grant users access to this service account and create the service account key afterwards via the service account edit function: Manage keys

in the step Domain wide delegation you need Google Admin not the Google Cloud Platform Admin Console as in the previous step

Just remember to swap out the lines about

```<code>https://www.googleapis.com/auth/admin.directory.user,
https://www.googleapis.com/auth/admin.directory.group
</code>```

and use

```<code>https://www.googleapis.com/auth/gmail.send
</code>```

instead as you want to access the Gmail API and only allow the service account to send (not read) emails

tip

in the sample code in that link

```<code>.setServiceAccountUser(userEmail)
</code>```

userEmail is the email address of the user you want to impersonate in this case no-reply@x.y

So I guess what I am saying is that what you want to do is definitely possible, however, it may be easier just to set up your own SMTP server.

Body:
Lets start with send user account activation emails from my server I am gong to assume that you have a web app.  This web app allows users to register with your system. Now when a user registers with your system you want to automatically send them an account creation email.   Your idea is to use Google rather than setting up your own smtp server and sending these emails from your own system.  Not a bad idea really.

Lets think about this for a minute the emails would need to be sent automatically so you need some kind of service sending them.  To do that you want to use a service account.  Again this is a great idea using a pre authorized service account that you will not need to have a user to authorize the app.

The only issue is that service accounts do not work with normal gmail accounts. To use a service account with Gmail api you need to use a google workspace domain account. The workspace domain admin would then be able to add permissions to the service account letting it act like a user on the domain. In this case your idea of no-reply.

So your workspace domain account would have a user called no-reply.  The domain admin would then configure domain wide delegation to the service account allowing it to pretend that it is the user called no-reply.  For all intents and purposes the service account is the no-reply user.  It will be able to send mails as if they are coming from that user.

For all this to work you will need the workspace account with that user.

Have a look at the following link, it's actually one of Google's better examples it shows how to set up the delegation.

Perform Google Workspace Domain-Wide Delegation of Authority

Here you create a service account with credentials, allow this account to impersonate other users (e.g. the no-reply user), to only use the Gmail API and to only use it to send emails.

the documentation is a bit outdated, you can skip the step Grant users access to this service account and create the service account key afterwards via the service account edit function: Manage keys

in the step Domain wide delegation you need Google Admin not the Google Cloud Platform Admin Console as in the previous step

Just remember to swap out the lines about

https://www.googleapis.com/auth/admin.directory.user,
https://www.googleapis.com/auth/admin.directory.group

and use

https://www.googleapis.com/auth/gmail.send

instead as you want to access the Gmail API and only allow the service account to send (not read) emails

tip

in the sample code in that link

.setServiceAccountUser(userEmail)

userEmail is the email address of the user you want to impersonate in this case no-reply@x.y

So I guess what I am saying is that what you want to do is definitely possible, however, it may be easier just to set up your own SMTP server.


问:
Run update script from select result for each row
I have a table with thousands scripts that I would like to run them in a while loop, but the query result doesn't have an ID column that can use to count, do you know?

There is only on column with the scripts. See some sample data:

```<code>UPDATE CAT_SP_03476811013725_01_2009 SET COD_LEGAL = '' WHERE ISNULL(PRODUTO_EXCLUIDO,'') <> 'S'
UPDATE CAT_SP_03476811013725_02_2009 SET COD_LEGAL = '' WHERE ISNULL(PRODUTO_EXCLUIDO,'') <> 'S'
UPDATE CAT_SP_03476811013725_03_2009 SET COD_LEGAL = '' WHERE ISNULL(PRODUTO_EXCLUIDO,'') <> 'S'
</code>```

I need to run each script from each row in a store procedure, but I don't know how to do it and I wouldn't like to copy the result and past them in the query editor because there are thousands records in dozen of tables, so, can someone help me with some example of store procedure to reach out this goal?

Any help will be appreciated.

答:
Following the Seaport recommendation, I create this sp:

```<code>CREATE TABLE #tabscrdia (id int identity(1,1), script varchar(255))

--Insere os dados desejados na tabela temporária recem criada
INSERT INTO #tabscrdia
    SELECT
        CONCAT('UPDATE ', [name], ' SET COD_LEGAL = '''' WHERE ISNULL(PRODUTO_EXCLUIDO,'''') <> ''S'' AND TIPO_OPERACAO = ''E'' AND cenario = ''10'' AND COD_LEGAL <> ''''  AND DESCARTE IS NULL') Query
    FROM sys.tables
    WHERE ([name] like 'CAT_SP_%%_2009'
        OR [name] like 'CAT_SP_%%_2010'
        OR [name] like 'CAT_SP_%%_2011'
        OR [name] like 'CAT_SP_%%_2012'
        OR [name] like 'CAT_SP_%%_2013'
        OR [name] like 'CAT_SP_%%_2014')
        AND [name] not in ('CAT_SP_03476811010033_06_2009', 'CAT_SP_03476811010033_07_2010', 'CAT_SP_03476811012249_03_2012')
        order by substring(name,26,4), substring(name,8,14), substring(name,23,2)

--Cria as variáveis desejadas
DECLARE @count INT
DECLARE @script VARCHAR(255)
SET @count = 1

--Cria um looping para realizar a ação desejada para cada linha da tabela temporária
WHILE @count <= (select max(id) from #tabscrdia)

BEGIN
    DECLARE @cmd VARCHAR(255)

    --Atribui o script recuperado à variável @script
    SET @cmd = 'select [@script] = script from #tabscrdia where id = [@count]'

    --Transforma o script recuperado em um comando
    SET @cmd = replace(@cmd,'@script',@script)

    --Executa o comando (descomentar após testar de print e comentar teste de print)
    PRINT @cmd
    --exec sp_executesql @cmd

    --Incrementa o contador
    SET @count = @count + 1

END

--Deleta a tabela temporária
drop table #tabscrdia
</code>```

But is is not showing the scripts that I want to run.

What is wrong that? I'm not expert in SQL. Can somebody else give me a north?

Body:
I have a table with thousands scripts that I would like to run them in a while loop, but the query result doesn't have an ID column that can use to count, do you know?

There is only on column with the scripts. See some sample data:

UPDATE CAT_SP_03476811013725_01_2009 SET COD_LEGAL = '' WHERE ISNULL(PRODUTO_EXCLUIDO,'') <> 'S'
UPDATE CAT_SP_03476811013725_02_2009 SET COD_LEGAL = '' WHERE ISNULL(PRODUTO_EXCLUIDO,'') <> 'S'
UPDATE CAT_SP_03476811013725_03_2009 SET COD_LEGAL = '' WHERE ISNULL(PRODUTO_EXCLUIDO,'') <> 'S'

I need to run each script from each row in a store procedure, but I don't know how to do it and I wouldn't like to copy the result and past them in the query editor because there are thousands records in dozen of tables, so, can someone help me with some example of store procedure to reach out this goal?

Any help will be appreciated.

Body:
Following the Seaport recommendation, I create this sp:

CREATE TABLE #tabscrdia (id int identity(1,1), script varchar(255))

--Insere os dados desejados na tabela temporária recem criada
INSERT INTO #tabscrdia
    SELECT
        CONCAT('UPDATE ', [name], ' SET COD_LEGAL = '''' WHERE ISNULL(PRODUTO_EXCLUIDO,'''') <> ''S'' AND TIPO_OPERACAO = ''E'' AND cenario = ''10'' AND COD_LEGAL <> ''''  AND DESCARTE IS NULL') Query
    FROM sys.tables
    WHERE ([name] like 'CAT_SP_%%_2009'
        OR [name] like 'CAT_SP_%%_2010'
        OR [name] like 'CAT_SP_%%_2011'
        OR [name] like 'CAT_SP_%%_2012'
        OR [name] like 'CAT_SP_%%_2013'
        OR [name] like 'CAT_SP_%%_2014')
        AND [name] not in ('CAT_SP_03476811010033_06_2009', 'CAT_SP_03476811010033_07_2010', 'CAT_SP_03476811012249_03_2012')
        order by substring(name,26,4), substring(name,8,14), substring(name,23,2)

--Cria as variáveis desejadas
DECLARE @count INT
DECLARE @script VARCHAR(255)
SET @count = 1

--Cria um looping para realizar a ação desejada para cada linha da tabela temporária
WHILE @count <= (select max(id) from #tabscrdia)

BEGIN
    DECLARE @cmd VARCHAR(255)

    --Atribui o script recuperado à variável @script
    SET @cmd = 'select [@script] = script from #tabscrdia where id = [@count]'

    --Transforma o script recuperado em um comando
    SET @cmd = replace(@cmd,'@script',@script)

    --Executa o comando (descomentar após testar de print e comentar teste de print)
    PRINT @cmd
    --exec sp_executesql @cmd

    --Incrementa o contador
    SET @count = @count + 1

END

--Deleta a tabela temporária
drop table #tabscrdia

But is is not showing the scripts that I want to run.

What is wrong that? I'm not expert in SQL. Can somebody else give me a north?


问:
propType "name" is not required, but has no corresponding defaultProps declaration
I have a component with optional props. I'm defining the default values of the optional props by passing them to the Card component, nevertheless eslint keeps telling me propType "text" is not required, but has no corresponding defaultProps declaration. The same goes for the children prop. The code below seems to be in line with the example without defaultProps on this page: https://github.com/yannickcr/eslint-plugin-react/blob/master/docs/rules/require-default-props.md.

```<code>import { ReactElement } from 'react';

interface CardProps {
  title: string,
  text?: string | (string|ReactElement)[],   // eslint is complaining here
  children?: React.ReactNode                 // and here
}

const Card = ({ title, text = '', children = null }: CardProps) => (
    <div className="container">
      <div className="title">{title}</div>
      <div className="underline" />
      <div className="card">
        <div className="text">
          {text}
          {children}
        </div>
      </div>
    </div>
);
</code>```

My eslint (7.32.0) config is as follows:

```<code>{
    "env": {
        "browser": true,
        "es2021": true
    },
    "extends": [
        "plugin:react/recommended",
        "airbnb"
    ],
    "parser": "@typescript-eslint/parser",
    "parserOptions": {
        "ecmaFeatures": {
            "jsx": true
        },
        "ecmaVersion": 12,
        "sourceType": "module"
    },
    "plugins": [
        "react",
        "@typescript-eslint"
    ],
    "rules": {
        "react/jsx-filename-extension": [1, { "extensions": [".ts", ".tsx"] }],
        "react/jsx-uses-react": "off",
        "react/react-in-jsx-scope": "off",
        "import/extensions": [
            "error",
            "ignorePackages",
            {
              "js": "never",
              "jsx": "never",
              "ts": "never",
              "tsx": "never"
            }
        ],
        "no-use-before-define": "off",
        "@typescript-eslint/no-use-before-define": ["error"]
    },
    "settings": {
        "import/resolver": {
            "node": {
            "extensions": [".js", ".jsx", ".ts", ".tsx"]
            }
        }
    },
    "globals": {
        "React": true,
        "JSX": true
    }
}
</code>```

答:
As @Jack mentioned

```<code>export interface Props {
  children?: ReactNode;
}
</code>```

Exporting the interface worked!

Body:
I have a component with optional props. I'm defining the default values of the optional props by passing them to the Card component, nevertheless eslint keeps telling me propType "text" is not required, but has no corresponding defaultProps declaration. The same goes for the children prop. The code below seems to be in line with the example without defaultProps on this page: https://github.com/yannickcr/eslint-plugin-react/blob/master/docs/rules/require-default-props.md.

import { ReactElement } from 'react';

interface CardProps {
  title: string,
  text?: string | (string|ReactElement)[],   // eslint is complaining here
  children?: React.ReactNode                 // and here
}

const Card = ({ title, text = '', children = null }: CardProps) => (

{title}

          {text}
          {children}

);

My eslint (7.32.0) config is as follows:

{
    "env": {
        "browser": true,
        "es2021": true
    },
    "extends": [
        "plugin:react/recommended",
        "airbnb"
    ],
    "parser": "@typescript-eslint/parser",
    "parserOptions": {
        "ecmaFeatures": {
            "jsx": true
        },
        "ecmaVersion": 12,
        "sourceType": "module"
    },
    "plugins": [
        "react",
        "@typescript-eslint"
    ],
    "rules": {
        "react/jsx-filename-extension": [1, { "extensions": [".ts", ".tsx"] }],
        "react/jsx-uses-react": "off",
        "react/react-in-jsx-scope": "off",
        "import/extensions": [
            "error",
            "ignorePackages",
            {
              "js": "never",
              "jsx": "never",
              "ts": "never",
              "tsx": "never"
            }
        ],
        "no-use-before-define": "off",
        "@typescript-eslint/no-use-before-define": ["error"]
    },
    "settings": {
        "import/resolver": {
            "node": {
            "extensions": [".js", ".jsx", ".ts", ".tsx"]
            }
        }
    },
    "globals": {
        "React": true,
        "JSX": true
    }
}

Body:
As @Jack mentioned

export interface Props {
  children?: ReactNode;
}

Exporting the interface worked!


问:
Join tables from two databases in C#
With SQL Server I run this query with no problem...

```<code>SELECT SUM(Esi) AS Dispo
FROM [mdb].[dbo].[Query1] AS A
  INNER JOIN [mdb2].[dbo].[TieCol] as B ON A.Alias=B.IDAlias
WHERE Alias LIKE 'SETUP%'
</code>```

I join two tables that reside in two different databases (mdb and mdb2).

But how can I do it in my .NET application?
When I need to use this statement

```<code>string cmdText = "SELECT SUM(Esi) AS Dispo
                  FROM [mdb].[dbo].[Query1] AS A
                    INNER JOIN [mdb2].[dbo].[TieCol] as B ON A.Alias=B.IDAlias
                  WHERE Alias LIKE 'SETUP%'";

this.OP = new SqlConnection(ConfigurationManager.ConnectionStrings["mdb2"].ConnectionString);
SqlCommand sqlCommand = new SqlCommand(cmdText, this.OP);
</code>```

I can't execute it, since this.OP is the connection to mdb2... And for mdb?

How can I connect to both databases simultanously?

答: I'm not sure if there is a way to do this within the connection string. But you can probably do it using a four part reference to the table: [server].[database].[table].[column].

Title: Join tables from two databases in C#

Body:
With SQL Server I run this query with no problem...

SELECT SUM(Esi) AS Dispo
FROM [mdb].[dbo].[Query1] AS A
  INNER JOIN [mdb2].[dbo].[TieCol] as B ON A.Alias=B.IDAlias
WHERE Alias LIKE 'SETUP%'

I join two tables that reside in two different databases (mdb and mdb2).

But how can I do it in my .NET application?
When I need to use this statement

string cmdText = "SELECT SUM(Esi) AS Dispo
                  FROM [mdb].[dbo].[Query1] AS A
                    INNER JOIN [mdb2].[dbo].[TieCol] as B ON A.Alias=B.IDAlias
                  WHERE Alias LIKE 'SETUP%'";

this.OP = new SqlConnection(ConfigurationManager.ConnectionStrings["mdb2"].ConnectionString);
SqlCommand sqlCommand = new SqlCommand(cmdText, this.OP);

I can't execute it, since this.OP is the connection to mdb2... And for mdb?

How can I connect to both databases simultanously?


问:
Get random password in javascript
I'm making a course and one of the tasks is to generate four different passwords that should fill the four different paragraphs

,

,

,

I have created a script that creates a password but somehow it doesn't print the first password. When I do console.log(password) it shows that creates a password on the console. But when I try to put first.textContent = password it shows nothing.

let chars = ["0", "1", "2", "3", "4", "5", "6", "7", "8", "9", "a", "b", "c", "d", "A", "B", "C", "D"]
let number = 10
let password = ""
let first = document.getElementById("first")
let second = document.getElementById("second")
let third = document.getElementById("third")
let fourth = document.getElementById("fourth")

function generate() {
  for (let i = 0; i < number; i++) {
    let passwordChar = Math.floor(Math.random() * chars.length)
    password += chars[passwordChar]
    return password
  }
}
first.textContent = password```
<pre class="snippet-code-html lang-html prettyprint-override"><code><html>

<head>
  <link rel="stylesheet" href="index.css">
</head>

<body>
  <h1>Generate a random password</h1>
  <p id="description">Never use an insecure password again</p>
  <button onclick="generate()">Generate passwords</button>
  <p id="line"></p>
  <p id="first"></p>
  <p id="second"></p>
  <p id="third"></p>
  <p id="fourth"></p>
</body>

</html></code>```

I'm also stuck to generate each time the function is running a new password and put it on the next paragraph. Like so:

```<code>first.textContent = password
second.textContent = password
third.textContent = password
fourth.textContent = password
</code>```

Any help will be appreciated

答:
Please pay attention to every single line of code you write. Every single line has a meaning!

You don't need to keep track of the 'password' in an outer scope variable. You just need a local variable (also note the return part should be after the for loop:

```<code>function generate() {
    let pw = ''
    for (let i = 0; i < number; i++) {
        let passwordChar = Math.floor(Math.random() * chars.length)
        pw += chars[passwordChar]
    }
    return pw
}
</code>```

You are not calling the generate():

```<code>first.textContent = generate()
second.textContent = generate()
third.textContent = generate()
fourth.textContent = generate()
</code>```

Title: Get random password in javascript

Body:
I'm making a course and one of the tasks is to generate four different passwords that should fill the four different paragraphs

,

,

,

I have created a script that creates a password but somehow it doesn't print the first password. When I do console.log(password) it shows that creates a password on the console. But when I try to put first.textContent = password it shows nothing.

let chars = ["0", "1", "2", "3", "4", "5", "6", "7", "8", "9", "a", "b", "c", "d", "A", "B", "C", "D"]
let number = 10
let password = ""
let first = document.getElementById("first")
let second = document.getElementById("second")
let third = document.getElementById("third")
let fourth = document.getElementById("fourth")

function generate() {
  for (let i = 0; i < number; i++) {
    let passwordChar = Math.floor(Math.random() * chars.length)
    password += chars[passwordChar]
    return password
  }
}
first.textContent = password

  <link rel="stylesheet" href="index.css">

Generate a random password

Never use an insecure password again

  <button onclick="generate()">Generate passwords</button>

I'm also stuck to generate each time the function is running a new password and put it on the next paragraph. Like so:

first.textContent = password
second.textContent = password
third.textContent = password
fourth.textContent = password

Any help will be appreciated

Body:
Please pay attention to every single line of code you write. Every single line has a meaning!

You don't need to keep track of the 'password' in an outer scope variable. You just need a local variable (also note the return part should be after the for loop:

function generate() {
    let pw = ''
    for (let i = 0; i < number; i++) {
        let passwordChar = Math.floor(Math.random() * chars.length)
        pw += chars[passwordChar]
    }
    return pw
}

You are not calling the generate():

first.textContent = generate()
second.textContent = generate()
third.textContent = generate()
fourth.textContent = generate()


问:
I cound'nt find buildscript in build.gradle(Project)
This is build.gradle(Project) what i knew.

```<code>buildscript {

    repositories {
        google()
        jcenter()
    }

    dependencies {
        classpath 'com.android.tools.build:gradle:7.0.0'
    }
}

allprojects {
    repositories {
        google()
        jcenter()
    }
}
</code>```

But my Project's build.gradle(Project) is that.

```<code>// Top-level build file where you can add configuration options common to all sub-projects/modules.
plugins {
    id 'com.android.application' version '7.1.1' apply false
    id 'com.android.library' version '7.1.1' apply false
}

task clean(type: Delete) {
    delete rootProject.buildDir
}
</code>```

I tried to link Firebase with Android, but build.gradle(Project) was different from the file I knew.

I tried to modify it by force, but it didn't sync...

How can I access the Top-Level Gradle file??

答: Please Check your Setting.gradle file.</p>

Body:
This is build.gradle(Project) what i knew.

buildscript {

    repositories {
        google()
        jcenter()
    }

    dependencies {
        classpath 'com.android.tools.build:gradle:7.0.0'
    }
}

allprojects {
    repositories {
        google()
        jcenter()
    }
}

But my Project's build.gradle(Project) is that.

// Top-level build file where you can add configuration options common to all sub-projects/modules.
plugins {
    id 'com.android.application' version '7.1.1' apply false
    id 'com.android.library' version '7.1.1' apply false
}

task clean(type: Delete) {
    delete rootProject.buildDir
}

I tried to link Firebase with Android, but build.gradle(Project) was different from the file I knew.

I tried to modify it by force, but it didn't sync...

How can I access the Top-Level Gradle file??

Body: Please Check your Setting.gradle file.


问:
Filtered Group-How to group one column with and add calculated columns
DATASET I CURRENTLY HAVE-

```<code>COUNTRY city    id  tag dummy
India   ackno   1   2   1
China   open    0   0   1
India   ackno   1   2   1
China   open    0   0   1
USA     open    0   0   1
USA     open    0   0   1
China   ackno   1   2   1
USA     ackno   1   2   1
USA     resol   1   0   1
Russia  open    0   0   1
Italy   open    0   0   1
</code>```

country=df['country'].unique().tolist()
city=['resol','ackno']

#below are the preferred filters for calculating column percentage
df_looped=df[(df['city'].isin(city)) & (df['id']!=0) | (df['tag']!=0)]
percentage=(df_looped/df)*100

df_summed=df.groupby(['COUNTRY']).agg({'COUNTRY':'count'})
summed=df_summed['COUNTRY'].sum(axis=0)
```
<p>THE DATASET I WANT-</p>
```COUNTRY percentage  summed
india   100%          2
China   66.66%        3
USA     25%           4
Russia  0%            1
Italy   0%            1
```

percentage should be derived from the above formula for every unique country and same for the sum.
percentage variable and summed variable should populate the columns.

答:
You can create helper column a by your conditions and for percentages of Trues use mean, for count values used GroupBy.size (because GroupBy.count omit misisng values and here no missing values) and last divide columns:

```<code>city=['resol','ackno']

df = (df.assign(a = (df['city'].isin(city) & (df['id']!=0) | (df['tag']!=0)))
        .groupby('COUNTRY', sort=False)
        .agg(percentage= ('a','mean'),summed=('a', 'size'))
        .assign(percentage = lambda x: x['percentage'].mul(100).round(2))
        )
print (df)
         percentage  summed
COUNTRY
India        100.00       2
China         33.33       3
USA           50.00       4
Russia         0.00       1
Italy          0.00       1
</code>```

Body:
DATASET I CURRENTLY HAVE-

COUNTRY city    id  tag dummy
India   ackno   1   2   1
China   open    0   0   1
India   ackno   1   2   1
China   open    0   0   1
USA     open    0   0   1
USA     open    0   0   1
China   ackno   1   2   1
USA     ackno   1   2   1
USA     resol   1   0   1
Russia  open    0   0   1
Italy   open    0   0   1

country=df['country'].unique().tolist()
city=['resol','ackno']

#below are the preferred filters for calculating column percentage
df_looped=df[(df['city'].isin(city)) & (df['id']!=0) | (df['tag']!=0)]
percentage=(df_looped/df)*100

df_summed=df.groupby(['COUNTRY']).agg({'COUNTRY':'count'})
summed=df_summed['COUNTRY'].sum(axis=0)

THE DATASET I WANT-

COUNTRY percentage  summed
india   100%          2
China   66.66%        3
USA     25%           4
Russia  0%            1
Italy   0%            1

percentage should be derived from the above formula for every unique country and same for the sum.
percentage variable and summed variable should populate the columns.

Body:
You can create helper column a by your conditions and for percentages of Trues use mean, for count values used GroupBy.size (because GroupBy.count omit misisng values and here no missing values) and last divide columns:

city=['resol','ackno']

df = (df.assign(a = (df['city'].isin(city) & (df['id']!=0) | (df['tag']!=0)))
        .groupby('COUNTRY', sort=False)
        .agg(percentage= ('a','mean'),summed=('a', 'size'))
        .assign(percentage = lambda x: x['percentage'].mul(100).round(2))
        )
print (df)
         percentage  summed
COUNTRY
India        100.00       2
China         33.33       3
USA           50.00       4
Russia         0.00       1
Italy          0.00       1


问:
Email field is accepting emojis
I'm using RegExp to validate email in one of my Flutter projects. Apparently, I'm able to insert, both by typing and copy-pasting, emojis in the email field. Below is the code for the email field:

```<code>Container(
  child: Theme(
    data: ThemeData(
        primaryColor: backgroundColor,
        hintColor: hintTextColor,
        primarySwatch: backgroundColorMaterial),
    child: TextFormField(
      controller: provider.emailController,
      border: outlineBorderGrey,
      hintText: Translations.of(context).getEmail,
      labelText: Translations.of(context).getEmail,
      prefixIcon: IconButton(
        icon: provider.emailvalid ? emailFieldLogo : emailFieldLogoRed,
      ),
    ),
    inputFormatters: [ValidateHelper.emailRegex],
    keyboardType: TextInputType.emailAddress,
  ),
),
</code>```

);

The inputFormatter that I'm using is also a RegExp:

```<code>static TextInputFormatter emailRegex = BlacklistingTextInputFormatter(RegExp(r'[!$#<>?":` ~;[\]\\|=+)(*&^%A-Z]'));
</code>```

After finishing the form, when I'm applying validation check on the email, the emojis are being accepted as valid input as well. The code for email validation is as follows:

```<code>bool isEmailValid(BuildContext context, String email) {
    Pattern patternEmail =
        r'^(([^<>()[\]\\.,;:\s@\"]+(\.[^<>()[\]\\.,;:\s@\"]+)*)|(\".+\"))@((\[[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\])|(([a-zA-Z\-0-9]+\.)+[a-zA-Z]{2,}))$';
    RegExp regexEmail = new RegExp(patternEmail);
    if (!regexEmail.hasMatch(email)) {
      return false;
    }
    if (email.isEmpty) {
      return false;
    }
    return true;
  }
</code>```

Is there any problem in the Regex pattern? Did I miss something out?

答:
Please try this to restrict entering emojis in email text field</p>
```<code>inputFormatters: [
              FilteringTextInputFormatter.deny(RegExp(
                  r'(\u00a9|\u00ae|[\u2000-\u3300]|\ud83c[\ud000-\udfff]|\ud83d[\ud000-\udfff]|\ud83e[\ud000-\udfff])')),
            ],
</code>```

Title: Email field is accepting emojis

Body:
I'm using RegExp to validate email in one of my Flutter projects. Apparently, I'm able to insert, both by typing and copy-pasting, emojis in the email field. Below is the code for the email field:

Container(
  child: Theme(
    data: ThemeData(
        primaryColor: backgroundColor,
        hintColor: hintTextColor,
        primarySwatch: backgroundColorMaterial),
    child: TextFormField(
      controller: provider.emailController,
      border: outlineBorderGrey,
      hintText: Translations.of(context).getEmail,
      labelText: Translations.of(context).getEmail,
      prefixIcon: IconButton(
        icon: provider.emailvalid ? emailFieldLogo : emailFieldLogoRed,
      ),
    ),
    inputFormatters: [ValidateHelper.emailRegex],
    keyboardType: TextInputType.emailAddress,
  ),
),

);

The inputFormatter that I'm using is also a RegExp:

static TextInputFormatter emailRegex = BlacklistingTextInputFormatter(RegExp(r'[!$#<>?":` ~;[\]\\|=+)(*&^%A-Z]'));

After finishing the form, when I'm applying validation check on the email, the emojis are being accepted as valid input as well. The code for email validation is as follows:

bool isEmailValid(BuildContext context, String email) {
    Pattern patternEmail =
        r'^(([^<>()[\]\\.,;:\s@\"]+(\.[^<>()[\]\\.,;:\s@\"]+)*)|(\".+\"))@((\[[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\])|(([a-zA-Z\-0-9]+\.)+[a-zA-Z]{2,}))$';
    RegExp regexEmail = new RegExp(patternEmail);
    if (!regexEmail.hasMatch(email)) {
      return false;
    }
    if (email.isEmpty) {
      return false;
    }
    return true;
  }

Is there any problem in the Regex pattern? Did I miss something out?

Body:
Please try this to restrict entering emojis in email text field

inputFormatters: [
              FilteringTextInputFormatter.deny(RegExp(
                  r'(\u00a9|\u00ae|[\u2000-\u3300]|\ud83c[\ud000-\udfff]|\ud83d[\ud000-\udfff]|\ud83e[\ud000-\udfff])')),
            ],


问:
TypeScript's type 'string | string[]' is not assignable to type 'string', what is the 'string | string[]' type? How to cast them to string?
When I do TypeScript:

```<code>let token = req.headers['x-access-token'] || req.headers['authorization'] as string;
</code>```

I have the following error:

```<code>Argument of type 'string | string[]' is not assignable to parameter of type 'string'
</code>```

Does anyone know what string | string[] type is? I mean if I want to use logical 'or' of two strings in TypeScript. How to do it?

And how to cast string | string[] to string type?

答:
Clarifications

Any one know what is 'string | string[]' type? I mean if I want use logical 'or' of two string in typescript. How to do it?

string | string[] is a type union (TS Docs) which means the relative value can be either a string OR string[] (or Array<string> or an array of strings).

The logical or operator || between two variables actually produces the union of the two variable types if and only if the left operand contains a falsish type (undefined, null, number, string and boolean), otherwise produces the first variable type. The falsish type is actually configuration dependent (see note below real solution). Example:

type NonFalsishType = { prop: number };
let var1: number | undefined = 42;
let var2: string = 'var2'
let var3: NonFalsishType  = { prop: 42 };

let test1: number | string = var1 || var2;
let test2: number | string = var2 || var1;
let test3: string | NonFalsishType = var2 || var3;

// strictNullCheck = true
// string type can be omitted because NonFalsishType
// is defenitely not falsy
let test4: NonFalsishType = var3 || var2;

// strictNullCheck = false
// string not omitted because null can be assigned to var3
let test4: NonFalsishType | string/* | null*/ = var3 || var2;
```
<blockquote>
<p>And How to cast 'string | string[]' type to string type?</p>
</blockquote>
<p>The "casting" (the correct name is type assertion (TS Docs), it is a semantically different concept) can be done in different ways, the most common is achieved by using the <code>as</code> keyword, but there is also the angle brackets notation:</p>
<pre class="lang-ts prettyprint-override"><code>// as
let myHeader: string = req.headers['authorization'] as string

// angle brackets
let myHeader: string = <string>req.headers['authorization']
</code>```

Note: Type assertions do nothing at all during runtime, it will neither be compiled at all in JS code:

```<code>// TS
let myHeader: string = req.headers['authorization'] as string

// JS
var myHeader = req.headers['authorization'];
</code>```

Type assertions are just ment to instruct the TS type checker to force a type to be restricted to another, ONLY during the type checking of the compilation phase. It is like saying to the compiler "I don't care which (of the union) type the variable actually is, treat it as it would be of this specified type"

Possible Solution

Now the easisest solution is assert the string type for your variable:

// parenthesis emphasize where the assertion is applied

let token: string = (req.headers['x-access-token'] as string) ||
                    (req.headers['authorization'] as string);

let token: string = (
    req.headers['x-access-token'] ||
    req.headers['authorization']
) as string;

// no runtime differences, just saying to the TS type checker
// two different way to see the same variables
```
<p>This solution lead to different problems: what if the client sends to the server multiple <code>x-access-token/authorization</code> headers?</p>
<p>You will end up with an array in the token variable, which means that your produced code could break (eg <code>token.substr(10)</code> will produce a runtime error since arrays do not have <code>substr</code> property, which strings have).</p>
<p>Even worse if the client does not send <code>x-access-token/authorization</code> header at all (<code>undefined</code> property will break the execution with any accessor).</p>
<h3>Real solution</h3>
<p>You need to think on what you need to achieve. The TypeScript type notations are not there just for decorate your code, but actually to produce a significant quality code through type and pattern checking. You should not ignore the fact that a variable can take multiple types, otherwise you will have bugs and security issues in a production environment.</p>
<p>If your real intent is to validate an access token you should be sure that the token is non-empty <strong>AND</strong> unique in order to identify an user:</p>
<pre class="lang-ts prettyprint-override"><code>// usually is a bad practice to authorize with multiple headers
// but it does not produce significant runtime error doing this
let token: string | string[] | undefined = req.headers['x-access-token'] || req.headers['authorization'];

if (typeof(token) === 'undefined') {
    // no token passed in the header
    // token variable is of type 'undefined' in this scope

    // probably here, if the page require access, you should
    // respond with a 401 unauth code

    // you can skip this check by appending a check at
    // the end of token variable initialization like this:
    // let token: string | string[] = ... || '';
}
else if (Array.isArray(token)) {
    // multiple tokens passed in the header
    // token variable is of type 'string[]' in this scope

    // for this special case see multiple tokens notes (at the end)
}
else if (!token) {
    // the header contains the token but is actually an empty string
    // token variable is of type 'string' in this scope

    // same as undefined token, if the page require access, you should
    // respond with a 401 unauth code
}
else {
    // the header contains a non-empty string token
    // token variable is of type 'string' also in this scope

    // validate your token and respond by consequence (200 OK / 401 unath)
}
</code>```

Note:

req.headers[key], as stated by @TmTron's answer, is of type string | string[] | undefined, but undefined is not mentioned in the union type in the error. This because it is possible to configure TypeScript (in the tsconfig.json or by passing the proper command line argument) to ignore falsy values during the type checking (like false, null and undefined). The option is strictNullCheck (TS Docs), and by default is set to false (meaning that TS will ignore the falsy values while type checking). If you put that option to true the error would become:

```<code>Argument of type 'string | string[] | undefined' is not assignable to parameter of type 'string'
</code>```

forcing you to take in account also the undefined case (which in my experience usually prevents many and very many bugs)

Multiple Tokens Notes

The case of multiple tokens is more fuzzy, you should take an agreement
with your intents:

always reject multiple tokens - best, suggested and common practice (401 unath)

reject multiple tokens if they refer to different users - if there is the possibility, like ignore and drop elasped tokens but check they refer to the same user (validate token - 200 OK / 401 unath)

accept as valid only the first token: just use token = token[0] || '' and remove the else in the subsequent else if (becoming if (!token) ...) - still viable but not really a clean solution

Pratically there are some authentication techniques which make use of extended tokens (coma separated tokens), but are very scarce in the daily usage of security implementations.

Also note that teoretically a client should not send multiple headers with the same name, but actually a malicious user could simulate a call to your server with repeated headers in order to exploit some of the vulnerabilities of your application. And this is the reason why you should validate also the array case.

Body:
When I do TypeScript:

let token = req.headers['x-access-token'] || req.headers['authorization'] as string;

I have the following error:

Argument of type 'string | string[]' is not assignable to parameter of type 'string'

Does anyone know what string | string[] type is? I mean if I want to use logical 'or' of two strings in TypeScript. How to do it?

And how to cast string | string[] to string type?

Body:
Clarifications

Any one know what is 'string | string[]' type? I mean if I want use logical 'or' of two string in typescript. How to do it?

string | string[] is a type union (TS Docs) which means the relative value can be either a string OR string[] (or Array<string> or an array of strings).

The logical or operator || between two variables actually produces the union of the two variable types if and only if the left operand contains a falsish type (undefined, null, number, string and boolean), otherwise produces the first variable type. The falsish type is actually configuration dependent (see note below real solution). Example:

type NonFalsishType = { prop: number };
let var1: number | undefined = 42;
let var2: string = 'var2'
let var3: NonFalsishType  = { prop: 42 };

let test1: number | string = var1 || var2;
let test2: number | string = var2 || var1;
let test3: string | NonFalsishType = var2 || var3;

// strictNullCheck = true
// string type can be omitted because NonFalsishType
// is defenitely not falsy
let test4: NonFalsishType = var3 || var2;

// strictNullCheck = false
// string not omitted because null can be assigned to var3
let test4: NonFalsishType | string/* | null*/ = var3 || var2;

And How to cast 'string | string[]' type to string type?

The "casting" (the correct name is type assertion (TS Docs), it is a semantically different concept) can be done in different ways, the most common is achieved by using the as keyword, but there is also the angle brackets notation:

// as
let myHeader: string = req.headers['authorization'] as string

// angle brackets
let myHeader: string = <string>req.headers['authorization']

Note: Type assertions do nothing at all during runtime, it will neither be compiled at all in JS code:

// TS
let myHeader: string = req.headers['authorization'] as string

// JS
var myHeader = req.headers['authorization'];

Type assertions are just ment to instruct the TS type checker to force a type to be restricted to another, ONLY during the type checking of the compilation phase. It is like saying to the compiler "I don't care which (of the union) type the variable actually is, treat it as it would be of this specified type"

Possible Solution

Now the easisest solution is assert the string type for your variable:

// parenthesis emphasize where the assertion is applied

let token: string = (req.headers['x-access-token'] as string) ||
                    (req.headers['authorization'] as string);

let token: string = (
    req.headers['x-access-token'] ||
    req.headers['authorization']
) as string;

// no runtime differences, just saying to the TS type checker
// two different way to see the same variables

This solution lead to different problems: what if the client sends to the server multiple x-access-token/authorization headers?

You will end up with an array in the token variable, which means that your produced code could break (eg token.substr(10) will produce a runtime error since arrays do not have substr property, which strings have).

Even worse if the client does not send x-access-token/authorization header at all (undefined property will break the execution with any accessor).

Real solution

You need to think on what you need to achieve. The TypeScript type notations are not there just for decorate your code, but actually to produce a significant quality code through type and pattern checking. You should not ignore the fact that a variable can take multiple types, otherwise you will have bugs and security issues in a production environment.

If your real intent is to validate an access token you should be sure that the token is non-empty AND unique in order to identify an user:

// usually is a bad practice to authorize with multiple headers
// but it does not produce significant runtime error doing this
let token: string | string[] | undefined = req.headers['x-access-token'] || req.headers['authorization'];

if (typeof(token) === 'undefined') {
    // no token passed in the header
    // token variable is of type 'undefined' in this scope

    // probably here, if the page require access, you should
    // respond with a 401 unauth code

    // you can skip this check by appending a check at
    // the end of token variable initialization like this:
    // let token: string | string[] = ... || '';
}
else if (Array.isArray(token)) {
    // multiple tokens passed in the header
    // token variable is of type 'string[]' in this scope

    // for this special case see multiple tokens notes (at the end)
}
else if (!token) {
    // the header contains the token but is actually an empty string
    // token variable is of type 'string' in this scope

    // same as undefined token, if the page require access, you should
    // respond with a 401 unauth code
}
else {
    // the header contains a non-empty string token
    // token variable is of type 'string' also in this scope

    // validate your token and respond by consequence (200 OK / 401 unath)
}

Note:

req.headers[key], as stated by @TmTron's answer, is of type string | string[] | undefined, but undefined is not mentioned in the union type in the error. This because it is possible to configure TypeScript (in the tsconfig.json or by passing the proper command line argument) to ignore falsy values during the type checking (like false, null and undefined). The option is strictNullCheck (TS Docs), and by default is set to false (meaning that TS will ignore the falsy values while type checking). If you put that option to true the error would become:

Argument of type 'string | string[] | undefined' is not assignable to parameter of type 'string'

forcing you to take in account also the undefined case (which in my experience usually prevents many and very many bugs)

Multiple Tokens Notes

The case of multiple tokens is more fuzzy, you should take an agreement
with your intents:

always reject multiple tokens - best, suggested and common practice (401 unath)

reject multiple tokens if they refer to different users - if there is the possibility, like ignore and drop elasped tokens but check they refer to the same user (validate token - 200 OK / 401 unath)

accept as valid only the first token: just use token = token[0] || '' and remove the else in the subsequent else if (becoming if (!token) ...) - still viable but not really a clean solution

Pratically there are some authentication techniques which make use of extended tokens (coma separated tokens), but are very scarce in the daily usage of security implementations.

Also note that teoretically a client should not send multiple headers with the same name, but actually a malicious user could simulate a call to your server with repeated headers in order to exploit some of the vulnerabilities of your application. And this is the reason why you should validate also the array case.


问:
Python - How can I check if a CSV file has a comma or a semicolon as a separator?
I have a bunch of CSV files that I would like to read with Python Pandas. Some of them have a comma as a delimiter, hence I use the following command to read them:

import pandas as pd
df = pd.read_csv('file_with_commas.csv')
```
<p>However I have others CSVs that have a semicolon as a delimiter. Hence, since the default separator is the comma, I now need to specify it and therefore use the following command:</p>
<pre class="lang-py prettyprint-override"><code>import pandas as pd
df = pd.read_csv('file_with_semicolons.csv', sep=';')
</code>```

I would like to write a piece of code that recognises if the CSV file has a comma or a semicolon as a delimiter (before I read it) so that I do not have to change the code every time. How can this be done?

Note: I have checked this similar question on Stack Overflow but it is helpless since it is applicable to R, rather than Python.

答:
Use sep=None

```<code>df = pd.read_csv('some_file.csv', sep=None)
</code>```

From the docs

sep str, default ‘,’

Delimiter to use. If sep is None, the C engine cannot automatically detect the separator, but the Python parsing engine can,
meaning the latter will be used and automatically detect the separator
by Python’s builtin sniffer tool, csv.Sniffer. In addition,
separators longer than 1 character and different from '\s+' will be
interpreted as regular expressions and will also force the use of the
Python parsing engine. Note that regex delimiters are prone to
ignoring quoted data. Regex example: '\r\t'

.

Body:
I have a bunch of CSV files that I would like to read with Python Pandas. Some of them have a comma as a delimiter, hence I use the following command to read them:

import pandas as pd
df = pd.read_csv('file_with_commas.csv')

However I have others CSVs that have a semicolon as a delimiter. Hence, since the default separator is the comma, I now need to specify it and therefore use the following command:

import pandas as pd
df = pd.read_csv('file_with_semicolons.csv', sep=';')

I would like to write a piece of code that recognises if the CSV file has a comma or a semicolon as a delimiter (before I read it) so that I do not have to change the code every time. How can this be done?

Note: I have checked this similar question on Stack Overflow but it is helpless since it is applicable to R, rather than Python.

Body:
Use sep=None

df = pd.read_csv('some_file.csv', sep=None)

From the docs

sep str, default ‘,’

Delimiter to use. If sep is None, the C engine cannot automatically detect the separator, but the Python parsing engine can,
meaning the latter will be used and automatically detect the separator
by Python’s builtin sniffer tool, csv.Sniffer. In addition,
separators longer than 1 character and different from '\s+' will be
interpreted as regular expressions and will also force the use of the
Python parsing engine. Note that regex delimiters are prone to
ignoring quoted data. Regex example: '\r\t'

.


问:
How to process the redirect in post method using HttpClient?
In My App , I POST a xml file to the server , but sometimes the server will send back 302 and then redirect .

However , after the redirecting the method become GET , not POST, and my data in xml file can't deliver to server.

And finally the status code I got is 404.

Is there some way to process the redirect by myself ? Can I do something when the redirecting is happening?

Anyone can help? THX.!

答:
From RFC 2616:

If the 302 status code is received in response to a request other than
  GET or HEAD, the user agent MUST NOT automatically redirect the
  request unless it can be confirmed by the user, since this might
  change the conditions under which the request was issued.

Are you sure your server isn't using the 'POST, redirect, GET' idiom?

You can disable automatic following of redirects in Apache HTTP client. For example:

```<code>_httpClient = new DefaultHttpClient();
_httpClient.getParams().setParameter(
    ClientPNames.HANDLE_REDIRECTS, Boolean.FALSE);
</code>```

Body:
From RFC 2616:

If the 302 status code is received in response to a request other than
  GET or HEAD, the user agent MUST NOT automatically redirect the
  request unless it can be confirmed by the user, since this might
  change the conditions under which the request was issued.

Are you sure your server isn't using the 'POST, redirect, GET' idiom?

You can disable automatic following of redirects in Apache HTTP client. For example:

_httpClient = new DefaultHttpClient();
_httpClient.getParams().setParameter(
    ClientPNames.HANDLE_REDIRECTS, Boolean.FALSE);


问:
Calculating gain or loss in a partition SQL
With SQL partitions min and max values are easy to find, but how is Gain or Loss determined over a partition?

This brings in the time element to compare min and max. If max occurs later in time than min, that would be a "Gain".  If min occurs later, that would be a "Loss".

How might the GainorLoss column be calculated?

```<code>CREATE TABLE Weights (id int, date date, person varchar(40), Weight int);

INSERT INTO Weights VALUES (1, '2022-09-01', 'Alice', 100);
INSERT INTO Weights VALUES (2, '2022-10-01', 'Alice', 105);
INSERT INTO Weights VALUES (3, '2022-11-01', 'Alice', 110);
INSERT INTO Weights VALUES (4, '2022-12-01', 'Alice', 115);
INSERT INTO Weights VALUES (5, '2022-09-01', 'Peter', 150);
INSERT INTO Weights VALUES (6, '2022-10-01', 'Peter', 145);
INSERT INTO Weights VALUES (7, '2022-11-01', 'Peter', 140);
INSERT INTO Weights VALUES (8, '2022-12-01', 'Peter', 135);

select
 person
 , date
 , weight
 , min(Weight) OVER (PARTITION BY person) as minWeight
 , max(Weight) OVER (PARTITION BY person) as maxWeight
 --if max weight occurs after min weight, then "Gain" ELSE "Loss" AS GainorLoss
 from weights
</code>```

Desired output:

person
date
weight
minWeight
maxWeight
GainorLoss

Alice
2022-09-01
100
100
120
Gain

Alice
2022-10-01
105
100
120
Gain

Alice
2022-11-01
110
100
120
Gain

Alice
2022-12-01
120
100
120
Gain

Peter
2022-09-01
150
135
150
Loss

Peter
2022-10-01
145
135
150
Loss

Peter
2022-11-01
140
135
150
Loss

Peter
2022-12-01
135
135
150
Loss

答:
I think the result would be more accurate if you measure the original weight with the current weight.

Or you can measure the status from the prior weight and the current weight.

It's up to you to choose, or you could just use both methods, they can be combined off course.

And I also added a resulttype for when the weight did not changed, when there is no gain and no loss

This method uses the original weight and the current weight to determine the gain-or-loss status

```<code>declare @Weights TABLE (id int, [date] date, person varchar(40), Weight int)

INSERT INTO @Weights values
(1, '2022-09-01', 'Alice', 100), (2, '2022-10-01', 'Alice', 105),
(3, '2022-11-01', 'Alice', 110), (4, '2022-12-01', 'Alice', 115),
(5, '2022-09-01', 'Peter', 150), (6, '2022-10-01', 'Peter', 145),
(7, '2022-11-01', 'Peter', 140), (8, '2022-12-01', 'Peter', 135)

select t.person,
       t.[date],
       t.weight,
       t.minWeight,
       t.maxWeight,
       t.Original,
       case when t.Original > t.weight then 'Loss'
            when t.Original < t.weight then 'Gain'
            else 'Unchanged'
       end as GainOrLoss
from   ( select  w.person,
                 w.[date],
                 w.weight,
                 min(w.Weight) OVER (PARTITION BY w.person) as minWeight,
                 max(w.Weight) OVER (PARTITION BY w.person) as maxWeight,
                 FIRST_VALUE(w.Weight) OVER (PARTITION BY person ORDER BY [date], id) as Original
         from    @weights w
       ) t

</code>```

with this result

```<code>-------|----------|--------|-----------|-----------|--------|---------
person |date      |weight  |minWeight  |maxWeight  |Original GainOrLoss
-------|----------|--------|-----------|-----------|--------|---------
Alice  |2022-09-01| 100    |100        |115        |100     |Unchanged
Alice  |2022-10-01| 105    |100        |115        |100     |Gain
Alice  |2022-11-01| 110    |100        |115        |100     |Gain
Alice  |2022-12-01| 115    |100        |115        |100     |Gain
Peter  |2022-09-01| 150    |135        |150        |150     |Unchanged
Peter  |2022-10-01| 145    |135        |150        |150     |Loss
Peter  |2022-11-01| 140    |135        |150        |150     |Loss
Peter  |2022-12-01| 135    |135        |150        |150     |Loss
</code>```

You can test and change is in this DBFiddle

EDIT

If you want to see the weight changes with regards to the prior weight, you can use the LAG funtion.

In my option this would be the best method to follow up someone's weight change.

This method uses the prior weight and the current weight to determine the gain-or-loss status

```<code>select t.person,
       t.[date],
       t.priorWeight,
       t.weight,
       case when t.priorWeight > t.weight then 'Loss'
            when t.priorWeight < t.weight then 'Gain'
            else 'nochange'
       end as GainOrLoss,
       t.minWeight,
       t.maxWeight
from   ( select  w.person,
                 w.[date],
                 w.weight,
                 min(w.Weight) OVER (PARTITION BY w.person) as minWeight,
                 max(w.Weight) OVER (PARTITION BY w.person) as maxWeight,
                 lag(w.Weight) over (partition by person order by [date]) as priorWeight
         from    @weights w
       ) t
</code>```
```<code>-------|----------|------------|-------|----------|---------|---------
person |date      |priorWeight |weight |GainOrLoss|minWeight|maxWeight
-------|----------|------------|-------|----------|---------|---------
Alice  |2022-09-01|            |100    |nochange  |100      |115
Alice  |2022-10-01|100         |105    |Gain      |100      |115
Alice  |2022-11-01|105         |110    |Gain      |100      |115
Alice  |2022-12-01|110         |115    |Gain      |100      |115
Peter  |2022-09-01|            |150    |nochange  |135      |150
Peter  |2022-10-01|150         |145    |Loss      |135      |150
Peter  |2022-11-01|145         |140    |Loss      |135      |150
Peter  |2022-12-01|140         |135    |Loss      |135      |150
</code>```

And again a DBFiddle you can use to play with this query

You can combine the 2 methods offcourse

Body:
With SQL partitions min and max values are easy to find, but how is Gain or Loss determined over a partition?

This brings in the time element to compare min and max. If max occurs later in time than min, that would be a "Gain".  If min occurs later, that would be a "Loss".

How might the GainorLoss column be calculated?

CREATE TABLE Weights (id int, date date, person varchar(40), Weight int);

INSERT INTO Weights VALUES (1, '2022-09-01', 'Alice', 100);
INSERT INTO Weights VALUES (2, '2022-10-01', 'Alice', 105);
INSERT INTO Weights VALUES (3, '2022-11-01', 'Alice', 110);
INSERT INTO Weights VALUES (4, '2022-12-01', 'Alice', 115);
INSERT INTO Weights VALUES (5, '2022-09-01', 'Peter', 150);
INSERT INTO Weights VALUES (6, '2022-10-01', 'Peter', 145);
INSERT INTO Weights VALUES (7, '2022-11-01', 'Peter', 140);
INSERT INTO Weights VALUES (8, '2022-12-01', 'Peter', 135);

select
 person
 , date
 , weight
 , min(Weight) OVER (PARTITION BY person) as minWeight
 , max(Weight) OVER (PARTITION BY person) as maxWeight
 --if max weight occurs after min weight, then "Gain" ELSE "Loss" AS GainorLoss
 from weights

Desired output:

person
date
weight
minWeight
maxWeight
GainorLoss

Alice
2022-09-01
100
100
120
Gain

Alice
2022-10-01
105
100
120
Gain

Alice
2022-11-01
110
100
120
Gain

Alice
2022-12-01
120
100
120
Gain

Peter
2022-09-01
150
135
150
Loss

Peter
2022-10-01
145
135
150
Loss

Peter
2022-11-01
140
135
150
Loss

Peter
2022-12-01
135
135
150
Loss

Body:
I think the result would be more accurate if you measure the original weight with the current weight.

Or you can measure the status from the prior weight and the current weight.

It's up to you to choose, or you could just use both methods, they can be combined off course.

And I also added a resulttype for when the weight did not changed, when there is no gain and no loss

This method uses the original weight and the current weight to determine the gain-or-loss status

declare @Weights TABLE (id int, [date] date, person varchar(40), Weight int)

INSERT INTO @Weights values
(1, '2022-09-01', 'Alice', 100), (2, '2022-10-01', 'Alice', 105),
(3, '2022-11-01', 'Alice', 110), (4, '2022-12-01', 'Alice', 115),
(5, '2022-09-01', 'Peter', 150), (6, '2022-10-01', 'Peter', 145),
(7, '2022-11-01', 'Peter', 140), (8, '2022-12-01', 'Peter', 135)

select t.person,
       t.[date],
       t.weight,
       t.minWeight,
       t.maxWeight,
       t.Original,
       case when t.Original > t.weight then 'Loss'
            when t.Original < t.weight then 'Gain'
            else 'Unchanged'
       end as GainOrLoss
from   ( select  w.person,
                 w.[date],
                 w.weight,
                 min(w.Weight) OVER (PARTITION BY w.person) as minWeight,
                 max(w.Weight) OVER (PARTITION BY w.person) as maxWeight,
                 FIRST_VALUE(w.Weight) OVER (PARTITION BY person ORDER BY [date], id) as Original
         from    @weights w
       ) t

with this result

-------|----------|--------|-----------|-----------|--------|---------
person |date      |weight  |minWeight  |maxWeight  |Original GainOrLoss
-------|----------|--------|-----------|-----------|--------|---------
Alice  |2022-09-01| 100    |100        |115        |100     |Unchanged
Alice  |2022-10-01| 105    |100        |115        |100     |Gain
Alice  |2022-11-01| 110    |100        |115        |100     |Gain
Alice  |2022-12-01| 115    |100        |115        |100     |Gain
Peter  |2022-09-01| 150    |135        |150        |150     |Unchanged
Peter  |2022-10-01| 145    |135        |150        |150     |Loss
Peter  |2022-11-01| 140    |135        |150        |150     |Loss
Peter  |2022-12-01| 135    |135        |150        |150     |Loss

You can test and change is in this DBFiddle

EDIT

If you want to see the weight changes with regards to the prior weight, you can use the LAG funtion.

In my option this would be the best method to follow up someone's weight change.

This method uses the prior weight and the current weight to determine the gain-or-loss status

select t.person,
       t.[date],
       t.priorWeight,
       t.weight,
       case when t.priorWeight > t.weight then 'Loss'
            when t.priorWeight < t.weight then 'Gain'
            else 'nochange'
       end as GainOrLoss,
       t.minWeight,
       t.maxWeight
from   ( select  w.person,
                 w.[date],
                 w.weight,
                 min(w.Weight) OVER (PARTITION BY w.person) as minWeight,
                 max(w.Weight) OVER (PARTITION BY w.person) as maxWeight,
                 lag(w.Weight) over (partition by person order by [date]) as priorWeight
         from    @weights w
       ) t

-------|----------|------------|-------|----------|---------|---------
person |date      |priorWeight |weight |GainOrLoss|minWeight|maxWeight
-------|----------|------------|-------|----------|---------|---------
Alice  |2022-09-01|            |100    |nochange  |100      |115
Alice  |2022-10-01|100         |105    |Gain      |100      |115
Alice  |2022-11-01|105         |110    |Gain      |100      |115
Alice  |2022-12-01|110         |115    |Gain      |100      |115
Peter  |2022-09-01|            |150    |nochange  |135      |150
Peter  |2022-10-01|150         |145    |Loss      |135      |150
Peter  |2022-11-01|145         |140    |Loss      |135      |150
Peter  |2022-12-01|140         |135    |Loss      |135      |150

And again a DBFiddle you can use to play with this query

You can combine the 2 methods offcourse


问:
The named parameter isn't defined (data persistence)
There is my error , I want to solve this problem
enter image description here
The named parameter 'itemCount' isn't defined.
The named parameter 'itemBuilder' isn't defined.</p>

答: You are using the default constructor that has different named parameters, you need to use ListView.builder() to use those named arguments.


问:
"No junit.jar" error in Intellij when right clicking a folder, but not when running individual classes of tests
My Spring boot application has several tests classes.

When right-clicking a test class, and selecting the option to Run XYZtest it works with no problem.

But when selecting the folder that contains that class and selecting Run test in com.example.my I get an error of No junit.jar:

When running all the tests from mvn they run with no problems.

Following some suggestions, I added the junit.jar specifically in the Library section, but it didn't help:

答:
I met this problem, this is how I soloved it:

Context:

SpringBoot application

Use maven to manage multiple modules

Add junit's maven dependency in root POM's dependencyManagement(rather than dependencies, their differences can be found here)

Intend to test class or folder inside one of the root module's child module

PS: If your situation does not match the context above, this solution may not solve your problem.

Steps

right click at the class or folder you want to test:

Choose More Run/Debug -> Modify Run Configuration

Change the module option to the one you want to test from root module


问:
$(TargetDir) replacement for SDK-style projects (analogue to "$(MSBuildProjectDirectory)\" for "$(ProjectDir)")
I have an old project in non-SDK-style format generated by Visual Studio. It contains a post-build event in which $(ProjectDir) and $(TargetDir) are used.

I am currently transforming the project into a new SDK-style project (csproj file).
If I just turn that post build event into a Target Exec Command, I get errors. After prefixing the command with echo I could see why: The values $(ProjectDir) and $(TargetDir) were both empty.

I figured out that replacing $(ProjectDir) by $(MSBuildProjectDirectory)\ gives the desired result, but what is the equivalent for $(TargetDir)?

Note that I am not using Visual Studio for the new SDK-style project. I am using Visual Studio Code. It seems that Visual Studio sets values for $(ProjectDir)/$(TargetDir)/others, but Visual Studio Code does not. I build my project using dotnet build.

答:
Seems I found the answer here:

The value of TargetDir is computed as the full absolute path of whatever you specify as the Output Path for your project, which is stored in the OutputPath property directly in your project file (.CSPROJ, .VBPROJ, etc.).

So I believe $(TargetDir)would be $(MSBuildProjectDirectory)\$(OutputPath).