问:
Do a form submit calling a function instead create specific submit on its id
I did on a project many forms with its "" in the part of page (generated by php) that add specific function to it per form id and are working, for example:

```<code>$("#fregistrazione").submit(function(event){
...
}
</code>```

I did the same with an html part loaded with ajax request but is not working.
I thinked to do in a different way with the same function called by many form submit, instead having one different defined for any form on any form submit, call a function with additional parameter that do the specific form things with less code duplication but I'm unable to have it working.
I did many try, for example:

```<code><form id="f_man-marker_edit-marker" method="post" action="#" onsubmit="TM.editMarker(this)">
...

...
TM.editMarker = function(rform){

    // Abort any pending request
    if (request) { request.abort(); }

    let form = $(rform);

    // Let's select and cache all the fields
    let inputs = form.find("input, select, button, textarea");

    // Serialize the data in the form
    let serializedData = form.serialize();

    // Let's disable the inputs for the duration of the Ajax request.
    // Note: we disable elements AFTER the form data has been serialized.
    // Disabled form elements will not be serialized.
    inputs.prop("disabled", true);

    request = $.ajax({
        url: "ajax.php?req=man-marker_edit-marker",
        type: "post",
        data: serializedData,
        dataType: "html"
    });

    request.done(function (response){
        $("#ajaxoutput2").empty().append(response);
        $("#ResultModal2").modal("show");
    });

    request.fail(function (jqXHR, textStatus, errorThrown){
        console.error(
            "Ajax man-marker_edit-marker request failed. The following error occurred: "+
            textStatus, errorThrown
        );
    });

    request.always(function () {
        inputs.prop("disabled", false);
    });

};

</code>```

but on submit reload the page with parameters as "get" in url and didn't execute the edit marker function.
Can someone please tell me what I did wrong and how to do a correct call of a function from the form submit instead do a .submit on any form id containing dozens of duplicate lines for each form and not working if generated by a code that is received through ajax request?
Thanks for any reply and sorry for my bad english.

EDIT:
I did what suggested by ChrisG and I tried to add a parameter in TM.editMarker but I not found how to maintain correctly event as first parameter and add 2 other parameters.
For example adding 1 parameter:

```<code>TM.editMarker = function (e, ajax_request) {
...
</code>```

I tried (even if IDE gave me event as deprecated):

```<code>$('#f_man-marker_edit-marker').on('submit', TM.editMarker(event, 'man-marker_edit-marker'));
</code>```

And also without but in both case don't work.

EDIT2:
solved with:

```<code>$('#f_man-marker_edit-marker').on('submit', function(e){
    TM.editMarker(e, $(this), 'man-marker_edit-marker');
});

...

TM.editMarker = function (e, form, ajax_request) {
...
</code>```

but I'm open to better solutions.

答:
Simple Answer:

You manipulated the DOM, so your selector is not there yet on event-binding.
Use a parent selector thats already there like document

```<code>$(document).on("submit", "#fregistrazione", function(event){
   event.preventDefault(); // stop the form submitting if needed
...
});
</code>```

this way it will work

Body:
I did on a project many forms with its "" in the part of page (generated by php) that add specific function to it per form id and are working, for example:

$("#fregistrazione").submit(function(event){
...
}

I did the same with an html part loaded with ajax request but is not working.
I thinked to do in a different way with the same function called by many form submit, instead having one different defined for any form on any form submit, call a function with additional parameter that do the specific form things with less code duplication but I'm unable to have it working.
I did many try, for example:

<form id="f_man-marker_edit-marker" method="post" action="#" onsubmit="TM.editMarker(this)">
...

...
TM.editMarker = function(rform){

    // Abort any pending request
    if (request) { request.abort(); }

    let form = $(rform);

    // Let's select and cache all the fields
    let inputs = form.find("input, select, button, textarea");

    // Serialize the data in the form
    let serializedData = form.serialize();

    // Let's disable the inputs for the duration of the Ajax request.
    // Note: we disable elements AFTER the form data has been serialized.
    // Disabled form elements will not be serialized.
    inputs.prop("disabled", true);

    request = $.ajax({
        url: "ajax.php?req=man-marker_edit-marker",
        type: "post",
        data: serializedData,
        dataType: "html"
    });

    request.done(function (response){
        $("#ajaxoutput2").empty().append(response);
        $("#ResultModal2").modal("show");
    });

    request.fail(function (jqXHR, textStatus, errorThrown){
        console.error(
            "Ajax man-marker_edit-marker request failed. The following error occurred: "+
            textStatus, errorThrown
        );
    });

    request.always(function () {
        inputs.prop("disabled", false);
    });

};

but on submit reload the page with parameters as "get" in url and didn't execute the edit marker function.
Can someone please tell me what I did wrong and how to do a correct call of a function from the form submit instead do a .submit on any form id containing dozens of duplicate lines for each form and not working if generated by a code that is received through ajax request?
Thanks for any reply and sorry for my bad english.

EDIT:
I did what suggested by ChrisG and I tried to add a parameter in TM.editMarker but I not found how to maintain correctly event as first parameter and add 2 other parameters.
For example adding 1 parameter:

TM.editMarker = function (e, ajax_request) {
...

I tried (even if IDE gave me event as deprecated):

$('#f_man-marker_edit-marker').on('submit', TM.editMarker(event, 'man-marker_edit-marker'));

And also without but in both case don't work.

EDIT2:
solved with:

$('#f_man-marker_edit-marker').on('submit', function(e){
    TM.editMarker(e, $(this), 'man-marker_edit-marker');
});

...

TM.editMarker = function (e, form, ajax_request) {
...

but I'm open to better solutions.

Body:
Simple Answer:

You manipulated the DOM, so your selector is not there yet on event-binding.
Use a parent selector thats already there like document

$(document).on("submit", "#fregistrazione", function(event){
   event.preventDefault(); // stop the form submitting if needed
...
});

this way it will work


来源: stackexchange

问:
New session files overwriting old session files even though a separate directory is created (Flask)
I have a Flask app where I need to store temporary files for different instances of the app inside a folder whose name is the time at which the app was opened.
I have an index function as follows:

```<code>@app.route('/')
def index():
    session["now"] = time.time() * 100.0
    os.mkdir(str(session["now"]))
</code>```

The above code makes a directory where the name of the directory is the the time when the app was opened.
When I open the app on two separate tabs on Chrome, two different directories are made as expected.

However, there is one issue.
I have a text area in my UI whose text needs to be saved in a text file in the directory created above. I have used a POST request to send the data.
The following is the Flask-Python method:

```<code>@app.route('/rt3/', methods=['POST'])
def fn3():
    x = request.get_json()
    data = x['textbox1']
    f = open("./" + str(session["now"]) + "/mytext.txt", "w")
    f.write(data)
    f.close()
</code>```

The issue is this: No matter on which Chrome tab I click the "run" button on, the text file always gets saved in the directory of the session created later. Hence the same text file is getting overwritten again and again.
Since I have used session variables, shouldn't it save in the directory of its own session?
Why is session variable getting overwritten?

答:
This is perfectly expected. When running Flask locally, you most probably use one single process/instance which processes all your requests (multithreaded by default in newer Flask versions, so you can process multiple requests in parallel).

So be aware that you DON'T have different instances of the app but only one, no matter how many Chrome tabs you open. You'd need to use gunicorn or any other WSGI to spawn multiple instances and make them completely independent.

In your example, when you do session["now"] = time.time() * 100.0 you simply override every time the content of session["now"]. So, when accessing it from fn3(), you'll obviously get the last version (last override).

Now, if you REALLY want to achieve this, you'd need to pass an explicit "directory" identifier (not necessarily based on time) in every request so you can use it to create the directory and write files to it.

EDIT (20.02.2020)

After a bit more research, Flask session's are stored in a cookie on client side (see doc)

As a consequence, when you call session from 2 requests coming from 2 different tabs (from the same browser 'instance'), you access the same cookie, thus the same value. However, if you open another browser (or a new Chrome Incognito tab for example), you'll have a new cookie so you'll use a different session value.

ContentLicense: CC BY-SA 4.0

Body:
I have a Flask app where I need to store temporary files for different instances of the app inside a folder whose name is the time at which the app was opened.
I have an index function as follows:

@app.route('/')
def index():
    session["now"] = time.time() * 100.0
    os.mkdir(str(session["now"]))

The above code makes a directory where the name of the directory is the the time when the app was opened.
When I open the app on two separate tabs on Chrome, two different directories are made as expected.

However, there is one issue.
I have a text area in my UI whose text needs to be saved in a text file in the directory created above. I have used a POST request to send the data.
The following is the Flask-Python method:

@app.route('/rt3/', methods=['POST'])
def fn3():
    x = request.get_json()
    data = x['textbox1']
    f = open("./" + str(session["now"]) + "/mytext.txt", "w")
    f.write(data)
    f.close()

The issue is this: No matter on which Chrome tab I click the "run" button on, the text file always gets saved in the directory of the session created later. Hence the same text file is getting overwritten again and again.
Since I have used session variables, shouldn't it save in the directory of its own session?
Why is session variable getting overwritten?


问:
How to verify parametr from request URL? (Selenium)
I am on that page:

```<code>http://localhost:8080/login?error=true
</code>```

How can i check is error variable contains value true?

Here is my failed try:

Error:

```<code>[info] Executing: | assertAttribute | error | true |
[info] Wait until the element is found
[error] Implicit Wait timed out after 10000ms
[error] Element erro not found
</code>```

I am using:

Selenium IDE ---> 3.16.1

Katalon Recorder ---> 4.0.0

Chrome 64-bit ---> 79.0.3945.130

I am newbie in the world of testing. Can someone help? :(

答:
Assert Attribute command is used for check of attributes of DOM element. So here you need to use js:

```<code>execute script | var url = window.location.href; return /error=true/.test(url); |flag
assert | flag | true
</code>```

Body:
I am on that page:

http://localhost:8080/login?error=true

How can i check is error variable contains value true?

Here is my failed try:

Error:

[info] Executing: | assertAttribute | error | true |
[info] Wait until the element is found
[error] Implicit Wait timed out after 10000ms
[error] Element erro not found

I am using:

Selenium IDE ---> 3.16.1

Katalon Recorder ---> 4.0.0

Chrome 64-bit ---> 79.0.3945.130

I am newbie in the world of testing. Can someone help? :(

Body:
Assert Attribute command is used for check of attributes of DOM element. So here you need to use js:

execute script | var url = window.location.href; return /error=true/.test(url); |flag
assert | flag | true


问:
pretty printing a Vec<char> with a separator
I am trying to apply join (or something similar) to a Vec<char> in order to pretty print it.

What I came up with so far is this (and this does what I want):

```<code>let vec: Vec<char> = "abcdef".chars().collect();
let sep = "-";
let vec_str: String = vec
    .iter().map(|c| c.to_string()).collect::<Vec<String>>().join(sep);
println!("{}", vec_str);  // a-b-c-d-e-f
</code>```

That seems overly complex (and allocates a Vec<String> that is not really needed).

I also tried to get std::slice::join to work by explicitly creating a slice:

```<code>let vec_str: String = (&vec[..]).join('-');
</code>```

but here the compiler complains:

method not found in &[char]

Is there a simpler way to create a printable String from a Vec<char> with a separator between the elements?

答:
You can use intersperse from the itertools crate.

```<code>use itertools::Itertools; // 0.8.2

fn main() {
    let vec : Vec<_> = "abcdef".chars().collect();
    let sep = '-';
    let sep_str : String = vec.iter().intersperse(&sep).collect();
    println!("{}", sep_str);
}
</code>```

Playground

Body:
I am trying to apply join (or something similar) to a Vec<char> in order to pretty print it.

What I came up with so far is this (and this does what I want):

let vec: Vec<char> = "abcdef".chars().collect();
let sep = "-";
let vec_str: String = vec
    .iter().map(|c| c.to_string()).collect::<Vec<String>>().join(sep);
println!("{}", vec_str);  // a-b-c-d-e-f

That seems overly complex (and allocates a Vec<String> that is not really needed).

I also tried to get std::slice::join to work by explicitly creating a slice:

let vec_str: String = (&vec[..]).join('-');

but here the compiler complains:

method not found in &[char]

Is there a simpler way to create a printable String from a Vec<char> with a separator between the elements?

Body:
You can use intersperse from the itertools crate.

use itertools::Itertools; // 0.8.2

fn main() {
    let vec : Vec<_> = "abcdef".chars().collect();
    let sep = '-';
    let sep_str : String = vec.iter().intersperse(&sep).collect();
    println!("{}", sep_str);
}

Playground


问:
Coding convention for adding rows to Pandas Dataframe in for loop
I'm writing a program where I want to extract data from multiple docx files and fill it into a pandas dataframe. I'm currently achieving this in a for loop like so:

```<code>cols = ["path","col1", "col2", "col3", "col4"]

def add_to_df(path):
    col1_val = extract_col1(path)
    col2_val = extract_col2(path)
    col3_val = extract_col3(path)
    col4_val = extract_col4(path)

    temp_df = pd.DataFrame(
        [[path, col1_val,col2_val,col3_val,col4_val]],
        columns=cols)
    return temp_df

df = pd.DataFrame()
for path in paths:
    df = df.append(add_to_df(path), ignore_index=True)
</code>```

Is this the best way to do this? Or is there a nicer, more accepted way? (This is just a simplified example of what I'm trying to do, the actual code looks a lot messier...)

答:
I think better is create list of lists instead many DataFrames and then pass to DataFrame constructor:

```<code>def add_to_df(path):
    col1_val = extract_col1(path)
    col2_val = extract_col2(path)
    col3_val = extract_col3(path)
    col4_val = extract_col4(path)

    temp_L = [path, col1_val,col2_val,col3_val,col4_val]
    return temp_L
</code>```

List comprehension solution:

```<code>L = [add_to_df(path) for path in paths]
</code>```

If want to use for loop:

```<code>L = []
for path in paths:
    L.append(add_to_df(path))
</code>```

```<code>df = pd.DataFrame(L, columns=cols)
</code>```

Body:
I'm writing a program where I want to extract data from multiple docx files and fill it into a pandas dataframe. I'm currently achieving this in a for loop like so:

cols = ["path","col1", "col2", "col3", "col4"]

def add_to_df(path):
    col1_val = extract_col1(path)
    col2_val = extract_col2(path)
    col3_val = extract_col3(path)
    col4_val = extract_col4(path)

    temp_df = pd.DataFrame(
        [[path, col1_val,col2_val,col3_val,col4_val]],
        columns=cols)
    return temp_df

df = pd.DataFrame()
for path in paths:
    df = df.append(add_to_df(path), ignore_index=True)

Is this the best way to do this? Or is there a nicer, more accepted way? (This is just a simplified example of what I'm trying to do, the actual code looks a lot messier...)

Body:
I think better is create list of lists instead many DataFrames and then pass to DataFrame constructor:

def add_to_df(path):
    col1_val = extract_col1(path)
    col2_val = extract_col2(path)
    col3_val = extract_col3(path)
    col4_val = extract_col4(path)

    temp_L = [path, col1_val,col2_val,col3_val,col4_val]
    return temp_L

List comprehension solution:

L = [add_to_df(path) for path in paths]

If want to use for loop:

L = []
for path in paths:
    L.append(add_to_df(path))

df = pd.DataFrame(L, columns=cols)


问:
Wrong output from code using isspace() test over index values
For some reason this code is not working correctly. I am trying to only replace dashes that do not have whitespace around them. However, dashes are still getting replaced when there is no white space.

```<code>    ls = []
    for idx, letter in enumerate(line):
        if letter == '-':
            ls.append(idx)
    for m in ls:
        if line[m-1].isspace() == True and line[m+1].isspace() == True:
            line = line[m].replace('-', ' @-@ ')
</code>```

For example:

```<code>If thieves came to you, if robbers by night -- oh, what disaster awaits you -- wouldn't they only steal until they had enough? If grape pickers came to you, wouldn't they leave some gleaning grapes?
How Esau will be ransacked! How his hidden treasures are sought out example-case!
</code>```

Gives:

```<code>If thieves came to you , if robbers by night  @-@  @-@  oh , what disaster awaits you  @-@  @-@  wouldn ' t they only steal until they had enough ? If grape pickers came to you , wouldn ' t they leave some gleaning grapes ?
How Esau will be ransacked ! How his hidden treasures are sought out example @-@ case !
</code>```

Note: there is other data tokenization going on here.

Desired output is:

```<code>If thieves came to you , if robbers by night -- oh , what disaster awaits you -- wouldn ' t they only steal until they had enough ? If grape pickers came to you , wouldn ' t they leave some gleaning grapes ?
How Esau will be ransacked ! How his hidden treasures are sought out example @-@ case !
</code>```

Thank you for your help!

答:
You're mutating the line as you're accessing it, so your indices will be wrong without manually fixing them up.

This really is a case where you'll want to use a regular expression using a lookbehind:

import re

line = "How his hidden treasures -- oh, what was the line again -- are sought out example-case!"
fixed_line = re.sub(r"(?<=[^\s])-(?=[^\s])", " @-@ ", line)
print(fixed_line)
```

<p>outputs</p>

```How his hidden treasures -- oh, what was the line again -- are sought out example @-@ case!
```

Body:
For some reason this code is not working correctly. I am trying to only replace dashes that do not have whitespace around them. However, dashes are still getting replaced when there is no white space.

    ls = []
    for idx, letter in enumerate(line):
        if letter == '-':
            ls.append(idx)
    for m in ls:
        if line[m-1].isspace() == True and line[m+1].isspace() == True:
            line = line[m].replace('-', ' @-@ ')

For example:

If thieves came to you, if robbers by night -- oh, what disaster awaits you -- wouldn't they only steal until they had enough? If grape pickers came to you, wouldn't they leave some gleaning grapes?
How Esau will be ransacked! How his hidden treasures are sought out example-case!

Gives:

If thieves came to you , if robbers by night  @-@  @-@  oh , what disaster awaits you  @-@  @-@  wouldn ' t they only steal until they had enough ? If grape pickers came to you , wouldn ' t they leave some gleaning grapes ?
How Esau will be ransacked ! How his hidden treasures are sought out example @-@ case !

Note: there is other data tokenization going on here.

Desired output is:

If thieves came to you , if robbers by night -- oh , what disaster awaits you -- wouldn ' t they only steal until they had enough ? If grape pickers came to you , wouldn ' t they leave some gleaning grapes ?
How Esau will be ransacked ! How his hidden treasures are sought out example @-@ case !

Thank you for your help!

Body:
You're mutating the line as you're accessing it, so your indices will be wrong without manually fixing them up.

This really is a case where you'll want to use a regular expression using a lookbehind:

import re

line = "How his hidden treasures -- oh, what was the line again -- are sought out example-case!"
fixed_line = re.sub(r"(?<=[^\s])-(?=[^\s])", " @-@ ", line)
print(fixed_line)

outputs

How his hidden treasures -- oh, what was the line again -- are sought out example @-@ case!


问:
Empty IQueryable that implements IAsyncEnumerable
I am looking for an empty IQueryable<T> that implements IAsyncEnumerable<T>. My current code does not work because empty Enumerable does not implement IAsyncEnumerable<T>. Thanks for any help or hint.

I have the following design:

```<code>var result = Enumerable.Empty<Foo>().AsQueryable();  // Not working!

if (condition1)
{
    IQueryable<Foo> part1 = ....;

    result = result.Concat(part1);
}

if (condition2)
{
    IQueryable<Foo> part2 = ....;

    result = result.Concat(part2);
}

return await result.ToListAsync();
</code>```

Error message:

```<code>The source IQueryable doesn't implement IAsyncEnumerable<Foo>. Only sources that implement IAsyncEnumerable can be used for Entity Framework asynchronous operations.
   at Microsoft.EntityFrameworkCore.EntityFrameworkQueryableExtensions.AsAsyncEnumerable[TSource](IQueryable`1 source)
   at Microsoft.EntityFrameworkCore.EntityFrameworkQueryableExtensions.ToListAsync[TSource](IQueryable`1 source, CancellationToken cancellationToken)
</code>```

答:
You can create an empty IAsyncEnumerable as it is described in this SO.

But if I don't think it is an ideal option since it requires referencing an additional package or implementing  AsyncEnumerable.Empty on your own.

Alternatively, you could change your code in a way that does not require an "empty" container for your expressions.

For example:

```<code>var expressions = new List<IQueryable<Foo>>();

if (condition1)
{
    IQueryable<Foo> part1 = ....;

    expressions.Add(part1);
}

if (condition2)
{
    IQueryable<Foo> part2 = ....;

    expressions.Add(part2);
}

var result = expressions.Aggregate((acc, i) => acc.Concat(i));

return await result.ToListAsync();
</code>```

Body:
I am looking for an empty IQueryable<T> that implements IAsyncEnumerable<T>. My current code does not work because empty Enumerable does not implement IAsyncEnumerable<T>. Thanks for any help or hint.

I have the following design:

var result = Enumerable.Empty<Foo>().AsQueryable();  // Not working!

if (condition1)
{
    IQueryable<Foo> part1 = ....;

    result = result.Concat(part1);
}

if (condition2)
{
    IQueryable<Foo> part2 = ....;

    result = result.Concat(part2);
}

return await result.ToListAsync();

Error message:

The source IQueryable doesn't implement IAsyncEnumerable<Foo>. Only sources that implement IAsyncEnumerable can be used for Entity Framework asynchronous operations.
   at Microsoft.EntityFrameworkCore.EntityFrameworkQueryableExtensions.AsAsyncEnumerable[TSource](IQueryable`1 source)
   at Microsoft.EntityFrameworkCore.EntityFrameworkQueryableExtensions.ToListAsync[TSource](IQueryable`1 source, CancellationToken cancellationToken)

Body:
You can create an empty IAsyncEnumerable as it is described in this SO.

But if I don't think it is an ideal option since it requires referencing an additional package or implementing  AsyncEnumerable.Empty on your own.

Alternatively, you could change your code in a way that does not require an "empty" container for your expressions.

For example:

var expressions = new List<IQueryable<Foo>>();

if (condition1)
{
    IQueryable<Foo> part1 = ....;

    expressions.Add(part1);
}

if (condition2)
{
    IQueryable<Foo> part2 = ....;

    expressions.Add(part2);
}

var result = expressions.Aggregate((acc, i) => acc.Concat(i));

return await result.ToListAsync();


问:
geth never stop syncing on rinkeby testnet
when the currentBlock becomes close to the highestBlock, it stop growing, and the highestBlock begin to grow. A while later, the currentBlock begin growing again.

I run geth with command geth --rinkeby --fast.

the highestBlock on my geth is very close to the actual number on https://www.rinkeby.io/#faucet.

```<code>> eth.syncing
{
  currentBlock: 2401750,
  highestBlock: 2401826,
  knownStates: 14219701,
  pulledStates: 14205841,
  startingBlock: 2401554
}
> eth.blockNumber
0
</code>```

logs below, seems normal:

```<code>INFO [06-04|15:34:52] Imported new state entries               count=621  elapsed=4.093ms   processed=14288823 pending=12362 retry=0   duplicate=6543 unexpected=9538
INFO [06-04|15:34:56] Imported new block headers               count=1    elapsed=713.868µs number=2401841 hash=db818c…70c969 ignored=0
INFO [06-04|15:34:57] Imported new state entries               count=1388 elapsed=9.091ms   processed=14290211 pending=12354 retry=0   duplicate=6543 unexpected=9538
INFO [06-04|15:35:00] Imported new state entries               count=768  elapsed=9.649ms   processed=14290979 pending=11944 retry=0   duplicate=6543 unexpected=9538
INFO [06-04|15:35:02] Imported new state entries               count=607  elapsed=4.707ms   processed=14291586 pending=11757 retry=0   duplicate=6543 unexpected=9538
INFO [06-04|15:35:05] Imported new state entries               count=768  elapsed=5.867ms   processed=14292354 pending=11629 retry=0   duplicate=6543 unexpected=9538
INFO [06-04|15:35:07] Imported new state entries               count=601  elapsed=4.242ms   processed=14292955 pending=11759 retry=0   duplicate=6543 unexpected=9538
INFO [06-04|15:35:09] Imported new state entries               count=601  elapsed=4.924ms   processed=14293556 pending=11479 retry=0   duplicate=6543 unexpected=9538
INFO [06-04|15:35:09] Imported new block headers               count=1    elapsed=711.566µs number=2401842 hash=39a2d8…5318ec ignored=0
INFO [06-04|15:35:10] Imported new state entries               count=384  elapsed=3.093ms   processed=14293940 pending=11375 retry=0   duplicate=6543 unexpected=9538
INFO [06-04|15:35:11] Imported new state entries               count=384  elapsed=2.660ms   processed=14294324 pending=11365 retry=0   duplicate=6543 unexpected=9538
INFO [06-04|15:35:13] Imported new state entries               count=601  elapsed=5.337ms   processed=14294925 pending=11094 retry=0   duplicate=6543 unexpected=9538
INFO [06-04|15:35:17] Imported new state entries               count=985  elapsed=6.948ms   processed=14295910 pending=11024 retry=0   duplicate=6543 unexpected=9538
INFO [06-04|15:35:20] Imported new state entries               count=602  elapsed=4.317ms   processed=14296512 pending=10940 retry=0   duplicate=6543 unexpected=9538
INFO [06-04|15:35:25] Imported new state entries               count=602  elapsed=4.380ms   processed=14297114 pending=10973 retry=0   duplicate=6543 unexpected=9538
INFO [06-04|15:35:25] Imported new block headers               count=1    elapsed=469.834µs number=2401843 hash=e8d3a7…152487 ignored=0
INFO [06-04|15:35:25] Imported new state entries               count=384  elapsed=2.758ms   processed=14297498 pending=11062 retry=0   duplicate=6543 unexpected=9538
INFO [06-04|15:35:28] Imported new state entries               count=592  elapsed=5.524ms   processed=14298090 pending=11015 retry=0   duplicate=6543 unexpected=9538
INFO [06-04|15:35:31] Imported new state entries               count=1210 elapsed=203.329ms processed=14299300 pending=10477 retry=0   duplicate=6543 unexpected=9538
INFO [06-04|15:35:37] Imported new state entries               count=1033 elapsed=1.656ms   processed=14300333 pending=10590 retry=0   duplicate=6543 unexpected=9538
</code>```

I think I've waited long enough, but the currentBlock just can't reach the highestBlock, even they are very close.

Is this common?

syncing finished. Theses numbers do not mean everything, just wait.

答:
You will have to be patient to sync a node.

It took me 60 hours to sync Rinkeby in fast mode. There were 125M state entries and the folder size was 38GB after synchronization. With time, both these numbers will grow.

You can type eth.syncing in Geth console. If you get 'False' as output, it means that syncing is finished. Otherwise you'll get various details about the blocks and the states.

By typing eth.blockNumber you will get the current block number. If the output is 0 then the syncing is not yet complete.

Here is the image when syncing was complete(all the states were pulled) and I started downloading the chain segments.
Synchronized Rinkeby

Body:
when the currentBlock becomes close to the highestBlock, it stop growing, and the highestBlock begin to grow. A while later, the currentBlock begin growing again.

I run geth with command geth --rinkeby --fast.

the highestBlock on my geth is very close to the actual number on https://www.rinkeby.io/#faucet.

> eth.syncing
{
  currentBlock: 2401750,
  highestBlock: 2401826,
  knownStates: 14219701,
  pulledStates: 14205841,
  startingBlock: 2401554
}
> eth.blockNumber
0

logs below, seems normal:

INFO [06-04|15:34:52] Imported new state entries               count=621  elapsed=4.093ms   processed=14288823 pending=12362 retry=0   duplicate=6543 unexpected=9538
INFO [06-04|15:34:56] Imported new block headers               count=1    elapsed=713.868µs number=2401841 hash=db818c…70c969 ignored=0
INFO [06-04|15:34:57] Imported new state entries               count=1388 elapsed=9.091ms   processed=14290211 pending=12354 retry=0   duplicate=6543 unexpected=9538
INFO [06-04|15:35:00] Imported new state entries               count=768  elapsed=9.649ms   processed=14290979 pending=11944 retry=0   duplicate=6543 unexpected=9538
INFO [06-04|15:35:02] Imported new state entries               count=607  elapsed=4.707ms   processed=14291586 pending=11757 retry=0   duplicate=6543 unexpected=9538
INFO [06-04|15:35:05] Imported new state entries               count=768  elapsed=5.867ms   processed=14292354 pending=11629 retry=0   duplicate=6543 unexpected=9538
INFO [06-04|15:35:07] Imported new state entries               count=601  elapsed=4.242ms   processed=14292955 pending=11759 retry=0   duplicate=6543 unexpected=9538
INFO [06-04|15:35:09] Imported new state entries               count=601  elapsed=4.924ms   processed=14293556 pending=11479 retry=0   duplicate=6543 unexpected=9538
INFO [06-04|15:35:09] Imported new block headers               count=1    elapsed=711.566µs number=2401842 hash=39a2d8…5318ec ignored=0
INFO [06-04|15:35:10] Imported new state entries               count=384  elapsed=3.093ms   processed=14293940 pending=11375 retry=0   duplicate=6543 unexpected=9538
INFO [06-04|15:35:11] Imported new state entries               count=384  elapsed=2.660ms   processed=14294324 pending=11365 retry=0   duplicate=6543 unexpected=9538
INFO [06-04|15:35:13] Imported new state entries               count=601  elapsed=5.337ms   processed=14294925 pending=11094 retry=0   duplicate=6543 unexpected=9538
INFO [06-04|15:35:17] Imported new state entries               count=985  elapsed=6.948ms   processed=14295910 pending=11024 retry=0   duplicate=6543 unexpected=9538
INFO [06-04|15:35:20] Imported new state entries               count=602  elapsed=4.317ms   processed=14296512 pending=10940 retry=0   duplicate=6543 unexpected=9538
INFO [06-04|15:35:25] Imported new state entries               count=602  elapsed=4.380ms   processed=14297114 pending=10973 retry=0   duplicate=6543 unexpected=9538
INFO [06-04|15:35:25] Imported new block headers               count=1    elapsed=469.834µs number=2401843 hash=e8d3a7…152487 ignored=0
INFO [06-04|15:35:25] Imported new state entries               count=384  elapsed=2.758ms   processed=14297498 pending=11062 retry=0   duplicate=6543 unexpected=9538
INFO [06-04|15:35:28] Imported new state entries               count=592  elapsed=5.524ms   processed=14298090 pending=11015 retry=0   duplicate=6543 unexpected=9538
INFO [06-04|15:35:31] Imported new state entries               count=1210 elapsed=203.329ms processed=14299300 pending=10477 retry=0   duplicate=6543 unexpected=9538
INFO [06-04|15:35:37] Imported new state entries               count=1033 elapsed=1.656ms   processed=14300333 pending=10590 retry=0   duplicate=6543 unexpected=9538

I think I've waited long enough, but the currentBlock just can't reach the highestBlock, even they are very close.

Is this common?

syncing finished. Theses numbers do not mean everything, just wait.


问:
how to alter table to add new column date with default value of current date?
I got confused about the alter.

I have an existing table, register and I want to add a this_date column with default value of current date. is it possible by alter? well it has already have data.

答:
On MySQL 5.7, I didn't find a way to use CURRENT_DATE or its synonyms as default.

If your application will always provide values in INSERT statements and you only need a way to add a non-null column to existing data and then set values for existing row, you can work around this by providing a fixed default for the non-null date column

```<code>ALTER TABLE MyTable ADD COLUMN MyColumn DATE DEFAULT '2020-01-01'
</code>```

and then update it to CURRENT_DATE

```<code>UPDATE MyTable SET MyColumn = CURRENT_DATE
</code>```

ContentLicense: CC BY-SA 3.0

Body:
On MySQL 5.7, I didn't find a way to use CURRENT_DATE or its synonyms as default.

If your application will always provide values in INSERT statements and you only need a way to add a non-null column to existing data and then set values for existing row, you can work around this by providing a fixed default for the non-null date column

ALTER TABLE MyTable ADD COLUMN MyColumn DATE DEFAULT '2020-01-01'

and then update it to CURRENT_DATE

UPDATE MyTable SET MyColumn = CURRENT_DATE


问:
Google Sheets referencing values from another sheet using dynamic value calculated in current sheet
In Google Sheets I need to reference a cell by (column, row) in another sheet.

I am using the following formula right now:

```<code>=countif('Oct 2019'!H:H, "=✅")
</code>```

Here Oct 2019 is the a different sheet in the same worksheet.

However, the string Oct 2019 is present in many formulas and in next row which is for Nov 2019 I have to manually make the changes.

Is there a way where I can replace Oct 2019 by a variable and that variable can reference to a value n the original sheet ?

I have tried

```<code>=countif("INDIRECT(A8)"&!H:H, "=✅")
</code>```

where cell A8 in current sheet has the value Oct 2019 but it gives me formula parse error.

Can someone help with this please ?

答:
Use Indirect() like below.

```<code>=COUNTIF(INDIRECT("'" & A8 & "'!H:H"),"=✅")
</code>```

Body:
In Google Sheets I need to reference a cell by (column, row) in another sheet.

I am using the following formula right now:

=countif('Oct 2019'!H:H, "=✅")

Here Oct 2019 is the a different sheet in the same worksheet.

However, the string Oct 2019 is present in many formulas and in next row which is for Nov 2019 I have to manually make the changes.

Is there a way where I can replace Oct 2019 by a variable and that variable can reference to a value n the original sheet ?

I have tried

=countif("INDIRECT(A8)"&!H:H, "=✅")

where cell A8 in current sheet has the value Oct 2019 but it gives me formula parse error.

Can someone help with this please ?

Body:
Use Indirect() like below.

=COUNTIF(INDIRECT("'" & A8 & "'!H:H"),"=✅")


问:
SSRS how to decrease space between textboxes
I have two text boxes and I want their values to be one on top of the other. With almoste no spacing. I tried to remove padding but this didn't influence much.

How it's displayed

How I want it to be displayed

Maybe the problem is that the Can grow property is turned on?

答:
The best result for me was to play with padding and options 'Allow height to decrease' as allready mentioned by bot. I didn't have to do anything else, not even changing Font size.

For example, I had two Textboxes, like you posted. By default all padding is set to 2pt. So what I did was to set upper Textbox to padding 'Top = 4pt', checked option 'Allow height to decrease', and set bottom Textbox to padding 'Top = 0pt' with checked option 'Allow height to increase' (I needed this because 2nd Textbox could contain data that not fits in one row).


问:
Cannot fully scroll to first and last items with padding on both ends in recycler view
I have recycler view in a home fragment.

```<code>        <androidx.recyclerview.widget.RecyclerView
            android:id="@+id/recyclerViewSkills"
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:layout_marginTop="16dp"
            android:clipToPadding="false"
            android:paddingLeft="16dp"
            android:paddingRight="16dp"
            app:layout_constraintEnd_toEndOf="parent"
            app:layout_constraintStart_toStartOf="parent"
            app:layout_constraintTop_toBottomOf="@+id/textView3" />
</code>```

The Item in the recycler view has layout as follows:

```<code><?xml version="1.0" encoding="utf-8"?>
<androidx.constraintlayout.widget.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
        xmlns:app="http://schemas.android.com/apk/res-auto"
        xmlns:tools="http://schemas.android.com/tools"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:clipToPadding="false"
        android:padding="4dp">

        <androidx.cardview.widget.CardView
                android:id="@id/cardView"
                android:layout_width="wrap_content"
                android:layout_height="wrap_content"
                app:cardElevation="4dp"
                android:clipToPadding="false"
                app:cardCornerRadius="8dp"
                app:contentPaddingLeft="48dp"
                app:contentPaddingRight="48dp"
                app:contentPaddingTop="24dp"
                app:contentPaddingBottom="24dp"
                app:layout_constraintEnd_toEndOf="parent"
                app:layout_constraintStart_toStartOf="parent"
                app:layout_constraintTop_toTopOf="parent">

            <ImageView
                    android:id="@+id/imageViewCategoryIcon"
                    android:layout_width="@dimen/category_card_icon_size_small"
                    android:layout_height="@dimen/category_card_icon_size_small"
                    android:adjustViewBounds="true" />

        </androidx.cardview.widget.CardView>

    <TextView
        android:id="@+id/textViewCategoryName"
        android:layout_width="0dp"
        android:layout_height="wrap_content"
        android:layout_marginStart="2dp"
        android:layout_marginTop="8dp"
        android:layout_marginEnd="2dp"
        android:ellipsize="end"
        android:gravity="center"
        android:lines="2"
        android:textAlignment="center"
        android:textColor="@color/colorPrimary"
        app:layout_constraintEnd_toEndOf="@+id/cardView"
        app:layout_constraintStart_toStartOf="@+id/cardView"
        app:layout_constraintTop_toBottomOf="@+id/cardView"
        tools:text="Communication" />

    <ImageView
            android:id="@+id/imageViewPremium"
            android:elevation="8dp"
            android:layout_width="24dp"
            android:layout_height="24dp"
            android:adjustViewBounds="true"
            android:scaleType="fitCenter"
            android:src="@drawable/ribbon"
            android:visibility="gone"
            app:layout_constraintTop_toTopOf="@id/cardView"
            app:layout_constraintRight_toRightOf="@id/cardView"
            tools:visibility="visible" />
</androidx.constraintlayout.widget.ConstraintLayout>
</code>```

My problem is when I cannot fully scroll to the first or last item.

When I scroll to the end it looks like image below:

But when I leave it, it goes back to the position as shown below: Somehow when scroll horizontal the recycler view's padding on left and right doesn't work.

答:
I think u should use margin instead of padding in your recyclerview :

Change your recyclerview to this :

```<code>  <androidx.recyclerview.widget.RecyclerView
        android:id="@+id/recyclerViewSkills"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:layout_marginTop="16dp"
        android:clipToPadding="false"
        android:layout_marginStart="24dp"
        android:layout_marginEnd="24dp"
        app:layout_constraintEnd_toEndOf="parent"
        app:layout_constraintStart_toStartOf="parent"
        app:layout_constraintTop_toBottomOf="@+id/textView3" />
</code>```

Body:
I have recycler view in a home fragment.

        <androidx.recyclerview.widget.RecyclerView
            android:id="@+id/recyclerViewSkills"
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:layout_marginTop="16dp"
            android:clipToPadding="false"
            android:paddingLeft="16dp"
            android:paddingRight="16dp"
            app:layout_constraintEnd_toEndOf="parent"
            app:layout_constraintStart_toStartOf="parent"
            app:layout_constraintTop_toBottomOf="@+id/textView3" />

The Item in the recycler view has layout as follows:

<?xml version="1.0" encoding="utf-8"?>
<androidx.constraintlayout.widget.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
        xmlns:app="http://schemas.android.com/apk/res-auto"
        xmlns:tools="http://schemas.android.com/tools"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:clipToPadding="false"
        android:padding="4dp">

        <androidx.cardview.widget.CardView
                android:id="@id/cardView"
                android:layout_width="wrap_content"
                android:layout_height="wrap_content"
                app:cardElevation="4dp"
                android:clipToPadding="false"
                app:cardCornerRadius="8dp"
                app:contentPaddingLeft="48dp"
                app:contentPaddingRight="48dp"
                app:contentPaddingTop="24dp"
                app:contentPaddingBottom="24dp"
                app:layout_constraintEnd_toEndOf="parent"
                app:layout_constraintStart_toStartOf="parent"
                app:layout_constraintTop_toTopOf="parent">

            <ImageView
                    android:id="@+id/imageViewCategoryIcon"
                    android:layout_width="@dimen/category_card_icon_size_small"
                    android:layout_height="@dimen/category_card_icon_size_small"
                    android:adjustViewBounds="true" />

        </androidx.cardview.widget.CardView>

    <TextView
        android:id="@+id/textViewCategoryName"
        android:layout_width="0dp"
        android:layout_height="wrap_content"
        android:layout_marginStart="2dp"
        android:layout_marginTop="8dp"
        android:layout_marginEnd="2dp"
        android:ellipsize="end"
        android:gravity="center"
        android:lines="2"
        android:textAlignment="center"
        android:textColor="@color/colorPrimary"
        app:layout_constraintEnd_toEndOf="@+id/cardView"
        app:layout_constraintStart_toStartOf="@+id/cardView"
        app:layout_constraintTop_toBottomOf="@+id/cardView"
        tools:text="Communication" />

    <ImageView
            android:id="@+id/imageViewPremium"
            android:elevation="8dp"
            android:layout_width="24dp"
            android:layout_height="24dp"
            android:adjustViewBounds="true"
            android:scaleType="fitCenter"
            android:src="@drawable/ribbon"
            android:visibility="gone"
            app:layout_constraintTop_toTopOf="@id/cardView"
            app:layout_constraintRight_toRightOf="@id/cardView"
            tools:visibility="visible" />
</androidx.constraintlayout.widget.ConstraintLayout>

My problem is when I cannot fully scroll to the first or last item.

When I scroll to the end it looks like image below:

But when I leave it, it goes back to the position as shown below: Somehow when scroll horizontal the recycler view's padding on left and right doesn't work.

Body:
I think u should use margin instead of padding in your recyclerview :

Change your recyclerview to this :

  <androidx.recyclerview.widget.RecyclerView
        android:id="@+id/recyclerViewSkills"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:layout_marginTop="16dp"
        android:clipToPadding="false"
        android:layout_marginStart="24dp"
        android:layout_marginEnd="24dp"
        app:layout_constraintEnd_toEndOf="parent"
        app:layout_constraintStart_toStartOf="parent"
        app:layout_constraintTop_toBottomOf="@+id/textView3" />


问:
.NET units class, inches to millimeters
Does .NET has Units conversion class? I need to convert inches to millimeters and vise versa. </p>

答: No there is nothing like that built-in. But you can simply multiply or divide by 25.4.</p>

Title: .NET units class, inches to millimeters


问:
How to sort out an Array with Swift
I can get my RSS feed printed out to the console in an array form. Every news-item I get is an element of the array. From every news-item is a title, description, link and pub-date available.

I want to get this sorted out wherefore all the titles are being put into an array and all the descriptions are being put into an array and so on.

Is there a way how to do this in Swift?

Here is my data that I want to get sorted out and put into four different arrays:

```<code> {
    description = "Voleco-arbiter gelauwerd voor 25 jaar op de bok\n      ";
    link = "https://api.nevobo.nl/permalink/nieuws/18914\n      ";
    pubDate = "Wed, 13 Nov 2019 12:00:00 +0100\n    \n    ";
    title = "Zilver voor Erik-Jan Geneugelijk\n      ";
}
{
    description = "Het einde van het jaar is weer in zicht. Dit houdt in dat er in iedere regio een regiosymposium wordt georganiseerd. Mis het niet!\n      ";
    link = "https://api.nevobo.nl/permalink/nieuws/18913\n      ";
    pubDate = "Tue, 12 Nov 2019 13:54:00 +0100\n    \n  \n";
    title = "Regiosymposia 2019: 'Superclubs'!\n      ";
}
</code>```

答:
What you want to do is not sorting, sorting means to set the order of the array following a certain logic.

You just want to create new arrays, you can do it like this

```<code>let titles = newsItems.map { $0.title }
</code>```

Repeat for different properties and you’ll have the arrays you want.

Title: How to sort out an Array with Swift

Body:
I can get my RSS feed printed out to the console in an array form. Every news-item I get is an element of the array. From every news-item is a title, description, link and pub-date available.

I want to get this sorted out wherefore all the titles are being put into an array and all the descriptions are being put into an array and so on.

Is there a way how to do this in Swift?

Here is my data that I want to get sorted out and put into four different arrays:

 {
    description = "Voleco-arbiter gelauwerd voor 25 jaar op de bok\n      ";
    link = "https://api.nevobo.nl/permalink/nieuws/18914\n      ";
    pubDate = "Wed, 13 Nov 2019 12:00:00 +0100\n    \n    ";
    title = "Zilver voor Erik-Jan Geneugelijk\n      ";
}
{
    description = "Het einde van het jaar is weer in zicht. Dit houdt in dat er in iedere regio een regiosymposium wordt georganiseerd. Mis het niet!\n      ";
    link = "https://api.nevobo.nl/permalink/nieuws/18913\n      ";
    pubDate = "Tue, 12 Nov 2019 13:54:00 +0100\n    \n  \n";
    title = "Regiosymposia 2019: 'Superclubs'!\n      ";
}

Body:
What you want to do is not sorting, sorting means to set the order of the array following a certain logic.

You just want to create new arrays, you can do it like this

let titles = newsItems.map { $0.title }

Repeat for different properties and you’ll have the arrays you want.


问:
Qt convert translated text to english
My Qt application supports dynamic translation IE the user can change languages whilst the application is running

Now I have a need to find the English equivalent of a translated string and don't seem to be able to find a way

For example
Given QString s = tr("Hello");
I need to be able to get "Hello" from s after translation has taken place.

Has anyone done this before or have any ideas on how (if) it can be achieved

Thanks

答:
Based on Mykhailo Bryzhaks answer I adopted the class a bit so we can have contexts in the .ts file which will make things a lot easier for big solutions:

```<code>#ifndef TrString_h__
#define TrString_h__

#include <QString>
#include <QRegularExpression>
#include <cassert>

class QObject;

namespace
{
    static QRegularExpression s_findClassNameRegExp("(?<=\\bclass\\s)(\\w+)");
    static QRegularExpression s_findQuotesRegExp("\"([^\"\\\\]|\\\\.)*\"");
}

#define TRStringVoid(QT_TRANSLATE_NOOP_STRING) TrString<void>(#QT_TRANSLATE_NOOP_STRING)
#define TRString(QT_TR_NOOP_STRING) TrString<decltype(this)>(this, #QT_TR_NOOP_STRING)

// Use      //: MyComment
// one line before the call to add a comment for the translator

namespace
{
    const QString kQT_TR_NOOP_Macro = "QT_TR_NOOP(";
    const QString kQT_TRANSLATE_NOOP_Macro = "QT_TRANSLATE_NOOP(";
    const QString kQT_TRANSLATE_NOOP_3_Macro = "QT_TRANSLATE_NOOP3(";
}

// Use TRString or TRStringVoid macro to get an instance of this class
template <class T> class TrString
{
    enum class MacroType { Unknown, QT_TR_NOOP, QT_TRANSLATE_NOOP, QT_TRANSLATE_NOOP3 };

public:
    // used for global functions where T is void
    template <typename SfinaeT = void, typename SfinaeT2 = std::enable_if_t<std::is_void<T>::value, T>>
    TrString(const char* lineString)
        : m_native(lineString)
    {
        m_macroType = getLineStringType(lineString);

        assert(("You must use TRStringVoid(QT_TRANSLATE_NOOP('Context','StringToTranslate')) here because you are not in a class context.",
            (m_macroType == MacroType::QT_TRANSLATE_NOOP || m_macroType == MacroType::QT_TRANSLATE_NOOP3)));

        initStrings();
    }

    // used for calls from within objects
    template <typename SfinaeT = void, typename SfinaeT2 = std::enable_if_t<!std::is_void<T>::value, T>>
    TrString(SfinaeT2 caller, const char* lineString)
        : m_native(lineString)
    {
        m_macroType = getLineStringType(lineString);
        checkIfTemplateHasCorrectType(caller);
        initStrings();
    }

    TrString& operator=(const TrString& other)
    {
        m_scope = other.m_scope;
        m_native = other.m_native;
        m_translated = other.m_translated;
    }

    TrString& arg(const TrString& arg1)
    {
        this->m_native = this->m_native.arg(arg1.native());
        this->m_translated = this->m_translated.arg(qApp->translate(m_scope.toLocal8Bit().data(), arg1.translated().toLocal8Bit().data()));

        return *this;
    }

    TrString& arg(const QString arg1)
    {
        this->m_native = this->m_native.arg(arg1);
        this->m_translated = this->m_translated.arg(arg1);
        return *this;
    }

    TrString& arg(const double arg1)
    {
        this->m_native = this->m_native.arg(arg1);
        this->m_translated = this->m_translated.arg(arg1);
        return *this;
    }

    inline const QString& native() const
    {
        return this->m_native;
    }

    inline const QString& translated() const
    {
        return this->m_translated;
    }

private:
    template<class SfinaeT = T>
    typename std::enable_if<!std::is_polymorphic< std::remove_pointer_t<SfinaeT>>::value, void>::type
        checkIfTemplateHasCorrectType(SfinaeT caller)
    {
        assert(("You must use TRString(QT_TRANSLATE_NOOP('Context', 'StringToTranslate')) here because your class does not derive from QObject.",
            (m_macroType == MacroType::QT_TRANSLATE_NOOP || m_macroType == MacroType::QT_TRANSLATE_NOOP3)));
    }

    template<class SfinaeT = T>
    typename std::enable_if<std::is_polymorphic< std::remove_pointer_t<SfinaeT>>::value, void>::type
        checkIfTemplateHasCorrectType(SfinaeT caller)
    {
        if (!dynamic_cast<QObject*>(caller))
            assert(("You must use TRString(QT_TRANSLATE_NOOP('Context', 'StringToTranslate')) here because your class does not derive from QObject.",
            (m_macroType == MacroType::QT_TRANSLATE_NOOP || m_macroType == MacroType::QT_TRANSLATE_NOOP3)));
        else
            m_isDerivedFromQObject = true;
    }

    MacroType getLineStringType(QString lineString) const
    {
        if (m_native.contains(kQT_TR_NOOP_Macro))
            return MacroType::QT_TR_NOOP;
        else if (m_native.contains(kQT_TRANSLATE_NOOP_3_Macro))
            return MacroType::QT_TRANSLATE_NOOP3;
        else if (m_native.contains(kQT_TRANSLATE_NOOP_Macro))
            return MacroType::QT_TRANSLATE_NOOP;
        else
        {
            assert(("You must you TRString(QT_TR_NOOP('StringToTranslate') or TRString(QT_TRANSLATE_NOOP('Context', 'StringToTranslate')) if you are not in a QObject derived class for this to work.", false));
            return MacroType::Unknown;
        }
    }

    inline void initStrings()
    {
        QRegularExpressionMatchIterator regExpIter = s_findQuotesRegExp.globalMatch(m_native);
        QStringList macroArguments;

        while (regExpIter.hasNext())
        {
            QRegularExpressionMatch match = regExpIter.next();
            QString argumentString = match.captured(0);
            argumentString.remove(0, 1);
            argumentString.remove(argumentString.length() - 1, 1);
            macroArguments.push_back(argumentString);
        }

        if (macroArguments.size() == 1 && m_macroType == MacroType::QT_TR_NOOP)
        {
            m_scope = QRegularExpressionMatch(s_findClassNameRegExp.match(typeid(T).name())).captured(0);
            m_native = macroArguments[0];
        }
        else if ((macroArguments.size() == 2 && m_macroType == MacroType::QT_TRANSLATE_NOOP) || (macroArguments.size() == 3 && m_macroType == MacroType::QT_TRANSLATE_NOOP3))
        {
            m_scope = macroArguments[0];
            m_native = macroArguments[1];
        }
        else
        {
            assert(("You must you TRString(QT_TR_NOOP('StringToTranslate') or TRString(QT_TRANSLATE_NOOP('Context', 'StringToTranslate')) if you are not in a QObject derived class for this to work.", false));
        }

        m_translated = qApp->translate(m_scope.toLocal8Bit().data(), m_native.toLocal8Bit().data());
    }

    MacroType m_macroType = MacroType::Unknown;
    bool m_isDerivedFromQObject = false;
    QString m_native;
    QString m_translated;
    QString m_scope;
};

#endif // TrString_h__
</code>```

Usage in a QObject derived class:

```<code>auto logString = TRString(QT_TR_NOOP("Indian Pale Ale"));
qDebug() << "Native: " << logString.native(); // "Indian Pale Ale"
qDebug() << "Transl: " << logString.translated(); // "Indisches Blass Ale"
</code>```

Usage in a class that does not derive from QObject:

```<code>auto logString = TRString(QT_TRANSLATE_NOOP("MyClass", "Log message"));
</code>```

Usage outside of classes:

```<code>auto logString = TRStringVoid(QT_TRANSLATE_NOOP("Main", "Log message in main"));
</code>```

If you inadvertently use the wrong Qt macro or the wrong TRString macro an assert will be created with a message on how to fix the call.

Title: Qt convert translated text to english

Body:
Based on Mykhailo Bryzhaks answer I adopted the class a bit so we can have contexts in the .ts file which will make things a lot easier for big solutions:

#ifndef TrString_h__
#define TrString_h__

#include <QString>
#include <QRegularExpression>
#include <cassert>

class QObject;

namespace
{
    static QRegularExpression s_findClassNameRegExp("(?<=\\bclass\\s)(\\w+)");
    static QRegularExpression s_findQuotesRegExp("\"([^\"\\\\]|\\\\.)*\"");
}

#define TRStringVoid(QT_TRANSLATE_NOOP_STRING) TrString<void>(#QT_TRANSLATE_NOOP_STRING)
#define TRString(QT_TR_NOOP_STRING) TrString<decltype(this)>(this, #QT_TR_NOOP_STRING)

// Use      //: MyComment
// one line before the call to add a comment for the translator

namespace
{
    const QString kQT_TR_NOOP_Macro = "QT_TR_NOOP(";
    const QString kQT_TRANSLATE_NOOP_Macro = "QT_TRANSLATE_NOOP(";
    const QString kQT_TRANSLATE_NOOP_3_Macro = "QT_TRANSLATE_NOOP3(";
}

// Use TRString or TRStringVoid macro to get an instance of this class
template <class T> class TrString
{
    enum class MacroType { Unknown, QT_TR_NOOP, QT_TRANSLATE_NOOP, QT_TRANSLATE_NOOP3 };

public:
    // used for global functions where T is void
    template <typename SfinaeT = void, typename SfinaeT2 = std::enable_if_t<std::is_void<T>::value, T>>
    TrString(const char* lineString)
        : m_native(lineString)
    {
        m_macroType = getLineStringType(lineString);

        assert(("You must use TRStringVoid(QT_TRANSLATE_NOOP('Context','StringToTranslate')) here because you are not in a class context.",
            (m_macroType == MacroType::QT_TRANSLATE_NOOP || m_macroType == MacroType::QT_TRANSLATE_NOOP3)));

        initStrings();
    }

    // used for calls from within objects
    template <typename SfinaeT = void, typename SfinaeT2 = std::enable_if_t<!std::is_void<T>::value, T>>
    TrString(SfinaeT2 caller, const char* lineString)
        : m_native(lineString)
    {
        m_macroType = getLineStringType(lineString);
        checkIfTemplateHasCorrectType(caller);
        initStrings();
    }

    TrString& operator=(const TrString& other)
    {
        m_scope = other.m_scope;
        m_native = other.m_native;
        m_translated = other.m_translated;
    }

    TrString& arg(const TrString& arg1)
    {
        this->m_native = this->m_native.arg(arg1.native());
        this->m_translated = this->m_translated.arg(qApp->translate(m_scope.toLocal8Bit().data(), arg1.translated().toLocal8Bit().data()));

        return *this;
    }

    TrString& arg(const QString arg1)
    {
        this->m_native = this->m_native.arg(arg1);
        this->m_translated = this->m_translated.arg(arg1);
        return *this;
    }

    TrString& arg(const double arg1)
    {
        this->m_native = this->m_native.arg(arg1);
        this->m_translated = this->m_translated.arg(arg1);
        return *this;
    }

    inline const QString& native() const
    {
        return this->m_native;
    }

    inline const QString& translated() const
    {
        return this->m_translated;
    }

private:
    template<class SfinaeT = T>
    typename std::enable_if<!std::is_polymorphic< std::remove_pointer_t<SfinaeT>>::value, void>::type
        checkIfTemplateHasCorrectType(SfinaeT caller)
    {
        assert(("You must use TRString(QT_TRANSLATE_NOOP('Context', 'StringToTranslate')) here because your class does not derive from QObject.",
            (m_macroType == MacroType::QT_TRANSLATE_NOOP || m_macroType == MacroType::QT_TRANSLATE_NOOP3)));
    }

    template<class SfinaeT = T>
    typename std::enable_if<std::is_polymorphic< std::remove_pointer_t<SfinaeT>>::value, void>::type
        checkIfTemplateHasCorrectType(SfinaeT caller)
    {
        if (!dynamic_cast<QObject*>(caller))
            assert(("You must use TRString(QT_TRANSLATE_NOOP('Context', 'StringToTranslate')) here because your class does not derive from QObject.",
            (m_macroType == MacroType::QT_TRANSLATE_NOOP || m_macroType == MacroType::QT_TRANSLATE_NOOP3)));
        else
            m_isDerivedFromQObject = true;
    }

    MacroType getLineStringType(QString lineString) const
    {
        if (m_native.contains(kQT_TR_NOOP_Macro))
            return MacroType::QT_TR_NOOP;
        else if (m_native.contains(kQT_TRANSLATE_NOOP_3_Macro))
            return MacroType::QT_TRANSLATE_NOOP3;
        else if (m_native.contains(kQT_TRANSLATE_NOOP_Macro))
            return MacroType::QT_TRANSLATE_NOOP;
        else
        {
            assert(("You must you TRString(QT_TR_NOOP('StringToTranslate') or TRString(QT_TRANSLATE_NOOP('Context', 'StringToTranslate')) if you are not in a QObject derived class for this to work.", false));
            return MacroType::Unknown;
        }
    }

    inline void initStrings()
    {
        QRegularExpressionMatchIterator regExpIter = s_findQuotesRegExp.globalMatch(m_native);
        QStringList macroArguments;

        while (regExpIter.hasNext())
        {
            QRegularExpressionMatch match = regExpIter.next();
            QString argumentString = match.captured(0);
            argumentString.remove(0, 1);
            argumentString.remove(argumentString.length() - 1, 1);
            macroArguments.push_back(argumentString);
        }

        if (macroArguments.size() == 1 && m_macroType == MacroType::QT_TR_NOOP)
        {
            m_scope = QRegularExpressionMatch(s_findClassNameRegExp.match(typeid(T).name())).captured(0);
            m_native = macroArguments[0];
        }
        else if ((macroArguments.size() == 2 && m_macroType == MacroType::QT_TRANSLATE_NOOP) || (macroArguments.size() == 3 && m_macroType == MacroType::QT_TRANSLATE_NOOP3))
        {
            m_scope = macroArguments[0];
            m_native = macroArguments[1];
        }
        else
        {
            assert(("You must you TRString(QT_TR_NOOP('StringToTranslate') or TRString(QT_TRANSLATE_NOOP('Context', 'StringToTranslate')) if you are not in a QObject derived class for this to work.", false));
        }

        m_translated = qApp->translate(m_scope.toLocal8Bit().data(), m_native.toLocal8Bit().data());
    }

    MacroType m_macroType = MacroType::Unknown;
    bool m_isDerivedFromQObject = false;
    QString m_native;
    QString m_translated;
    QString m_scope;
};

#endif // TrString_h__

Usage in a QObject derived class:

auto logString = TRString(QT_TR_NOOP("Indian Pale Ale"));
qDebug() << "Native: " << logString.native(); // "Indian Pale Ale"
qDebug() << "Transl: " << logString.translated(); // "Indisches Blass Ale"

Usage in a class that does not derive from QObject:

auto logString = TRString(QT_TRANSLATE_NOOP("MyClass", "Log message"));

Usage outside of classes:

auto logString = TRStringVoid(QT_TRANSLATE_NOOP("Main", "Log message in main"));

If you inadvertently use the wrong Qt macro or the wrong TRString macro an assert will be created with a message on how to fix the call.


问:
Jmeter - How to test an api protected with Client Certificate Authentication in Jmeter?
How to test an api protected with Client Certificate Authentication in Jmeter?
Client Certificate Authentication - How to get an alias for the certificate?
Can someone please help me with the configuration in Jmeter that can do the same..</p>

答:
You need to put the certificate (and the client file) into a jks (or better pkcs12) keystore, I normally do this using openssl command line tool and keytool but you might find a GUI-based tool like KeyStore Explorer easier

If you need to supply only one certificate - it would be sufficient just to provide keystore location, type and password to JMeter via javax.net.ssl.keyStore, javax.net.ssl.keyStoreType and javax.net.ssl.keyStorePassword system properties correspondingly.

If you have > 1 certificate in the keystore and would like each JMeter thread to use different certificate - go for Keystore Configuration element

Check out How to Use Multiple Certificates When Load Testing Secure Websites article for more details.


问:
problem with JavaScript sortable html table
Here is webtoolkit but ...

```<code>var t = new SortableTable(document.getElementById('myTable'), 100);
</code>```

2 parameters

```<code>function SortableTable (tableEl) {
</code>```

and where is height ?

Here is my try to make it work but it doesn't works (only commented code works but for ff and ie only)

```<code>    function ScrollableTable(tableEl, tableHeight, tableWidth)
{
    this.tbody = tableEl.getElementsByTagName('tbody');
    this.thead = tableEl.getElementsByTagName('thead');
    this.tfoot = tableEl.getElementsByTagName('tfoot');

    this.getInnerText = function(el) {
        if (typeof (el.textContent) != 'undefined') return el.textContent;
        if (typeof (el.innerText) != 'undefined') return el.innerText;
        if (typeof (el.innerHTML) == 'string') return el.innerHTML.replace(/<[^<>]+>/g, '');
    }

    this.getParent = function(el, pTagName) {
        if (el == null) return null;
        else if (el.nodeType == 1 && el.tagName.toLowerCase() == pTagName.toLowerCase())
            return el;
        else
            return this.getParent(el.parentNode, pTagName);
    }

    this.sort = function(cell) {

        var column = cell.cellIndex;
        var itm = this.getInnerText(this.tbody[0].rows[1].cells[column]);
        var sortfn = this.sortCaseInsensitive;

        if (itm.match(/\d\d[-]+\d\d[-]+\d\d\d\d/)) sortfn = this.sortDate; // date format mm-dd-yyyy
        if (itm.replace(/^\s+|\s+$/g, "").match(/^[\d\.]+$/)) sortfn = this.sortNumeric;

        this.sortColumnIndex = column;

        var newRows = new Array();
        for (j = 0; j < this.tbody[0].rows.length; j++) {
            newRows[j] = this.tbody[0].rows[j];
        }

        newRows.sort(sortfn);

        if (cell.getAttribute("sortdir") == 'down') {
            newRows.reverse();
            cell.setAttribute('sortdir', 'up');
        } else {
            cell.setAttribute('sortdir', 'down');
        }

        for (i = 0; i < newRows.length; i++) {
            this.tbody[0].appendChild(newRows[i]);
        }

    }

    this.sortCaseInsensitive = function(a, b) {
        aa = thisObject.getInnerText(a.cells[thisObject.sortColumnIndex]).toLowerCase();
        bb = thisObject.getInnerText(b.cells[thisObject.sortColumnIndex]).toLowerCase();
        if (aa == bb) return 0;
        if (aa < bb) return -1;
        return 1;
    }

    this.sortDate = function(a, b) {
        aa = thisObject.getInnerText(a.cells[thisObject.sortColumnIndex]);
        bb = thisObject.getInnerText(b.cells[thisObject.sortColumnIndex]);
        date1 = aa.substr(6, 4) + aa.substr(3, 2) + aa.substr(0, 2);
        date2 = bb.substr(6, 4) + bb.substr(3, 2) + bb.substr(0, 2);
        if (date1 == date2) return 0;
        if (date1 < date2) return -1;
        return 1;
    }

    this.sortNumeric = function(a, b) {
        aa = parseFloat(thisObject.getInnerText(a.cells[thisObject.sortColumnIndex]));
        if (isNaN(aa)) aa = 0;
        bb = parseFloat(thisObject.getInnerText(b.cells[thisObject.sortColumnIndex]));
        if (isNaN(bb)) bb = 0;
        return aa - bb;
    }

    // define variables
    var thisObject = this;
    var sortSection = this.thead;

    // constructor actions
    if (!(this.tbody && this.tbody[0].rows && this.tbody[0].rows.length > 0)) return;

    if (sortSection && sortSection[0].rows && sortSection[0].rows.length > 0) {
        var sortRow = sortSection[0].rows[0];
    } else {
        return;
    }

    for (var i = 0; i < sortRow.cells.length; i++) {
        sortRow.cells[i].sTable = this;
        sortRow.cells[i].onclick = function() {
            this.sTable.sort(this);
            return false;
        }
    }

/*
    this.initIEengine = function() {

        this.containerEl.style.overflowY = 'auto';
        if (this.tableEl.parentElement.clientHeight - this.tableEl.offsetHeight < 0) {
            this.tableEl.style.width = this.newWidth - this.scrollWidth + 'px';
        } else {
            this.containerEl.style.overflowY = 'hidden';
            this.tableEl.style.width = this.newWidth + 'px';
        }

        if (this.thead) {
            var trs = this.thead.getElementsByTagName('tr');
            for (x = 0; x < trs.length; x++) {
                trs[x].style.position = 'relative';
                trs[x].style.setExpression("top", "this.parentElement.parentElement.parentElement.scrollTop + 'px'");
            }
        }

        if (this.tfoot) {
            var trs = this.tfoot.getElementsByTagName('tr');
            for (x = 0; x < trs.length; x++) {
                trs[x].style.position = 'relative';
                trs[x].style.setExpression("bottom", "(this.parentElement.parentElement.offsetHeight - this.parentElement.parentElement.parentElement.clientHeight - this.parentElement.parentElement.parentElement.scrollTop) + 'px'");
            }
        }

        eval("window.attachEvent('onresize', function () { document.getElementById('" + this.tableEl.id + "').style.visibility = 'hidden'; document.getElementById('" + this.tableEl.id + "').style.visibility = 'visible'; } )");
    };

    this.initFFengine = function() {
        this.containerEl.style.overflow = 'hidden';
        this.tableEl.style.width = this.newWidth + 'px';

        var headHeight = (this.thead) ? this.thead.clientHeight : 0;
        var footHeight = (this.tfoot) ? this.tfoot.clientHeight : 0;
        var bodyHeight = this.tbody.clientHeight;
        var trs = this.tbody.getElementsByTagName('tr');
        if (bodyHeight >= (this.newHeight - (headHeight + footHeight))) {
            this.tbody.style.overflow = '-moz-scrollbars-vertical';
            for (x = 0; x < trs.length; x++) {
                var tds = trs[x].getElementsByTagName('td');
                tds[tds.length - 1].style.paddingRight += this.scrollWidth + 'px';
            }
        } else {
            this.tbody.style.overflow = '-moz-scrollbars-none';
        }

        var cellSpacing = (this.tableEl.offsetHeight - (this.tbody.clientHeight + headHeight + footHeight)) / 4;
        this.tbody.style.height = (this.newHeight - (headHeight + cellSpacing * 2) - (footHeight + cellSpacing * 2)) + 'px';

    };

    if (!this.tbody) return;

    if (document.all && document.getElementById && !window.opera) this.initIEengine();
    if (!document.all && document.getElementById && !window.opera) this.initFFengine();
    */

    this.tableEl = tableEl;
    this.scrollWidth = 16;

    this.originalHeight = this.tableEl.clientHeight;
    this.originalWidth = this.tableEl.clientWidth;

    this.newHeight = parseInt(tableHeight);
    this.newWidth = tableWidth ? parseInt(tableWidth) : this.originalWidth;

    this.tableEl.style.height = 'auto';
    this.tableEl.removeAttribute('height');

    this.containerEl = this.tableEl.parentNode.insertBefore(document.createElement('div'), this.tableEl);
    this.containerEl.appendChild(this.tableEl);
    this.containerEl.style.height = this.newHeight + 'px';
    this.containerEl.style.width = this.newWidth + 'px';

    var thead = this.tableEl.getElementsByTagName('thead');
    this.thead = (thead[0]) ? thead[0] : null;

    var tfoot = this.tableEl.getElementsByTagName('tfoot');
    this.tfoot = (tfoot[0]) ? tfoot[0] : null;

    var tbody = this.tableEl.getElementsByTagName('tbody');
    this.tbody = (tbody[0]) ? tbody[0] : null;
}
</code>```

The trouble is I got no THead and TBody here :

```<code>    <asp:Panel ID="Panel2" style="width:990px; border-style: outset; border-width: 4px; " runat="server" ScrollBars="Horizontal">
    <asp:GridView ID="GridView2" runat="server"
        DataSourceID="SqlDataSource1" Width="100%"
        ondatabound="GridView2_DataBound" CellPadding="4" ForeColor="#333333"
        GridLines="both" ShowFooter="True" onrowdatabound="GridView2_RowDataBound"
        HorizontalAlign="Center">
        <RowStyle BackColor="#F7F6F3" ForeColor="#333333" HorizontalAlign="Center"
            VerticalAlign="Middle" />
        <FooterStyle BackColor="#5D7B9D" Font-Bold="True" ForeColor="White" />
        <PagerStyle BackColor="#284775" ForeColor="White" HorizontalAlign="Center"
            VerticalAlign="Middle" />
        <SelectedRowStyle BackColor="#E2DED6" Font-Bold="True" ForeColor="#333333"
            HorizontalAlign="Center" VerticalAlign="Middle" />
        <HeaderStyle BackColor="#5D7B9D" Font-Bold="True" ForeColor="White" />
        <EditRowStyle BackColor="#999999" HorizontalAlign="Center" />
        <AlternatingRowStyle BackColor="White" ForeColor="#284775"
            HorizontalAlign="Center" />
    </asp:GridView>
</asp:Panel>
</code>```

Is there some wais to make this script works for GridView ?..

and Ive got a trouble with hiding of vertical scrollbar if there is horizontal scroll bar (but that's trouble if I use commented code)

答:
Couldn't you just have a new function that instantiates a new SortableTable? Or do you have to rewrite everything for some reason?

Something like:

```<code>function ScrollableTable(tableEl, tableHeight, tableWidth)
{
var table = new SortableTable(document.getElementById('myTable'), 100);
do stuff to the table that you whant..like width and height..
}
</code>```

ContentLicense: CC BY-SA 2.5

Body:
Here is webtoolkit but ...

var t = new SortableTable(document.getElementById('myTable'), 100);

2 parameters

function SortableTable (tableEl) {

and where is height ?

Here is my try to make it work but it doesn't works (only commented code works but for ff and ie only)

    function ScrollableTable(tableEl, tableHeight, tableWidth)
{
    this.tbody = tableEl.getElementsByTagName('tbody');
    this.thead = tableEl.getElementsByTagName('thead');
    this.tfoot = tableEl.getElementsByTagName('tfoot');

    this.getInnerText = function(el) {
        if (typeof (el.textContent) != 'undefined') return el.textContent;
        if (typeof (el.innerText) != 'undefined') return el.innerText;
        if (typeof (el.innerHTML) == 'string') return el.innerHTML.replace(/<[^<>]+>/g, '');
    }

    this.getParent = function(el, pTagName) {
        if (el == null) return null;
        else if (el.nodeType == 1 && el.tagName.toLowerCase() == pTagName.toLowerCase())
            return el;
        else
            return this.getParent(el.parentNode, pTagName);
    }

    this.sort = function(cell) {

        var column = cell.cellIndex;
        var itm = this.getInnerText(this.tbody[0].rows[1].cells[column]);
        var sortfn = this.sortCaseInsensitive;

        if (itm.match(/\d\d[-]+\d\d[-]+\d\d\d\d/)) sortfn = this.sortDate; // date format mm-dd-yyyy
        if (itm.replace(/^\s+|\s+$/g, "").match(/^[\d\.]+$/)) sortfn = this.sortNumeric;

        this.sortColumnIndex = column;

        var newRows = new Array();
        for (j = 0; j < this.tbody[0].rows.length; j++) {
            newRows[j] = this.tbody[0].rows[j];
        }

        newRows.sort(sortfn);

        if (cell.getAttribute("sortdir") == 'down') {
            newRows.reverse();
            cell.setAttribute('sortdir', 'up');
        } else {
            cell.setAttribute('sortdir', 'down');
        }

        for (i = 0; i < newRows.length; i++) {
            this.tbody[0].appendChild(newRows[i]);
        }

    }

    this.sortCaseInsensitive = function(a, b) {
        aa = thisObject.getInnerText(a.cells[thisObject.sortColumnIndex]).toLowerCase();
        bb = thisObject.getInnerText(b.cells[thisObject.sortColumnIndex]).toLowerCase();
        if (aa == bb) return 0;
        if (aa < bb) return -1;
        return 1;
    }

    this.sortDate = function(a, b) {
        aa = thisObject.getInnerText(a.cells[thisObject.sortColumnIndex]);
        bb = thisObject.getInnerText(b.cells[thisObject.sortColumnIndex]);
        date1 = aa.substr(6, 4) + aa.substr(3, 2) + aa.substr(0, 2);
        date2 = bb.substr(6, 4) + bb.substr(3, 2) + bb.substr(0, 2);
        if (date1 == date2) return 0;
        if (date1 < date2) return -1;
        return 1;
    }

    this.sortNumeric = function(a, b) {
        aa = parseFloat(thisObject.getInnerText(a.cells[thisObject.sortColumnIndex]));
        if (isNaN(aa)) aa = 0;
        bb = parseFloat(thisObject.getInnerText(b.cells[thisObject.sortColumnIndex]));
        if (isNaN(bb)) bb = 0;
        return aa - bb;
    }

    // define variables
    var thisObject = this;
    var sortSection = this.thead;

    // constructor actions
    if (!(this.tbody && this.tbody[0].rows && this.tbody[0].rows.length > 0)) return;

    if (sortSection && sortSection[0].rows && sortSection[0].rows.length > 0) {
        var sortRow = sortSection[0].rows[0];
    } else {
        return;
    }

    for (var i = 0; i < sortRow.cells.length; i++) {
        sortRow.cells[i].sTable = this;
        sortRow.cells[i].onclick = function() {
            this.sTable.sort(this);
            return false;
        }
    }

/*
    this.initIEengine = function() {

        this.containerEl.style.overflowY = 'auto';
        if (this.tableEl.parentElement.clientHeight - this.tableEl.offsetHeight < 0) {
            this.tableEl.style.width = this.newWidth - this.scrollWidth + 'px';
        } else {
            this.containerEl.style.overflowY = 'hidden';
            this.tableEl.style.width = this.newWidth + 'px';
        }

        if (this.thead) {
            var trs = this.thead.getElementsByTagName('tr');
            for (x = 0; x < trs.length; x++) {
                trs[x].style.position = 'relative';
                trs[x].style.setExpression("top", "this.parentElement.parentElement.parentElement.scrollTop + 'px'");
            }
        }

        if (this.tfoot) {
            var trs = this.tfoot.getElementsByTagName('tr');
            for (x = 0; x < trs.length; x++) {
                trs[x].style.position = 'relative';
                trs[x].style.setExpression("bottom", "(this.parentElement.parentElement.offsetHeight - this.parentElement.parentElement.parentElement.clientHeight - this.parentElement.parentElement.parentElement.scrollTop) + 'px'");
            }
        }

        eval("window.attachEvent('onresize', function () { document.getElementById('" + this.tableEl.id + "').style.visibility = 'hidden'; document.getElementById('" + this.tableEl.id + "').style.visibility = 'visible'; } )");
    };

    this.initFFengine = function() {
        this.containerEl.style.overflow = 'hidden';
        this.tableEl.style.width = this.newWidth + 'px';

        var headHeight = (this.thead) ? this.thead.clientHeight : 0;
        var footHeight = (this.tfoot) ? this.tfoot.clientHeight : 0;
        var bodyHeight = this.tbody.clientHeight;
        var trs = this.tbody.getElementsByTagName('tr');
        if (bodyHeight >= (this.newHeight - (headHeight + footHeight))) {
            this.tbody.style.overflow = '-moz-scrollbars-vertical';
            for (x = 0; x < trs.length; x++) {
                var tds = trs[x].getElementsByTagName('td');
                tds[tds.length - 1].style.paddingRight += this.scrollWidth + 'px';
            }
        } else {
            this.tbody.style.overflow = '-moz-scrollbars-none';
        }

        var cellSpacing = (this.tableEl.offsetHeight - (this.tbody.clientHeight + headHeight + footHeight)) / 4;
        this.tbody.style.height = (this.newHeight - (headHeight + cellSpacing * 2) - (footHeight + cellSpacing * 2)) + 'px';

    };

    if (!this.tbody) return;

    if (document.all && document.getElementById && !window.opera) this.initIEengine();
    if (!document.all && document.getElementById && !window.opera) this.initFFengine();
    */

    this.tableEl = tableEl;
    this.scrollWidth = 16;

    this.originalHeight = this.tableEl.clientHeight;
    this.originalWidth = this.tableEl.clientWidth;

    this.newHeight = parseInt(tableHeight);
    this.newWidth = tableWidth ? parseInt(tableWidth) : this.originalWidth;

    this.tableEl.style.height = 'auto';
    this.tableEl.removeAttribute('height');

    this.containerEl = this.tableEl.parentNode.insertBefore(document.createElement('div'), this.tableEl);
    this.containerEl.appendChild(this.tableEl);
    this.containerEl.style.height = this.newHeight + 'px';
    this.containerEl.style.width = this.newWidth + 'px';

    var thead = this.tableEl.getElementsByTagName('thead');
    this.thead = (thead[0]) ? thead[0] : null;

    var tfoot = this.tableEl.getElementsByTagName('tfoot');
    this.tfoot = (tfoot[0]) ? tfoot[0] : null;

    var tbody = this.tableEl.getElementsByTagName('tbody');
    this.tbody = (tbody[0]) ? tbody[0] : null;
}

The trouble is I got no THead and TBody here :

    <asp:Panel ID="Panel2" style="width:990px; border-style: outset; border-width: 4px; " runat="server" ScrollBars="Horizontal">
    <asp:GridView ID="GridView2" runat="server"
        DataSourceID="SqlDataSource1" Width="100%"
        ondatabound="GridView2_DataBound" CellPadding="4" ForeColor="#333333"
        GridLines="both" ShowFooter="True" onrowdatabound="GridView2_RowDataBound"
        HorizontalAlign="Center">
        <RowStyle BackColor="#F7F6F3" ForeColor="#333333" HorizontalAlign="Center"
            VerticalAlign="Middle" />
        <FooterStyle BackColor="#5D7B9D" Font-Bold="True" ForeColor="White" />
        <PagerStyle BackColor="#284775" ForeColor="White" HorizontalAlign="Center"
            VerticalAlign="Middle" />
        <SelectedRowStyle BackColor="#E2DED6" Font-Bold="True" ForeColor="#333333"
            HorizontalAlign="Center" VerticalAlign="Middle" />
        <HeaderStyle BackColor="#5D7B9D" Font-Bold="True" ForeColor="White" />
        <EditRowStyle BackColor="#999999" HorizontalAlign="Center" />
        <AlternatingRowStyle BackColor="White" ForeColor="#284775"
            HorizontalAlign="Center" />
    </asp:GridView>
</asp:Panel>

Is there some wais to make this script works for GridView ?..

and Ive got a trouble with hiding of vertical scrollbar if there is horizontal scroll bar (but that's trouble if I use commented code)

Body:
Couldn't you just have a new function that instantiates a new SortableTable? Or do you have to rewrite everything for some reason?

Something like:

function ScrollableTable(tableEl, tableHeight, tableWidth)
{
var table = new SortableTable(document.getElementById('myTable'), 100);
do stuff to the table that you whant..like width and height..
}


问:
Diff of two states of a string or array
For a string and an array, I have an "old" state, and a "new" state (after some modifications).

I need to often send to the server (with AJAX/XMLHttpRequest) the changes, if possible in an efficient way (don't resend 200 KB of data if only one element in the array has changed/has been deleted/has been moved). Example:

```<code>var oldstate1 = 'hello how are you? very good and you? thanks for asking! this text will be removed.';
var newstate1 = 'hello how are you? very good and you? new text here. thanks for asking!';

var oldstate2 = [[1732, "item1"], [1732, "will be deleted"], [23, "will be moved"], [23, "hello"]];
var newstate2 = [[23, "will be moved"], [1732, "item1"], [23, "hello"], [126, "new item"]];
</code>```

Of course, I could manually code a protocol between client and server with events such as delete, insert, move, update, etc. and send these events with AJAX, and the server would update its database accordingly. But this is quite tedious to do correctly.

Question: is there a more clever way to encode only changes between oldstate and newstate of a big string or array with Javascript? in a way that can easily be decoded on backend, running Python.

Something similar to a diff/patch algorithm for strings or arrays, understood between JS (client-side) and Python (back-end).

Note:

a solution for strings might be enough, the "array case" would be covered by the "string case" with JSON.stringigy(...)

related but doesn't solve directly the problem: How to get the difference between two arrays in JavaScript?

答:
It is probably possible with no third-party tool (if so, feel free to post another answer).

After further research, I found this project: diff-match-patch and particularly this example.

Originally built in 2006 to power Google Docs, this library is now available in C++, C#, Dart, Java, JavaScript, Lua, Objective C, and Python.

var oldstate1 = "hello how are you? very good and you? blablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablabla. thanks for asking! this text will be removed.";
var newstate1 = "hello how are you? very good and you? blablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablabla.new text here. thanks for asking!";
var dmp = new diff_match_patch();
var diff = dmp.diff_main(oldstate1, newstate1);
dmp.diff_cleanupSemantic(diff);
console.log(dmp.diff_toDelta(diff))
// =138 +new text here. =19 -27```
<pre class="snippet-code-html lang-html prettyprint-override"><code><script src="https://cdnjs.cloudflare.com/ajax/libs/diff_match_patch/20121119/diff_match_patch.js"></script></code>```

This delta + oldstate1 can then be used server-side, with Python, to reconstruct the newstate1:

```<code>import diff_match_patch as dmp_module
dmp = dmp_module.diff_match_patch()

oldstate1 = "hello how are you? very good and you? blablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablabla. thanks for asking! this text will be removed."
delta = "=138\t+new text here.\t=19\t-27"
patch = dmp.patch_make(oldstate1, dmp.diff_fromDelta(oldstate1, delta))
newstate1 = dmp.patch_apply(patch, oldstate1)[0]
print(newstate1)
</code>```

See also this issue.

Title: Diff of two states of a string or array

Body:
For a string and an array, I have an "old" state, and a "new" state (after some modifications).

I need to often send to the server (with AJAX/XMLHttpRequest) the changes, if possible in an efficient way (don't resend 200 KB of data if only one element in the array has changed/has been deleted/has been moved). Example:

var oldstate1 = 'hello how are you? very good and you? thanks for asking! this text will be removed.';
var newstate1 = 'hello how are you? very good and you? new text here. thanks for asking!';

var oldstate2 = [[1732, "item1"], [1732, "will be deleted"], [23, "will be moved"], [23, "hello"]];
var newstate2 = [[23, "will be moved"], [1732, "item1"], [23, "hello"], [126, "new item"]];

Of course, I could manually code a protocol between client and server with events such as delete, insert, move, update, etc. and send these events with AJAX, and the server would update its database accordingly. But this is quite tedious to do correctly.

Question: is there a more clever way to encode only changes between oldstate and newstate of a big string or array with Javascript? in a way that can easily be decoded on backend, running Python.

Something similar to a diff/patch algorithm for strings or arrays, understood between JS (client-side) and Python (back-end).

Note:

a solution for strings might be enough, the "array case" would be covered by the "string case" with JSON.stringigy(...)

related but doesn't solve directly the problem: How to get the difference between two arrays in JavaScript?

Body:
It is probably possible with no third-party tool (if so, feel free to post another answer).

After further research, I found this project: diff-match-patch and particularly this example.

Originally built in 2006 to power Google Docs, this library is now available in C++, C#, Dart, Java, JavaScript, Lua, Objective C, and Python.

var oldstate1 = "hello how are you? very good and you? blablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablabla. thanks for asking! this text will be removed.";
var newstate1 = "hello how are you? very good and you? blablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablabla.new text here. thanks for asking!";
var dmp = new diff_match_patch();
var diff = dmp.diff_main(oldstate1, newstate1);
dmp.diff_cleanupSemantic(diff);
console.log(dmp.diff_toDelta(diff))
// =138 +new text here. =19 -27

<script src="https://cdnjs.cloudflare.com/ajax/libs/diff_match_patch/20121119/diff_match_patch.js"></script>

This delta + oldstate1 can then be used server-side, with Python, to reconstruct the newstate1:

import diff_match_patch as dmp_module
dmp = dmp_module.diff_match_patch()

oldstate1 = "hello how are you? very good and you? blablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablabla. thanks for asking! this text will be removed."
delta = "=138\t+new text here.\t=19\t-27"
patch = dmp.patch_make(oldstate1, dmp.diff_fromDelta(oldstate1, delta))
newstate1 = dmp.patch_apply(patch, oldstate1)[0]
print(newstate1)

See also this issue.


问:
How to extend and style existing LitElements?
We want to work with components from https://github.com/ing-bank/lion and style them to our needs. Their repo advertises with the components being extensible and minimally styled. However, I cannot seem to figure out how to actually style them. We tried using style element in the parent component, but we cant seem to style these components properly.

Could you give me an example of how to extend a component?

update after answer by @niiyeboah
After a very nice answer by @niiyeboah, I created the following class:

```<code>import {css, customElement} from 'lit-element'
import {LionButton} from '@lion/button'

@customElement('my-custom-button')
class MyCustomButton extends LionButton {
  static get styles() {
    return [
      super.styles,
      css`
        :host {
          background-color: red;
        }
      `,
    ]
  }

  constructor() {
    super()
  }
}

</code>```

However, now it just shows be the button completely unstyled, i.e. only the text. Does anyone know whats happening?

答:
The ING Lion team has a Slack channel: https://www.polymer-project.org/slack-invite

for support questions.

It is the #lion sub-channel in the Polymer Project Slack

Body:
We want to work with components from https://github.com/ing-bank/lion and style them to our needs. Their repo advertises with the components being extensible and minimally styled. However, I cannot seem to figure out how to actually style them. We tried using style element in the parent component, but we cant seem to style these components properly.

Could you give me an example of how to extend a component?

update after answer by @niiyeboah
After a very nice answer by @niiyeboah, I created the following class:

import {css, customElement} from 'lit-element'
import {LionButton} from '@lion/button'

@customElement('my-custom-button')
class MyCustomButton extends LionButton {
  static get styles() {
    return [
      super.styles,
      css`
        :host {
          background-color: red;
        }
      `,
    ]
  }

  constructor() {
    super()
  }
}

However, now it just shows be the button completely unstyled, i.e. only the text. Does anyone know whats happening?


问:
Postman - Using complete response from one request as body of another request
I have a request were the exact response from one request is the body of another request.

Is there an easy way to store the response from one request to reuse as the body of another request in Postman?

I tried storing the response body in a global variable customerData and then having the body of my other request be {{customerData}} but this does not work.

Thanks for the help.

答:
```<code>API-1 - Test Tab

//Get the response of first API

var jsonData=JSON.parse(responseBody);

//Convert the JSON response to String

var jsonString=JSON.stringify(jsonData);

//Store in environment variable

pm.environment.set("MyPayLoad", jsonString);

API-2 - Body
{{MyPayLoad}}
</code>```

This way response from API-1 is passed as payload to API-2

Body:
API-1 - Test Tab

//Get the response of first API

var jsonData=JSON.parse(responseBody);

//Convert the JSON response to String

var jsonString=JSON.stringify(jsonData);

//Store in environment variable

pm.environment.set("MyPayLoad", jsonString);

API-2 - Body
{{MyPayLoad}}

This way response from API-1 is passed as payload to API-2


问:
R: subtract variable amount of columns from target column
I wish to make a function that takes in three arguments: a data.table, a target column and a vector of columns to subtract from the target column:

```<code>test = data.table(
  total = c(10,6,4,4,5,6),
  b = c(9,5,3,3,4,5),
  c = rep(1, 6),
  d = rep(2, 6)
)
</code>```

function(data, target = "total", cols = c("b", "c"))
should give desired output:

```<code>test = data.table(
  total = c(10,6,4,4,5,6),
  b = c(9,5,3,3,4,5),
  c = rep(1, 6),
  d = rep(2, 6),
  new_total = rep(0, 6)
)
</code>```

Attempts so far:

1)

```<code>testfunction <- function(dt, target, cols){
    dt[, new_total := target - .SD , .SDcols = cols]

}
</code>```

2)

```<code>testfunction <- function(dt, target, cols){
     temp = copy(dt[, .SD, .SDcols = cols])
     dt[, new_total := target - temp]

 }
</code>```

None of these work, and I think my attempt show a lack of understanding of data.table, unfortunately.

答:
Try this:

```<code>foo <- function(data, target = "total", cols = c("b", "c")) {
  data[, new_total := get(target) - rowSums(.SD), .SDcols = cols]
}

foo(test)[]

#    total b c d new_total
# 1:    10 9 1 2         0
# 2:     6 5 1 2         0
# 3:     4 3 1 2         0
# 4:     4 3 1 2         0
# 5:     5 4 1 2         0
# 6:     6 5 1 2         0
</code>```

The problems were

.SD is a data.table while target is just a vector.

to get a column with a string variable can't be done like this, you can, for example, use get(). More examples here.

Body:
I wish to make a function that takes in three arguments: a data.table, a target column and a vector of columns to subtract from the target column:

test = data.table(
  total = c(10,6,4,4,5,6),
  b = c(9,5,3,3,4,5),
  c = rep(1, 6),
  d = rep(2, 6)
)

function(data, target = "total", cols = c("b", "c"))
should give desired output:

test = data.table(
  total = c(10,6,4,4,5,6),
  b = c(9,5,3,3,4,5),
  c = rep(1, 6),
  d = rep(2, 6),
  new_total = rep(0, 6)
)

Attempts so far:

1)

testfunction <- function(dt, target, cols){
    dt[, new_total := target - .SD , .SDcols = cols]

}

2)

testfunction <- function(dt, target, cols){
     temp = copy(dt[, .SD, .SDcols = cols])
     dt[, new_total := target - temp]

 }

None of these work, and I think my attempt show a lack of understanding of data.table, unfortunately.

Body:
Try this:

foo <- function(data, target = "total", cols = c("b", "c")) {
  data[, new_total := get(target) - rowSums(.SD), .SDcols = cols]
}

foo(test)[]

#    total b c d new_total
# 1:    10 9 1 2         0
# 2:     6 5 1 2         0
# 3:     4 3 1 2         0
# 4:     4 3 1 2         0
# 5:     5 4 1 2         0
# 6:     6 5 1 2         0

The problems were

.SD is a data.table while target is just a vector.

to get a column with a string variable can't be done like this, you can, for example, use get(). More examples here.


问:
Django pagination dependent on ordering
I have the following model (simplified):

```<code>class Post(models.Model):
    title = models.CharField(max_length=20)
    date_created = models.DateTimeField(auto_now=True)

    class Meta:
        ordering = ('-date_created',) # note the "reverse" ordering here
</code>```

, then my custom DetailView based on generic.DetailView:

```<code>class PostDetailView(generic.DetailView):
    queryset = Post.objects.all()
</code>```

and, finally, the following template:

```<code>{% with object.get_previous_by_date_created as prev %}
    {% if prev %}
    <a class="nav-link-prev"
       href="{% url "blog:post_detail" pk=prev.id %}">Previous</a>
    {% endif %}
{% endwith %}

{% with object.get_next_by_date_created as next %}
    {% if next %}
    <a class="nav-link-next"
       href="{% url "blog:post_detail" pk=next.id %}">Next</a>
    {% endif %}
{% endwith %}
</code>```

My pagination implemented this way works, but due to the reverse ordering (i.e -date_created) field, its Previous/Next labels are misplaced. In other words my template outputs "Previous" where it should be "Next", and vice versa. If I remove a - sign in ordering = ('-date_created',) it will work fine, but that's not the ordering I would like to have on my website.

Is there an easy and idiomatic way of fixing this misbehavior? What am I missing?

答:
Add

```<code>ordering = ['-date_created']
</code>```

or

```<code>ordering = Post._meta.ordering
</code>```

to PostListView

Title: Django pagination dependent on ordering

Body:
I have the following model (simplified):

class Post(models.Model):
    title = models.CharField(max_length=20)
    date_created = models.DateTimeField(auto_now=True)

    class Meta:
        ordering = ('-date_created',) # note the "reverse" ordering here

, then my custom DetailView based on generic.DetailView:

class PostDetailView(generic.DetailView):
    queryset = Post.objects.all()

and, finally, the following template:

{% with object.get_previous_by_date_created as prev %}
    {% if prev %}
    Previous
    {% endif %}
{% endwith %}

{% with object.get_next_by_date_created as next %}
    {% if next %}
    Next
    {% endif %}
{% endwith %}

My pagination implemented this way works, but due to the reverse ordering (i.e -date_created) field, its Previous/Next labels are misplaced. In other words my template outputs "Previous" where it should be "Next", and vice versa. If I remove a - sign in ordering = ('-date_created',) it will work fine, but that's not the ordering I would like to have on my website.

Is there an easy and idiomatic way of fixing this misbehavior? What am I missing?

Body:
Add

ordering = ['-date_created']

or

ordering = Post._meta.ordering

to PostListView