问:
Duplicating Results when using Subquery, need to filter out Nulls and only show value if value exists
(Edited) I am having a problem with duplicating results when using a Count() Function and then Grouping by a column that changes from Null to having a value. See Below:

Here is a sample table of data:

```<code>t_order_table
  Line#     Order       User_Assigned
  1         12345       Null
  2         12345       Null
  3         12345       Null
  4         12345       Null
  5         12345       Null
  6         12345       Null
  7         12345       Null
  8         12345       Null
  9         12345       Null
  1         11223       Null
  2         11223       Null
  3         11223       Null
</code>```

Here is the script to report on the table(below):

```<code>Select Order,
(Select Count(Line#) from t_order_table ord
    Where User_Assigned is null
    and o.Order = ord.Order) as 'Open Lines',
(Select Count(Line#) from t_order_table ord
    Where User_Assigned is not null
    and o.Order = ord.Order) as 'Picked Lines',
(Select User_Assigned from t_order_table ord
    Where o.Order = ord.Order) as 'User Assigned'
from t_order_table o
Group By Order, User_Assigned
</code>```

Which Returns:

```<code>Order   Open Lines  Picked Lines    User_Assigned
12345       9           0               Null
11223       3           0               Null

</code>```

As a worker logs into the system, he gets assigned to the lines, one by one as he picks the order. After he picks 3 lines, the table would look like this:

```<code>t_order_table
  Line#     Order       User_Assigned
  1         12345       Chris
  2         12345       Chris
  3         12345       Chris
  4         12345       Null
  5         12345       Null
  6         12345       Null
  7         12345       Null
  8         12345       Null
  9         12345       Null
  1         11223       Null
  2         11223       Null
  3         11223       Null
</code>```

and the report would look like this:

```<code>Order   Open Lines  Picked Lines    User_Assigned
12345       9           3               Null
12345       9           3               Chris
11223       3           0               Null
</code>```

The Result has a duplicated record because the SubSelect Query for 'User_Assigned' found a null and a user, so there is two records. I would like there to be some logic that checks if a user is assigned, it returns the user, else returns null. I can't figure out how to do that. Thanks for the help!!!!

答:
This seems to give you what you need.

```<code>set transaction isolation level read uncommitted;

declare @OrderTable as table
(
    [Line] tinyint,
    [Order] int,
    [User_Assigned] nvarchar(50)
);
insert into @OrderTable
(
    [Line],
    [Order],
    [User_Assigned]
)
values
(1, 12345, 'Chris'),
(2, 12345, 'Chris'),
(3, 12345, 'Chris'),
(4, 12345, null),
(5, 12345, null),
(6, 12345, null),
(7, 12345, null),
(8, 12345, null),
(9, 12345, null),
(1, 11223, null),
(2, 11223, null),
(3, 11223, null);

select
    o.[Order],
    sum(iif(o.User_Assigned is null, 1, 0)) as [OpenLines],
    sum(iif(o.User_Assigned is not null, 1, 0)) as [PickedLines],
    max(o.User_Assigned) as [User_Assigned]
from @OrderTable as [o]
group by
    o.[Order]
</code>```

Returns:

```<code>Order   OpenLines   PickedLines User_Assigned
11223   3           0           NULL
12345   6           3           Chris
</code>```

Body:
(Edited) I am having a problem with duplicating results when using a Count() Function and then Grouping by a column that changes from Null to having a value. See Below:

Here is a sample table of data:

t_order_table
  Line#     Order       User_Assigned
  1         12345       Null
  2         12345       Null
  3         12345       Null
  4         12345       Null
  5         12345       Null
  6         12345       Null
  7         12345       Null
  8         12345       Null
  9         12345       Null
  1         11223       Null
  2         11223       Null
  3         11223       Null

Here is the script to report on the table(below):

Select Order,
(Select Count(Line#) from t_order_table ord
    Where User_Assigned is null
    and o.Order = ord.Order) as 'Open Lines',
(Select Count(Line#) from t_order_table ord
    Where User_Assigned is not null
    and o.Order = ord.Order) as 'Picked Lines',
(Select User_Assigned from t_order_table ord
    Where o.Order = ord.Order) as 'User Assigned'
from t_order_table o
Group By Order, User_Assigned

Which Returns:

Order   Open Lines  Picked Lines    User_Assigned
12345       9           0               Null
11223       3           0               Null

As a worker logs into the system, he gets assigned to the lines, one by one as he picks the order. After he picks 3 lines, the table would look like this:

t_order_table
  Line#     Order       User_Assigned
  1         12345       Chris
  2         12345       Chris
  3         12345       Chris
  4         12345       Null
  5         12345       Null
  6         12345       Null
  7         12345       Null
  8         12345       Null
  9         12345       Null
  1         11223       Null
  2         11223       Null
  3         11223       Null

and the report would look like this:

Order   Open Lines  Picked Lines    User_Assigned
12345       9           3               Null
12345       9           3               Chris
11223       3           0               Null

The Result has a duplicated record because the SubSelect Query for 'User_Assigned' found a null and a user, so there is two records. I would like there to be some logic that checks if a user is assigned, it returns the user, else returns null. I can't figure out how to do that. Thanks for the help!!!!

Body:
This seems to give you what you need.

set transaction isolation level read uncommitted;

declare @OrderTable as table
(
    [Line] tinyint,
    [Order] int,
    [User_Assigned] nvarchar(50)
);
insert into @OrderTable
(
    [Line],
    [Order],
    [User_Assigned]
)
values
(1, 12345, 'Chris'),
(2, 12345, 'Chris'),
(3, 12345, 'Chris'),
(4, 12345, null),
(5, 12345, null),
(6, 12345, null),
(7, 12345, null),
(8, 12345, null),
(9, 12345, null),
(1, 11223, null),
(2, 11223, null),
(3, 11223, null);

select
    o.[Order],
    sum(iif(o.User_Assigned is null, 1, 0)) as [OpenLines],
    sum(iif(o.User_Assigned is not null, 1, 0)) as [PickedLines],
    max(o.User_Assigned) as [User_Assigned]
from @OrderTable as [o]
group by
    o.[Order]

Returns:

Order   OpenLines   PickedLines User_Assigned
11223   3           0           NULL
12345   6           3           Chris


来源: stackexchange

问:
Sphinx does not show local headings in TOC
When generating sphinx documentation using the default settings (including the Alabaster theme), the TOC sidebar only shows the top level headings for the entire document. It used to show the second-plus level headings for the current page. How do I fix this?

(Note: IIRC this used to be affected by whether or not globaltoc.html or localtoc.html was included in html_sidebars, but it seems with Alabaster and/or recent versions, neither of those exist.)

答:
It turns out this is due to a stupid and easy-to-overlook default when generating a new Sphinx project. Specifically, the default TOC looks like:

```<code>.. toctree::
    :maxdepth: 1
    :caption: Contents:

    overview
    topic1
    topic2
    ...

</code>```

The problem is the maxdepth. It turns out this doesn't just control the number of heading levels that will be displayed in the TOC that appears in the body of the index page, but also the local TOC depth as it appears in the sidebar. Apparently, new projects get a maxdepth of 1, which means that no local TOC's will be seen.

ContentLicense: CC BY-SA 4.0

Body:
It turns out this is due to a stupid and easy-to-overlook default when generating a new Sphinx project. Specifically, the default TOC looks like:

.. toctree::
    :maxdepth: 1
    :caption: Contents:

    overview
    topic1
    topic2
    ...

The problem is the maxdepth. It turns out this doesn't just control the number of heading levels that will be displayed in the TOC that appears in the body of the index page, but also the local TOC depth as it appears in the sidebar. Apparently, new projects get a maxdepth of 1, which means that no local TOC's will be seen.


问:
How to run a set of dependent groovy scripts without compilation?
I've got a set of groovy scripts (or should I say a groovy app) which has hierarchical java alike package structure and script names the same as class names. All of them are called from the main script (like a java class with main method). I need to call just that particular main script and get all other scripts executed in sequence when needed (or loaded and executed).

Practically, this can be acieved by having all scripts compiled and .class files obtained and put into classpath while running the main script, but that's quite redundant for a scripting (the idea is to have it working without compilation, even though groovy will do it somwhere behind the scene)

How can I achieve it?

答:
Groovy can be used in a scripting environment quite easily - no compile step required.  Read this:

http://groovy.codehaus.org/Running

You can write your usual main method etc. and call it like this,

```<code>groovy -cp foo/ foo/MyScript.groovy [arguments]
</code>```

Or if you're in a *nix environment you can give it a shebang like so,

```<code>#!/usr/bin/env groovy
println("Hello world")
for (a in this.args) {
  println("Argument: " + a)
}
</code>```

and run it using ./fileName (provided you've marked it as executable)

ContentLicense: CC BY-SA 3.0

Body:
Groovy can be used in a scripting environment quite easily - no compile step required.  Read this:

http://groovy.codehaus.org/Running

You can write your usual main method etc. and call it like this,

groovy -cp foo/ foo/MyScript.groovy [arguments]

Or if you're in a *nix environment you can give it a shebang like so,

#!/usr/bin/env groovy
println("Hello world")
for (a in this.args) {
  println("Argument: " + a)
}

and run it using ./fileName (provided you've marked it as executable)


问:
Is it necessary for converting all angularjs controllers into angularjs components(v1.5+) for making the hybrid app work?
I have a pretty large AngularJS(v1.5) application which contains numerous controllers. I want to migrate the app to the latest Angular version(v7) using the upgrade module which runs both the old and the new frameworks together, allowing for an incremental approach to the upgrade. So my question is, do I need to convert all my controllers into component directives(introduced from v1.5+) before using the upgrade module to make my hybrid app work?  Or can we first make the hybrid app with the controllers as it is and then convert each angularJS controller into angular components?

Another question related to the hybrid approach, the new files which I have been creating(related to the angular framework) are in typescript format. Do I need to convert all the old javascript files into typescript to make the hybrid app work?

答:
You probably already read this but in case you haven't...

https://angular.io/guide/upgrade

under Preparation is says:

Follow the AngularJS Style Guide

Using a Module Loader

Migrating to TypeScript

Using Component Directives


问:
Can I do this with data.table without using the merge() function?
I work with very huge datasets and I'm trying to speed up my R code.
Here is an example of data :

```<code>dt <- data.table(id = c(100,101,102,103, 104), sex = c("m","f","m","m","f"),
value = c(32,14,32,03,03))

data look like this :
    id sex value
1: 100   m    32
2: 101   f    14
3: 102   m    32
4: 103   m     3
5: 104   f     3
</code>```

The final output I want :

```<code>   value f.value m.value f   m
1:     3    1       1    1   1
2:    14    1       NA   1   NA
3:    32    NA      2    NA  2
</code>```

The code I currently use :

```<code>dt_u <- unique(dt, by = c("id", "sex", "value"))
dt_u <- dt_u[, .(n = .N), keyby = .(value, sex)]
dt_u <- dcast(dt_u, value ~ sex, value.var = "n")
dt_t <- dt[, .(n = .N), keyby = .(value, sex)]
dt_t <- dcast(dt_t, value ~ sex, value.var = "n")
dt <- merge(dt_t, dt_u, by = "value", all = TRUE)
</code>```

The code is working great, the problem is that the merging of dt_u and dt_t can take a lot of time on 10GB + data. So my question is : Is it possible to get the same final output without having to "split" the data and then merging it?

Also I would like the answer to be in data.table if possible,
thank you.

EDIT : example and explaination. The ID represent a person, this person can go to the same location (value) more than one time. For this example you can say that each value represent a different city.

IE:

```<code>dt <- data.table(value = c(21,21,21,21,21,40,1,22,1,1,22, 22, 49,
49,21,21,1,1,1), id =
c(1000716624,1000722724,1000716624,1000746824,1001012024,
1002067324,1002743624,1002743645, 1002743636,
1002743423,1000716624,1000722724, 1000722724,1001012024,
1000716624,1000716624,1002743624,1002743624,1002743624), sex = c("f", "m",
"m", "m", "f", "f", "m", "f", "f", "m", "f", "m", "m", "f","f","f", "m",
"m", "m"))
</code>```

Output :

```<code> value   places_women   places_men  number_women   number_men
1:     1            1          5            1          2
2:    21            4          3            2          3
3:    22            2          1            2          1
4:    40            1         NA            1         NA
5:    49            1          1            1          1
</code>```

答:
library(data.table)

dt <- data.table(id = c(100,101,102,103, 104), sex = c("m","f","m","m","f"),
                 value = c(32,14,32,03,03))

dcast(unique(unique(dt,
                    by = c("id", "sex", "value"))[ ,

            count := .N, by = list(value,sex)][,
        id:=NULL]),
value ~ sex, value.var = "count")

#>    value  f  m
#> 1:     3  1  1
#> 2:    14  1 NA
#> 3:    32 NA  2
```

Created on 2019-05-29 by the reprex package (v0.3.0)

Body:
I work with very huge datasets and I'm trying to speed up my R code.
Here is an example of data :

dt <- data.table(id = c(100,101,102,103, 104), sex = c("m","f","m","m","f"),
value = c(32,14,32,03,03))

data look like this :
    id sex value
1: 100   m    32
2: 101   f    14
3: 102   m    32
4: 103   m     3
5: 104   f     3

The final output I want :

   value f.value m.value f   m
1:     3    1       1    1   1
2:    14    1       NA   1   NA
3:    32    NA      2    NA  2

The code I currently use :

dt_u <- unique(dt, by = c("id", "sex", "value"))
dt_u <- dt_u[, .(n = .N), keyby = .(value, sex)]
dt_u <- dcast(dt_u, value ~ sex, value.var = "n")
dt_t <- dt[, .(n = .N), keyby = .(value, sex)]
dt_t <- dcast(dt_t, value ~ sex, value.var = "n")
dt <- merge(dt_t, dt_u, by = "value", all = TRUE)

The code is working great, the problem is that the merging of dt_u and dt_t can take a lot of time on 10GB + data. So my question is : Is it possible to get the same final output without having to "split" the data and then merging it?

Also I would like the answer to be in data.table if possible,
thank you.

EDIT : example and explaination. The ID represent a person, this person can go to the same location (value) more than one time. For this example you can say that each value represent a different city.

IE:

dt <- data.table(value = c(21,21,21,21,21,40,1,22,1,1,22, 22, 49,
49,21,21,1,1,1), id =
c(1000716624,1000722724,1000716624,1000746824,1001012024,
1002067324,1002743624,1002743645, 1002743636,
1002743423,1000716624,1000722724, 1000722724,1001012024,
1000716624,1000716624,1002743624,1002743624,1002743624), sex = c("f", "m",
"m", "m", "f", "f", "m", "f", "f", "m", "f", "m", "m", "f","f","f", "m",
"m", "m"))

Output :

 value   places_women   places_men  number_women   number_men
1:     1            1          5            1          2
2:    21            4          3            2          3
3:    22            2          1            2          1
4:    40            1         NA            1         NA
5:    49            1          1            1          1

Body:
library(data.table)

dt <- data.table(id = c(100,101,102,103, 104), sex = c("m","f","m","m","f"),
                 value = c(32,14,32,03,03))

dcast(unique(unique(dt,
                    by = c("id", "sex", "value"))[ ,

            count := .N, by = list(value,sex)][,
        id:=NULL]),
value ~ sex, value.var = "count")

#>    value  f  m
#> 1:     3  1  1
#> 2:    14  1 NA
#> 3:    32 NA  2

Created on 2019-05-29 by the reprex package (v0.3.0)


问:
How to recreate the 'take' function by list comprehension in Haskell?
The below code recreate the 'take' function in Haskell by recursion:

```<code>take' :: Int->[a]->[a]
take' 0 _=[]
take' _ []= []
take' n (x:xs)=x : take' (n-1) xs
</code>```

I want to create 'take' function using list comprehension:

```<code>take' n a=[x|x<-a]
</code>```

答:
With the ParallelListComp extension, a list comprehension can zip:</p>

```<code>{-# LANGUAGE ParallelListComp #-}

take' n a = [x | x <- a | _ <- [1..n]]
</code>```

Body:
The below code recreate the 'take' function in Haskell by recursion:

take' :: Int->[a]->[a]
take' 0 _=[]
take' _ []= []
take' n (x:xs)=x : take' (n-1) xs

I want to create 'take' function using list comprehension:

take' n a=[x|x<-a]

Body:
With the ParallelListComp extension, a list comprehension can zip:

{-# LANGUAGE ParallelListComp #-}

take' n a = [x | x <- a | _ <- [1..n]]


问:
How to enable MODE_NIGHT_YES in every activity with setLocalNightMode()?
I recently wanted to create a setting, to enable a night mode in my android app, i searched in the internet and found a nice solution with AppCompatDelegate´s DayNight theme and a short code fragment... :

```<code>if(settingsSharedPreferences.getBoolean(getString(R.string.design_dark_design_key),false))
    {
        getDelegate().setLocalNightMode(AppCompatDelegate.MODE_NIGHT_YES);
    }
</code>```

...to enable dark mode for my MainActivity, if it is enabled in my app settings. It worked perfectly and changed my MainActivity in "DarkMode"! But if i open another activity, this not appears in dark mode like main activity, but if i add the code lines above to this new activity it also starts with dark mode. So my question:

Do i have to call this code lines in every activity or is there a way to set global night mode for any activity in my app?

UPDATE:

I just called the code baove in a new activity before the super.onCreate() and setContentView() methods and my whole app theme changed. But if i call it in MainActivity just the Theme of my MainActivity changes... Its really strange.
Can i change whole theme also in MainActivity?

Thank you in advanced!

答:
Ok, I've found a solution!
For anyone who has the same problem, this is the correct way to apply dark design for your whole application:
I got it from this NICE site

https://blog.iamsuleiman.com/daynight-theme-android-tutorial-example/

It's pretty easy, you just have to use:

```<code>AppCompatDelegate.setDefaultNightMode(mode);
</code>```

instead of

```<code>getDelegate().setLocalNightMode(mode);
</code>```

Quite easy, but really useful!!! Happy coding.

Sorry for my English, I'm German :)

Body:
I recently wanted to create a setting, to enable a night mode in my android app, i searched in the internet and found a nice solution with AppCompatDelegate´s DayNight theme and a short code fragment... :

if(settingsSharedPreferences.getBoolean(getString(R.string.design_dark_design_key),false))
    {
        getDelegate().setLocalNightMode(AppCompatDelegate.MODE_NIGHT_YES);
    }

...to enable dark mode for my MainActivity, if it is enabled in my app settings. It worked perfectly and changed my MainActivity in "DarkMode"! But if i open another activity, this not appears in dark mode like main activity, but if i add the code lines above to this new activity it also starts with dark mode. So my question:

Do i have to call this code lines in every activity or is there a way to set global night mode for any activity in my app?

UPDATE:

I just called the code baove in a new activity before the super.onCreate() and setContentView() methods and my whole app theme changed. But if i call it in MainActivity just the Theme of my MainActivity changes... Its really strange.
Can i change whole theme also in MainActivity?

Thank you in advanced!

Body:
Ok, I've found a solution!
For anyone who has the same problem, this is the correct way to apply dark design for your whole application:
I got it from this NICE site

https://blog.iamsuleiman.com/daynight-theme-android-tutorial-example/

It's pretty easy, you just have to use:

AppCompatDelegate.setDefaultNightMode(mode);

instead of

getDelegate().setLocalNightMode(mode);

Quite easy, but really useful!!! Happy coding.

Sorry for my English, I'm German :)


问:
How to use R to download a file from webpage when there is no specific file embedded on the page
Is there any possible solution to extract the file from any website when there is no specific file uploaded using download.file() in R.

I have this url

```<code>https://www.fangraphs.com/leaders.aspx?pos=all&stats=bat&lg=all&qual=y&type=8&season=2016&month=0&season1=2016&ind=0
</code>```

there is a link to export csv file to my working directory, but when i right click on the export data hyperlink on the webpage and select the link address
it turns to be the following script

```<code>javascript:__doPostBack('LeaderBoard1$cmdCSV','')
</code>```

instead of the url which give me access to the csv file.

Is there any solution to tackle this problem.

答:
You can use RSelenium for jobs like this. The script below works for me exactly as is, and it should for you as well with minor edits noted in the text. The solution uses two packages: RSelenium to automate Chrome, and here to select your active directory.

library(RSelenium)
library(here)
```

<p>Here's the URL you provided:</p>

<pre class="lang-r prettyprint-override"><code>url <- paste0(
  "https://www.fangraphs.com/leaders.aspx",
  "?pos=all",
  "&stats=bat",
  "&lg=all",
  "&qual=y",
  "&type=8",
  "&season=2016",
  "&month=0",
  "&season1=2016",
  "&ind=0"
)
</code>```

Here's the ID of the download button. You can find it by right-clicking the button in Chrome and hitting "Inspect."

button_id <- "LeaderBoard1_cmdCSV"
```

<p>We're going to automate Chrome to download the file, and it's going to go to your default download location. At the end of the script we'll want to move it to your current directory. So first let's set the name of the file (per fangraphs.com) and your download location (which you should <strong>edit as needed</strong>):</p>

<pre class="lang-r prettyprint-override"><code>filename <- "FanGraphs Leaderboard.csv"
download_location <- file.path(Sys.getenv("USERPROFILE"), "Downloads")
</code>```

Now you'll want to start a browser session. I use Chrome, and specifying this particular Chrome version (using the chromever argument) works for me. YMMV; check the best way to start a browser session for you.

An rsDriver object has two parts: a server and a browser client. Most of the magic happens in the browser client.

driver <- rsDriver(
  browser = "chrome",
  chromever = "74.0.3729.6"
)
server <- driver$server
browser <- driver$client
```

<p>Using the browser client, navigate to the page and click that button.</p>

<p>Quick note before you do: <code>RSelenium</code> may start looking for the button and trying to click it before there's anything to click. So I added a few lines to watch for the button to show up, and then click it once it's there.</p>

<pre class="lang-r prettyprint-override"><code>buttons <- list()
browser$navigate(url)
while (length(buttons) == 0) {
  buttons <- browser$findElements(button_id, using = "id")
}
buttons[[1]]$clickElement()
</code>```

Then wait for the file to show up in your downloads folder, and move it to the current project directory:

while (!file.exists(file.path(download_location, filename))) {
  Sys.sleep(0.1)
}
file.rename(file.path(download_location, filename), here(filename))
```

<p>Lastly, always clean up your server and browser client, or <code>RSelenium</code> gets quirky with you.</p>

<pre class="lang-r prettyprint-override"><code>browser$close()
server$stop()
</code>```

And you're on your merry way!

Note that you won't always have an element ID to use, and that's OK. IDs are great because they uniquely identify an element and using them requires almost no knowledge of website language. But if you don't have an ID to use, above where I specify using = "id", you have a lot of other options:

using = "xpath"

using = "css selector"

using = "name"

using = "tag name"

using = "class name"

using = "link text"

using = "partial link text"

Those give you a ton of alternatives and really allow you to identify anything on the page. findElements will always return a list. If there's nothing to find, that list will be of length zero. If it finds multiple elements, you'll get all of them.

XPath and CSS selectors in particular are super versatile. And you can find them without really knowing what you're doing. Let's walk through an example with the "Sign In" button on that page, which in fact does not have an ID.

Start in Chrome by pretty Control+Shift+J to get the Developer Console. In the upper left corner of the panel that shows up is a little icon for selecting elements:

Click that, and then click on the element you want:

That'll pull it up (highlight it) over in the "Elements" panel. Right-click the highlighted line and click "Copy selector." You can also click "Copy XPath," if you want to use XPath.

And that gives you your code!

buttons <- browser$findElements(
  "#linkAccount > div > div.label-account",
  using = "css selector"
)
buttons[[1]]$clickElement()
```

Boom.

Body:
Is there any possible solution to extract the file from any website when there is no specific file uploaded using download.file() in R.

I have this url

https://www.fangraphs.com/leaders.aspx?pos=all&stats=bat&lg=all&qual=y&type=8&season=2016&month=0&season1=2016&ind=0

there is a link to export csv file to my working directory, but when i right click on the export data hyperlink on the webpage and select the link address
it turns to be the following script

javascript:__doPostBack('LeaderBoard1$cmdCSV','')

instead of the url which give me access to the csv file.

Is there any solution to tackle this problem.

Body:
You can use RSelenium for jobs like this. The script below works for me exactly as is, and it should for you as well with minor edits noted in the text. The solution uses two packages: RSelenium to automate Chrome, and here to select your active directory.

library(RSelenium)
library(here)

Here's the URL you provided:

url <- paste0(
  "https://www.fangraphs.com/leaders.aspx",
  "?pos=all",
  "&stats=bat",
  "&lg=all",
  "&qual=y",
  "&type=8",
  "&season=2016",
  "&month=0",
  "&season1=2016",
  "&ind=0"
)

Here's the ID of the download button. You can find it by right-clicking the button in Chrome and hitting "Inspect."

button_id <- "LeaderBoard1_cmdCSV"

We're going to automate Chrome to download the file, and it's going to go to your default download location. At the end of the script we'll want to move it to your current directory. So first let's set the name of the file (per fangraphs.com) and your download location (which you should edit as needed):

filename <- "FanGraphs Leaderboard.csv"
download_location <- file.path(Sys.getenv("USERPROFILE"), "Downloads")

Now you'll want to start a browser session. I use Chrome, and specifying this particular Chrome version (using the chromever argument) works for me. YMMV; check the best way to start a browser session for you.

An rsDriver object has two parts: a server and a browser client. Most of the magic happens in the browser client.

driver <- rsDriver(
  browser = "chrome",
  chromever = "74.0.3729.6"
)
server <- driver$server
browser <- driver$client

Using the browser client, navigate to the page and click that button.

Quick note before you do: RSelenium may start looking for the button and trying to click it before there's anything to click. So I added a few lines to watch for the button to show up, and then click it once it's there.

buttons <- list()
browser$navigate(url)
while (length(buttons) == 0) {
  buttons <- browser$findElements(button_id, using = "id")
}
buttons[[1]]$clickElement()

Then wait for the file to show up in your downloads folder, and move it to the current project directory:

while (!file.exists(file.path(download_location, filename))) {
  Sys.sleep(0.1)
}
file.rename(file.path(download_location, filename), here(filename))

Lastly, always clean up your server and browser client, or RSelenium gets quirky with you.

browser$close()
server$stop()

And you're on your merry way!

Note that you won't always have an element ID to use, and that's OK. IDs are great because they uniquely identify an element and using them requires almost no knowledge of website language. But if you don't have an ID to use, above where I specify using = "id", you have a lot of other options:

using = "xpath"

using = "css selector"

using = "name"

using = "tag name"

using = "class name"

using = "link text"

using = "partial link text"

Those give you a ton of alternatives and really allow you to identify anything on the page. findElements will always return a list. If there's nothing to find, that list will be of length zero. If it finds multiple elements, you'll get all of them.

XPath and CSS selectors in particular are super versatile. And you can find them without really knowing what you're doing. Let's walk through an example with the "Sign In" button on that page, which in fact does not have an ID.

Start in Chrome by pretty Control+Shift+J to get the Developer Console. In the upper left corner of the panel that shows up is a little icon for selecting elements:

Click that, and then click on the element you want:

That'll pull it up (highlight it) over in the "Elements" panel. Right-click the highlighted line and click "Copy selector." You can also click "Copy XPath," if you want to use XPath.

And that gives you your code!

buttons <- browser$findElements(
  "#linkAccount > div > div.label-account",
  using = "css selector"
)
buttons[[1]]$clickElement()

Boom.


问:
How to add dropdown list which contains all element in my product list
I can iterate over different products using

```<code><li
{ % if not category % }class = "selected" {% endif % }>

<a href="{% url "shop:product_list" %}">All</a>

</li>

{% for c in categories %}

    <li {% if category.slug == c.slug %}class="selected"{% endif %}>
        <a href="{{ c.get_absolute_url }}">{{ c.name }}</a>
    </li>
{% endfor %}
</code>```

this is my code for a dropdown list, but it is not showing anything after books.

```<code><li class="nav-item dropdown ">
    <a class="nav-link dropdown-toggle" href="#" id="navbardrop" data-toggle="dropdown">
        Categories
    </a>
    <p class=" dropdown-menu ">
        <a class="dropdown-item" href="{% url 'shop:product_list' %}">All</a>
        <a class="dropdown-item" href="#">Electronics</a>
        <a class="dropdown-item" href="#">Books</a>

    <ul>
        <li {% if not category %}class="selected"{% endif %}>
            <a href="{% url "shop:product_list" %}">All</a>
        </li>
        {% for c in categories %}
            <li {% if category.slug == c.slug %}class="selected"{% endif %}>
                <a class="dropdown-item" href="{{ c.get_absolute_url }}">{{ c.name }}</a>
            </li>
        {% endfor %}
    </ul>

    </p>
</li>
</code>```

I want to add this code to my dropdown list

```<code>        <li {% if not category %}class="selected"{% endif %}>
            <a href="{% url "shop:product_list" %}">All</a>
        </li>
        {% for c in categories %}
            <li {% if category.slug == c.slug %}class="selected"{% endif %}>
                <a class="dropdown-item" href="{{ c.get_absolute_url }}">{{ c.name }}</a>
            </li>
        {% endfor %}
</code>```

but this code is showing nothing in the drop down list

my views.py file:

```<code>from django.shortcuts import render, get_object_or_404

from .models import Category, Product

def product_list(request, category_slug=None):
    category = None
    categories = Category.objects.all()
    products = Product.objects.filter(available=True)
    if category_slug:
        category = get_object_or_404(Category, slug=category_slug)
        products = products.filter(category=category)

    return render(request, 'shop/products/list.html', {
        'category': category,
        'categories': categories,
        'products': products
    })
</code>```

my models.py:

```<code>from django.db import models
from django.urls import reverse

class Category(models.Model):
    name = models.CharField(max_length=200, db_index=True)
    slug = models.SlugField(max_length=200, db_index=True, unique=True)

    class Meta:
        ordering = ('name',)
        verbose_name = 'category'
        verbose_name_plural = 'categories'

    def __str__(self):
        return self.name

    def get_absolute_url(self):
        return reverse('shop:product_list_by_category', args=[self.slug])

class Product(models.Model):
    category = models.ForeignKey(Category, related_name='products', on_delete=True)
    name = models.CharField(max_length=200, db_index=True)
    slug = models.SlugField(max_length=200, db_index=True, unique=True)
    image = models.ImageField(upload_to='products/%y/%m/%d', blank=True)
    description = models.TextField(blank=True)
    price = models.DecimalField(max_digits=10, decimal_places=2)
    stock = models.PositiveIntegerField()
    available = models.BooleanField(default=True)
    created = models.DateTimeField(auto_now_add=True)
    updated = models.DateTimeField(auto_now_add=True)

    class Meta:
        ordering = ('-created',)
        index_together = (('id', 'slug'),)

    def __str__(self):
        return self.name
</code>```

--------------------------------------------------------------------------------

答: I think that it is because you are nesting a ul inside a p and it is invalid HTML.

Body:
I can iterate over different products using

All

{% for c in categories %}

        {{ c.name }}

{% endfor %}

this is my code for a dropdown list, but it is not showing anything after books.

        Categories

        All
        Electronics
        Books

            All

        {% for c in categories %}

                {{ c.name }}

        {% endfor %}

I want to add this code to my dropdown list

            All

        {% for c in categories %}

                {{ c.name }}

        {% endfor %}

but this code is showing nothing in the drop down list

my views.py file:

from django.shortcuts import render, get_object_or_404

from .models import Category, Product

def product_list(request, category_slug=None):
    category = None
    categories = Category.objects.all()
    products = Product.objects.filter(available=True)
    if category_slug:
        category = get_object_or_404(Category, slug=category_slug)
        products = products.filter(category=category)

    return render(request, 'shop/products/list.html', {
        'category': category,
        'categories': categories,
        'products': products
    })

my models.py:

from django.db import models
from django.urls import reverse

class Category(models.Model):
    name = models.CharField(max_length=200, db_index=True)
    slug = models.SlugField(max_length=200, db_index=True, unique=True)

    class Meta:
        ordering = ('name',)
        verbose_name = 'category'
        verbose_name_plural = 'categories'

    def __str__(self):
        return self.name

    def get_absolute_url(self):
        return reverse('shop:product_list_by_category', args=[self.slug])

class Product(models.Model):
    category = models.ForeignKey(Category, related_name='products', on_delete=True)
    name = models.CharField(max_length=200, db_index=True)
    slug = models.SlugField(max_length=200, db_index=True, unique=True)
    image = models.ImageField(upload_to='products/%y/%m/%d', blank=True)
    description = models.TextField(blank=True)
    price = models.DecimalField(max_digits=10, decimal_places=2)
    stock = models.PositiveIntegerField()
    available = models.BooleanField(default=True)
    created = models.DateTimeField(auto_now_add=True)
    updated = models.DateTimeField(auto_now_add=True)

    class Meta:
        ordering = ('-created',)
        index_together = (('id', 'slug'),)

    def __str__(self):
        return self.name

--------------------------------------------------------------------------------


问:
Expand Variadic Template Pack by Pairs
I'm creating a generic collection of Nodes. Each Node has a Start and End type. And the End type of one must match the Start type of the next.

If I were to list each of the types in the collection the constructor would look like this (for four types):

```<code>template <typename Start, typename End>
class Node {
};

template <typename A, typename B, typename C, typename D>
class Collection
{
public:
    Collection(Node<A, B> n1, Node<B, C> n2, Node<C, D> n3) { }
};
</code>```

But when I try to write constuctor as a variadic template to support any number of types, I am stumped.

答:
I propose a little different solution.

Given a trivial tag struct to wrap a generic type (to avoid problems with types not default constructible in std::tupless)

```<code>template <typename>
struct tag
 { };
</code>```

and an helper struct that define 2 types based on std::tuple

```<code>template <typename...>
struct getTpls;

template <std::size_t ... Is, typename ... Ts>
struct getTpls<std::index_sequence<Is...>, Ts...>
 {
   using tpl0 = std::tuple<tag<Ts>...>;
   using ftpl = std::tuple<std::tuple_element_t<Is,    tpl0>...>;
   using stpl = std::tuple<std::tuple_element_t<1u+Is, tpl0>...>;
 };
</code>```

you can write Collection as follows

```<code>template <typename ... Ts>
struct Collection
 {
   static_assert( sizeof...(Ts) > 1u, "more types, please");

   using getT = getTpls<std::make_index_sequence<sizeof...(Ts)-1u>, Ts...>;

   using ftpl = typename getT::ftpl;
   using stpl = typename getT::stpl;

   template <typename ... FTs, typename ... STs,
             std::enable_if_t<
                 std::is_same_v<ftpl, std::tuple<tag<FTs>...>>
              && std::is_same_v<stpl, std::tuple<tag<STs>...>>, int> = 0>
   Collection (Node<FTs, STs> ...)
    { }
 };
</code>```

The following is a full compiling example

```<code>#include <tuple>
#include <type_traits>

template <typename Start, typename End>
class Node
 { };

struct A {};
struct B {};
struct C {};

template <typename>
struct tag
 { };

template <typename...>
struct getTpls;

template <std::size_t ... Is, typename ... Ts>
struct getTpls<std::index_sequence<Is...>, Ts...>
 {
   using tpl0 = std::tuple<tag<Ts>...>;
   using ftpl = std::tuple<std::tuple_element_t<Is,    tpl0>...>;
   using stpl = std::tuple<std::tuple_element_t<1u+Is, tpl0>...>;
 };

template <typename ... Ts>
struct Collection
 {
   static_assert( sizeof...(Ts) > 1u, "more types, please");

   using getT = getTpls<std::make_index_sequence<sizeof...(Ts)-1u>, Ts...>;

   using ftpl = typename getT::ftpl;
   using stpl = typename getT::stpl;

   template <typename ... FTs, typename ... STs,
             std::enable_if_t<
                 std::is_same_v<ftpl, std::tuple<tag<FTs>...>>
              && std::is_same_v<stpl, std::tuple<tag<STs>...>>, int> = 0>
   Collection (Node<FTs, STs> ...)
    { }
 };

int main ()
 {
   Collection<A, B, C>  c0{Node<A, B>{}, Node<B, C>{}};    // compile
   // Collection<A, B, B>  c1{Node<A, B>{}, Node<B, C>{}}; // error!
 }
</code>```

Title: Expand Variadic Template Pack by Pairs

Body:
I'm creating a generic collection of Nodes. Each Node has a Start and End type. And the End type of one must match the Start type of the next.

If I were to list each of the types in the collection the constructor would look like this (for four types):

template <typename Start, typename End>
class Node {
};

template <typename A, typename B, typename C, typename D>
class Collection
{
public:
    Collection(Node n1, Node n2, Node<C, D> n3) { }
};

But when I try to write constuctor as a variadic template to support any number of types, I am stumped.

Body:
I propose a little different solution.

Given a trivial tag struct to wrap a generic type (to avoid problems with types not default constructible in std::tupless)

template <typename>
struct tag
 { };

and an helper struct that define 2 types based on std::tuple

template <typename...>
struct getTpls;

template <std::size_t ... Is, typename ... Ts>
struct getTpls<std::index_sequence<Is...>, Ts...>
 {
   using tpl0 = std::tuple<tag<Ts>...>;
   using ftpl = std::tuple<std::tuple_element_t<Is,    tpl0>...>;
   using stpl = std::tuple<std::tuple_element_t<1u+Is, tpl0>...>;
 };

you can write Collection as follows

template <typename ... Ts>
struct Collection
 {
   static_assert( sizeof...(Ts) > 1u, "more types, please");

   using getT = getTpls<std::make_index_sequence<sizeof...(Ts)-1u>, Ts...>;

   using ftpl = typename getT::ftpl;
   using stpl = typename getT::stpl;

   template <typename ... FTs, typename ... STs,
             std::enable_if_t<
                 std::is_same_v<ftpl, std::tuple<tag<FTs>...>>
              && std::is_same_v<stpl, std::tuple<tag<STs>...>>, int> = 0>
   Collection (Node<FTs, STs> ...)
    { }
 };

The following is a full compiling example

#include <tuple>
#include <type_traits>

template <typename Start, typename End>
class Node
 { };

struct A {};
struct B {};
struct C {};

template <typename>
struct tag
 { };

template <typename...>
struct getTpls;

template <std::size_t ... Is, typename ... Ts>
struct getTpls<std::index_sequence<Is...>, Ts...>
 {
   using tpl0 = std::tuple<tag<Ts>...>;
   using ftpl = std::tuple<std::tuple_element_t<Is,    tpl0>...>;
   using stpl = std::tuple<std::tuple_element_t<1u+Is, tpl0>...>;
 };

template <typename ... Ts>
struct Collection
 {
   static_assert( sizeof...(Ts) > 1u, "more types, please");

   using getT = getTpls<std::make_index_sequence<sizeof...(Ts)-1u>, Ts...>;

   using ftpl = typename getT::ftpl;
   using stpl = typename getT::stpl;

   template <typename ... FTs, typename ... STs,
             std::enable_if_t<
                 std::is_same_v<ftpl, std::tuple<tag<FTs>...>>
              && std::is_same_v<stpl, std::tuple<tag<STs>...>>, int> = 0>
   Collection (Node<FTs, STs> ...)
    { }
 };

int main ()
 {
   Collection<A, B, C>  c0{Node<A, B>{}, Node<B, C>{}};    // compile
   // Collection<A, B, B>  c1{Node<A, B>{}, Node<B, C>{}}; // error!
 }


问:
Extracting meaning full content from web pages
I am doing some analysis by mining web content using my crawlers. Web pages often contain clutter (such as ads, unnecessary images and extraneous links) around the body of an article that distracts a user from actual content.

To extract the sensible content is a difficult problem as I understand it, considering the fact that there is no standard that defines the actual position of a news-story/blog post/forum comment/article in the web page.

I could find some open source solutions like this: https://metacpan.org/pod/HTML::ContentExtractor

But I am curious if anyone has dealt with this and got reasonable success rate. It seems a fairly common problem and I would like to believe many experts are out there. I would prefer a JAVA based solution but that is not a hard rule. Please give some inputs. I will deeply appreciate.

答:
Ideally, you would look for an RSS feed to get the raw content.

The is no standard for overall structure & meaning in HTML. Authors define different elements in their page. Search engines have invested a lot into this area, and they have their own secret sauce for indexing the content and getting some kind of meaning & structure out of it for search ranking.

Until we have the long-foretold "semantic web", we can only make educated guesses about the structure and meaning of arbitrary HTML pages.

But, in theory:

Look for heading tags. These should give you a clue for where to start reading, and hopefully an outline for the order of importance for the content.

Look for common element id and classes. A well-structured site might have things like
 and
, which is as semantic as it gets these days. Also get to know the standard element names used by common CMS platforms like WordPress ("post") or Drupal ("node"). Often these will be used to mark up the content.

Last but not least, look for microformats.

Body:
Ideally, you would look for an RSS feed to get the raw content.

The is no standard for overall structure & meaning in HTML. Authors define different elements in their page. Search engines have invested a lot into this area, and they have their own secret sauce for indexing the content and getting some kind of meaning & structure out of it for search ranking.

Until we have the long-foretold "semantic web", we can only make educated guesses about the structure and meaning of arbitrary HTML pages.

But, in theory:

Look for heading tags. These should give you a clue for where to start reading, and hopefully an outline for the order of importance for the content.

Look for common element id and classes. A well-structured site might have things like <div id="content"> and <div class="article">, which is as semantic as it gets these days. Also get to know the standard element names used by common CMS platforms like WordPress ("post") or Drupal ("node"). Often these will be used to mark up the content.

Last but not least, look for microformats.

OwnerDisplayName: Andrew Vit

ContentLicense: CC BY-SA 2.5


问:
html question want to move a table beside another
I have two tables. One above the other. I want to move the bottom table to the right of the top table. Right now when I run the server, the top table is positioned above the bottom table. Is there a way to move the bottom table to the right side of the top table?</p>

```<code><table>
        <tr><th>Type</th><th>Quantity</th></tr>
        </tr><td>Tape + Film</td><td>{{total_tape_and_film_items}}</td></tr>
        </tr><td>Electrical Equipment</td><td>{{total_electrical_equipment_items}}</td></tr>
</tables>

<table>
        <tr><th></th><th>Status</th><th>Quantity</th></tr>
        <tr><td><a id="new_client" href='{% url tiptop.views.in_items client.pk%}'/>View</a></td><td>In</td><td>{{in_items|length}}</td</tr>
        <tr><td><a id="new_client" href='{% url tiptop.views.out_items client.pk%}'/>View</a></td><td>Out</td><td>{{out_items|length}}</td</tr>
        <tr><td><a id="new_client" href='{% url tiptop.views.empty_items client.pk%}'/>View</a></td><td>Empty</td><td>{{empty_items|length}}</td</tr>
</table>
</code>```

答:
Set both tables to have a fixed width and then float them using CSS:</p>

```<code>table { float:left; width:400px; }
</code>```

Body:
I have two tables. One above the other. I want to move the bottom table to the right of the top table. Right now when I run the server, the top table is positioned above the bottom table. Is there a way to move the bottom table to the right side of the top table?

Type	Quantity

Tape + Film	{{total_tape_and_film_items}}

Electrical Equipment	{{total_electrical_equipment_items}}

</tables>

	Status	Quantity

View	In	{{in_items|length}}</td

View	Out	{{out_items|length}}</td

View	Empty	{{empty_items|length}}</td

Body:
Set both tables to have a fixed width and then float them using CSS:

table { float:left; width:400px; }


问:
Split a string based on colon and new line and add the result to dicitonary
I want to convert the below unicode in python to a dictionary:

```<code>Version: 67
Build Number: 123master
Project Name: git+ssh://git@stash.xyz.com:1999/ns/x-y.git
Git Url: origin/master
Git Branch: 0223445as5njn34nfk6kg
perforce_url:
  //project//url//
artifacts:
  "./": "./"
exclude:
  - manifest.yml
  - node_modules
  - RPMS
  - .git
  - build-toolbox

</code>```

```<code>>>> x
' Version: 67\nBuild Number: 123master\nProject Name: git+ssh://git@stash.xyz.com:1999/ns/x-y.git\nGit Url: origin/master\nGit Branch: 0223445as5njn34nfk6kg\nperforce_url:\n  //project//url//\nartifacts:\n  "./": "./"\nexclude:\n  - manifest.yml\n  - node_modules\n  - RPMS\n  - .git\n  - build-toolbox '
>>>
>>>
>>> dict(map(lambda x: x.split(':'), x.splitlines()))
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
ValueError: dictionary update sequence element #2 has length 4; 2 is required

</code>```

```<code>
dict(item.split(":") for item in x.splitlines())
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
ValueError: dictionary update sequence element #2 has length 4; 2 is required

</code>```

I believe the problem is with the following item

```<code>Project Name: git+ssh://git@stash.xyz.com:1999/ns/x-y.git

</code>```

git url above has a : in it.  Consequently, when I try to split, I get the following error:

ValueError: dictionary update sequence element #2 has length 4; 2 is required

```<code>dict(item.split(":") for item in data.splitlines())
</code>```

```<code>dict(map(lambda x: x.split(':'), x.splitlines()))
</code>```

expected result:

```<code>{"version" : 67 , " Build Number" : "123master", "Project Name": "xyz", "Git Url" : "origin/master", "Git Branch": "0223445as5njn34nfk6kg", "perforce_url":
  "//project//url//", "artifacts" : " "./": "./" "}

</code>```

Actual result:

```<code>ValueError: dictionary update sequence element #2 has length 4; 2 is required
</code>```

答:
Your immediate problem IS that colon- you can solve that by using line.split(':', 1)

You are also going to have problems with the list elements. Is the input file yaml by any chance?

```<code>import yaml

data = """
Version: 67
Build Number: 123master
Project Name: git+ssh://git@stash.xyz.com:1999/ns/x-y.git
Git Url: origin/master
Git Branch: 0223445as5njn34nfk6kg
perforce_url:
  //project//url//
artifacts:
  "./": "./"
exclude:
  - manifest.yml
  - node_modules
  - RPMS
  - .git
  - build-toolbox
"""
yaml.load(data)
</code>```

Body:
I want to convert the below unicode in python to a dictionary:

Version: 67
Build Number: 123master
Project Name: git+ssh://git@stash.xyz.com:1999/ns/x-y.git
Git Url: origin/master
Git Branch: 0223445as5njn34nfk6kg
perforce_url:
  //project//url//
artifacts:
  "./": "./"
exclude:
  - manifest.yml
  - node_modules
  - RPMS
  - .git
  - build-toolbox

>>> x
' Version: 67\nBuild Number: 123master\nProject Name: git+ssh://git@stash.xyz.com:1999/ns/x-y.git\nGit Url: origin/master\nGit Branch: 0223445as5njn34nfk6kg\nperforce_url:\n  //project//url//\nartifacts:\n  "./": "./"\nexclude:\n  - manifest.yml\n  - node_modules\n  - RPMS\n  - .git\n  - build-toolbox '
>>>
>>>
>>> dict(map(lambda x: x.split(':'), x.splitlines()))
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
ValueError: dictionary update sequence element #2 has length 4; 2 is required

dict(item.split(":") for item in x.splitlines())
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
ValueError: dictionary update sequence element #2 has length 4; 2 is required

I believe the problem is with the following item

Project Name: git+ssh://git@stash.xyz.com:1999/ns/x-y.git

git url above has a : in it.  Consequently, when I try to split, I get the following error:

ValueError: dictionary update sequence element #2 has length 4; 2 is required

dict(item.split(":") for item in data.splitlines())

dict(map(lambda x: x.split(':'), x.splitlines()))

expected result:

{"version" : 67 , " Build Number" : "123master", "Project Name": "xyz", "Git Url" : "origin/master", "Git Branch": "0223445as5njn34nfk6kg", "perforce_url":
  "//project//url//", "artifacts" : " "./": "./" "}

Actual result:

ValueError: dictionary update sequence element #2 has length 4; 2 is required

Body:
Your immediate problem IS that colon- you can solve that by using line.split(':', 1)

You are also going to have problems with the list elements. Is the input file yaml by any chance?

import yaml

data = """
Version: 67
Build Number: 123master
Project Name: git+ssh://git@stash.xyz.com:1999/ns/x-y.git
Git Url: origin/master
Git Branch: 0223445as5njn34nfk6kg
perforce_url:
  //project//url//
artifacts:
  "./": "./"
exclude:
  - manifest.yml
  - node_modules
  - RPMS
  - .git
  - build-toolbox
"""
yaml.load(data)


问:
What does 'polling' refer to and what is this code doing exactly?
I am currently building a python script that enables and disables certain ports on switches to see how the switch will act for quality assurance purposes. I've been using a Python library called paramiko which implements SSH to connect to whichever devices I want and I'm referring to legacy code handed by one of my teammates to write more scripts. In one of the legacy code files, there is a function called _run_poll and I'm not understanding what it's doing exactly.

I have tried do some research on what "polling" means in regards to SSH, but I am still not understanding what is going when we are running the "poll". The definition for it seems a little vague. Here is the function:

```<code>def _run_poll(self, session, timeout, input_data):

    interval = 0.1
    maxseconds = timeout
    maxcount = maxseconds / interval

    i = 0
    timeout_flag = False
    self.info('polling (%d, %d)' % (maxseconds, maxcount))
    start = datetime.datetime.now()
    start_secs = time.mktime(start.timetuple())
    output = ''
    session.setblocking(0)
    while True:
        if session.recv_ready(): # returns true if data has been buffered
            data = session.recv(self.bufsize) # receive data from the channel
            output += data
            self.info('read %d bytes, total %d' % (len(data), len(output)))

            if session.send_ready():
                # We received a potential prompt.
                # In the future this could be made to work more like
                # pexpect with pattern matching.
                if i < len(input_data):
                    data = input_data[input_idx] + '\n'
                    i += 1
                    self.info('sending input data %d' % (len(data)))
                    session.send(data)

        self.info('session.exit_status_ready() = %s' % (str(session.exit_status_ready())))
        if session.exit_status_ready():
            break

        # Timeout check
        now = datetime.datetime.now()
        now_secs = time.mktime(now.timetuple())
        et_secs = now_secs - start_secs
        self.info('timeout check %d %d' % (et_secs, maxseconds))
        if et_secs > maxseconds:
            self.info('polling finished - timeout')
            timeout_flag = True
            break
        time.sleep(0.200)

    self.info('polling loop ended')
    if session.recv_ready():
        data = session.recv(self.bufsize)
        output += data
        self.info('read %d bytes, total %d' % (len(data), len(output)))

    self.info('polling finished - %d output bytes' % (len(output)))
    if timeout_flag:
        self.info('appending timeout message')
        output += '\nERROR: timeout after %d seconds\n' % (timeout)
        session.close()

    return output
</code>```

I'm not able to find a lot of online resources to describe what is going on here or about "polling" in general. Can anyone help me explain what exactly is "polling" and what is going on here ?

答:
Wikipedia article about Polling defines it as:

Actively sampling the status of an external device by a client program as a synchronous activity.

In your code, this means that it regularly (every 200ms) checks the SSH connection for any incoming data and for free capacity in an output queue.

Body:
I am currently building a python script that enables and disables certain ports on switches to see how the switch will act for quality assurance purposes. I've been using a Python library called paramiko which implements SSH to connect to whichever devices I want and I'm referring to legacy code handed by one of my teammates to write more scripts. In one of the legacy code files, there is a function called _run_poll and I'm not understanding what it's doing exactly.

I have tried do some research on what "polling" means in regards to SSH, but I am still not understanding what is going when we are running the "poll". The definition for it seems a little vague. Here is the function:

def _run_poll(self, session, timeout, input_data):

    interval = 0.1
    maxseconds = timeout
    maxcount = maxseconds / interval

    i = 0
    timeout_flag = False
    self.info('polling (%d, %d)' % (maxseconds, maxcount))
    start = datetime.datetime.now()
    start_secs = time.mktime(start.timetuple())
    output = ''
    session.setblocking(0)
    while True:
        if session.recv_ready(): # returns true if data has been buffered
            data = session.recv(self.bufsize) # receive data from the channel
            output += data
            self.info('read %d bytes, total %d' % (len(data), len(output)))

            if session.send_ready():
                # We received a potential prompt.
                # In the future this could be made to work more like
                # pexpect with pattern matching.
                if i < len(input_data):
                    data = input_data[input_idx] + '\n'
                    i += 1
                    self.info('sending input data %d' % (len(data)))
                    session.send(data)

        self.info('session.exit_status_ready() = %s' % (str(session.exit_status_ready())))
        if session.exit_status_ready():
            break

        # Timeout check
        now = datetime.datetime.now()
        now_secs = time.mktime(now.timetuple())
        et_secs = now_secs - start_secs
        self.info('timeout check %d %d' % (et_secs, maxseconds))
        if et_secs > maxseconds:
            self.info('polling finished - timeout')
            timeout_flag = True
            break
        time.sleep(0.200)

    self.info('polling loop ended')
    if session.recv_ready():
        data = session.recv(self.bufsize)
        output += data
        self.info('read %d bytes, total %d' % (len(data), len(output)))

    self.info('polling finished - %d output bytes' % (len(output)))
    if timeout_flag:
        self.info('appending timeout message')
        output += '\nERROR: timeout after %d seconds\n' % (timeout)
        session.close()

    return output

I'm not able to find a lot of online resources to describe what is going on here or about "polling" in general. Can anyone help me explain what exactly is "polling" and what is going on here ?


问:
Security Exception: MalformedURLException: unknown protocol: socket during opening JNLP file
OS: Windows 7 32-bit
JDK: jdk1.7.0_25

I have Studio.jnlp file. I tried to open it by double-click. But I found the error as below:

"MalformedURLException: unknown protocol: socket"
Details: java.net.MalformedURLException: unknown protocol: socket

答:
Run the command javaws --viewer to open the Java Control Panel, click on the button Network Settings and select Direct Connection.

Now run again your jnlp with:

javaws Studio.jnlp


问:
boost::asio no handler called when using post(), works when function called directly (io_context has work)
I am trying to periodically trigger a request from an application to a server by using a timer. The called function waits for completion by utilizing boost::promise (In case it is called manually and a success state is required to be displayed). When starting up I call the function directly and it completes without problem. Then a timer calls it again periodically but when initiated via deadline_timer the promise never gets fulfilled.

When calling via .post() the connection to the server is opened but on the client side the handle_connect handler is never triggered. The io_context has work assigned.

I have already tried moving the promise to the ServiceRequest-class instead of passing a refernce and also implementing it as a class member to rule out lifetime problems.

I have reduced the whole problem to a minimum example of the failing code:

(Demos on Coliru: Working (via direct call), Failing (via post))

class ServiceRequest : public boost::enable_shared_from_this<ServiceRequest>
{
    public:

        ServiceRequest(boost::asio::io_service& io_service, Client& client, boost::promise<bool>& promise)
          : io_service_(io_service),
            socket_(io_service_),
            client_(client),
            promise_(promise)
        {}

        ~ServiceRequest()
        {}

        void Start()
        {
            socket_.async_connect(
                boost::asio::ip::tcp::endpoint(boost::asio::ip::address::from_string("127.0.0.1"), 3005),
                boost::bind(&ServiceRequest::handle_connect,
                            shared_from_this(),
                            boost::asio::placeholders::error
                )
            );
        }

    private:

        void handle_connect(const boost::system::error_code& ec)
        {
            if(!ec)
            {
                promise_.set_value(true);

                boost::asio::async_write(socket_,
                                         boost::asio::buffer("Test"),
                                         boost::bind(&ServiceRequest::close_socket,
                                                     shared_from_this())
                                        );

            }
            else
            {
                promise_.set_value(false);
            }
        }

        void close_socket()
        {
            socket_.shutdown(boost::asio::ip::tcp::socket::shutdown_both);
            socket_.close();
        }

        boost::asio::io_service&        io_service_;
        boost::asio::ip::tcp::socket    socket_;
        Client&                         client_;
        boost::promise<bool>&           promise_;

};

class RequestHandler
{

    public:

        RequestHandler(boost::asio::io_service& io_service, Client& client)
          : io_service_(io_service),
            client_(client)
        {}

        ~RequestHandler()
        {}

        bool RequestService()
        {

            boost::promise<bool> promise;
            boost::shared_ptr<ServiceRequest> service_request = boost::make_shared<ServiceRequest>(io_service_, client_, promise);
            service_request->Start();

            bool result = promise.get_future().get();

            return result;
        }

    private:

        boost::asio::io_service&    io_service_;
        Client&                     client_;

};

class Client {

    public:

        Client()
          : io_service_(),
            work_(io_service_),
            thread_group_(),
            timer_(io_service_),
            request_handler_(io_service_, *this)
        {
            thread_group_.create_thread(boost::bind(&boost::asio::io_service::run, &io_service_));
        }

        ~Client()
        {
            io_service_.stop();
            thread_group_.join_all();
        }

        void RequestService()
        {
            io_service_.post(boost::bind(&RequestHandler::RequestService, &request_handler_));  // <<--- deadlocks at promise.get_future().get()
            request_handler_.RequestService(); // <<--- works
            timer_.expires_from_now(boost::posix_time::seconds(10));
            timer_.async_wait(boost::bind(&Client::RequestService, this)); // <<--- deadlocks at promise.get_future().get()
        }

    private:

        boost::asio::io_service         io_service_;
        boost::asio::io_service::work   work_;
        boost::thread_group             thread_group_;
        boost::asio::deadline_timer     timer_;
        RequestHandler                  request_handler_;

};

int main()
{
    Client client;
    client.RequestService();
    return 0;
}
```

<p>When calling request_handler_.RequestService() directly everything works as expected. The handler tracking of boost::asio shows as expected:</p>

```@asio|1559149650.446538|0*1|socket@00000000007b9d40.async_connect
@asio|1559149650.456538|>1|ec=system:0
@asio|1559149650.456538|1*2|socket@00000000007b9d40.async_send
@asio|1559149650.456538|<1|
@asio|1559149650.456538|>2|ec=system:0,bytes_transferred=5
@asio|1559149650.456538|2|socket@00000000007b9d40.close
@asio|1559149650.456538|<2|
```

<p>When using .post() or a deadline timer to call RequestService() the handler tracker shows:</p>

```@asio|1559149477.071693|0*1|io_context@000000000022fd90.post
@asio|1559149477.071693|>1|
@asio|1559149477.071693|1*2|socket@00000000007b9e10.async_connect
```

So the connection is established but the handler is not triggered and therefore no promise.set_value(bool) is called and the whole thing locks up.

What am I doing wrong here?

答:
You've only got one thread that's calling io_service::run.

post() executes the function you give it from within the io_service on one of the io_service's threads. The function that you're trying to run within the io_service's main loop (RequestHandler::RequestService) is a blocking function that is waiting for promise to be fulfilled by the work that's supposed to execute on the io_service's thread. This will never complete because you've blocked the io_service's thread.

This is one of the primary mistakes to you need to avoid when using ASIO or any async framework. Never block in the thread that is processing your events because you can introduce subtle (or not-so-subtle) deadlocks like this.

Body:
I am trying to periodically trigger a request from an application to a server by using a timer. The called function waits for completion by utilizing boost::promise (In case it is called manually and a success state is required to be displayed). When starting up I call the function directly and it completes without problem. Then a timer calls it again periodically but when initiated via deadline_timer the promise never gets fulfilled.

When calling via .post() the connection to the server is opened but on the client side the handle_connect handler is never triggered. The io_context has work assigned.

I have already tried moving the promise to the ServiceRequest-class instead of passing a refernce and also implementing it as a class member to rule out lifetime problems.

I have reduced the whole problem to a minimum example of the failing code:

(Demos on Coliru: Working (via direct call), Failing (via post))

class ServiceRequest : public boost::enable_shared_from_this<ServiceRequest>
{
    public:

        ServiceRequest(boost::asio::io_service& io_service, Client& client, boost::promise<bool>& promise)
          : io_service_(io_service),
            socket_(io_service_),
            client_(client),
            promise_(promise)
        {}

        ~ServiceRequest()
        {}

        void Start()
        {
            socket_.async_connect(
                boost::asio::ip::tcp::endpoint(boost::asio::ip::address::from_string("127.0.0.1"), 3005),
                boost::bind(&ServiceRequest::handle_connect,
                            shared_from_this(),
                            boost::asio::placeholders::error
                )
            );
        }

    private:

        void handle_connect(const boost::system::error_code& ec)
        {
            if(!ec)
            {
                promise_.set_value(true);

                boost::asio::async_write(socket_,
                                         boost::asio::buffer("Test"),
                                         boost::bind(&ServiceRequest::close_socket,
                                                     shared_from_this())
                                        );

            }
            else
            {
                promise_.set_value(false);
            }
        }

        void close_socket()
        {
            socket_.shutdown(boost::asio::ip::tcp::socket::shutdown_both);
            socket_.close();
        }

        boost::asio::io_service&        io_service_;
        boost::asio::ip::tcp::socket    socket_;
        Client&                         client_;
        boost::promise<bool>&           promise_;

};

class RequestHandler
{

    public:

        RequestHandler(boost::asio::io_service& io_service, Client& client)
          : io_service_(io_service),
            client_(client)
        {}

        ~RequestHandler()
        {}

        bool RequestService()
        {

            boost::promise<bool> promise;
            boost::shared_ptr<ServiceRequest> service_request = boost::make_shared<ServiceRequest>(io_service_, client_, promise);
            service_request->Start();

            bool result = promise.get_future().get();

            return result;
        }

    private:

        boost::asio::io_service&    io_service_;
        Client&                     client_;

};

class Client {

    public:

        Client()
          : io_service_(),
            work_(io_service_),
            thread_group_(),
            timer_(io_service_),
            request_handler_(io_service_, *this)
        {
            thread_group_.create_thread(boost::bind(&boost::asio::io_service::run, &io_service_));
        }

        ~Client()
        {
            io_service_.stop();
            thread_group_.join_all();
        }

        void RequestService()
        {
            io_service_.post(boost::bind(&RequestHandler::RequestService, &request_handler_));  // <<--- deadlocks at promise.get_future().get()
            request_handler_.RequestService(); // <<--- works
            timer_.expires_from_now(boost::posix_time::seconds(10));
            timer_.async_wait(boost::bind(&Client::RequestService, this)); // <<--- deadlocks at promise.get_future().get()
        }

    private:

        boost::asio::io_service         io_service_;
        boost::asio::io_service::work   work_;
        boost::thread_group             thread_group_;
        boost::asio::deadline_timer     timer_;
        RequestHandler                  request_handler_;

};

int main()
{
    Client client;
    client.RequestService();
    return 0;
}

When calling request_handler_.RequestService() directly everything works as expected. The handler tracking of boost::asio shows as expected:

@asio|1559149650.446538|0*1|socket@00000000007b9d40.async_connect
@asio|1559149650.456538|>1|ec=system:0
@asio|1559149650.456538|1*2|socket@00000000007b9d40.async_send
@asio|1559149650.456538|<1|
@asio|1559149650.456538|>2|ec=system:0,bytes_transferred=5
@asio|1559149650.456538|2|socket@00000000007b9d40.close
@asio|1559149650.456538|<2|

When using .post() or a deadline timer to call RequestService() the handler tracker shows:

@asio|1559149477.071693|0*1|io_context@000000000022fd90.post
@asio|1559149477.071693|>1|
@asio|1559149477.071693|1*2|socket@00000000007b9e10.async_connect

So the connection is established but the handler is not triggered and therefore no promise.set_value(bool) is called and the whole thing locks up.

What am I doing wrong here?


问:
How to calculate the difference between consecutive sets of two columns in a column range using dplyr
I would like to calculate the difference between consecutive columns in a range of columns using dplyr.

For example, using the iris data set I would want to be able to specify the range Sepal.Width:Petal.Width and have a dataframe that contained the original iris data and the differences between the consecutive columns from Sepal.Width:Petal.Width:

```<code>  Sepal.Length Sepal.Width Petal.Length Petal.Width Species diff1 diff2
1          5.1         3.5          1.4         0.2  setosa   2.1   1.2
2          4.9         3.0          1.4         0.2  setosa   1.6   1.2
3          4.7         3.2          1.3         0.2  setosa   1.9   1.1
4          4.6         3.1          1.5         0.2  setosa   1.6   1.3
5          5.0         3.6          1.4         0.2  setosa   2.2   1.2
6          5.4         3.9          1.7         0.4  setosa   2.2   1.3
</code>```

Someone posted a solution loops and lapply (Calculate the difference between consecutive, grouped columns in a data.table) but I'm specifically looking for a dplyr solution.

答:
Here's a less advanced approach using dplyr and tidyr verbs. First I gather the columns for differencing into long format, then take their differences vs. previous column, strip out NA's for the first columns which have no previous column, rename the column, spread out, and attach onto the original.

```<code>library(tidyverse)
iris %>%
  bind_cols(iris %>%
    rowid_to_column() %>%
    gather(col, val, Sepal.Width:Petal.Width) %>%
    group_by(rowid) %>%
    mutate(val = abs(val - lag(val))) %>%
    filter(!is.na(val)) %>%
    mutate(col = paste0("diff_", col)) %>%
    spread(col, val)  %>%
    select(contains("diff"))
  )

    Sepal.Length Sepal.Width Petal.Length Petal.Width    Species rowid diff_Petal.Length diff_Petal.Width
1            5.1         3.5          1.4         0.2     setosa     1               2.1              1.2
2            4.9         3.0          1.4         0.2     setosa     2               1.6              1.2
3            4.7         3.2          1.3         0.2     setosa     3               1.9              1.1
4            4.6         3.1          1.5         0.2     setosa     4               1.6              1.3
5            5.0         3.6          1.4         0.2     setosa     5               2.2              1.2
6            5.4         3.9          1.7         0.4     setosa     6               2.2              1.3
7            4.6         3.4          1.4         0.3     setosa     7               2.0              1.1
</code>```

Body:
I would like to calculate the difference between consecutive columns in a range of columns using dplyr.

For example, using the iris data set I would want to be able to specify the range Sepal.Width:Petal.Width and have a dataframe that contained the original iris data and the differences between the consecutive columns from Sepal.Width:Petal.Width:

  Sepal.Length Sepal.Width Petal.Length Petal.Width Species diff1 diff2
1          5.1         3.5          1.4         0.2  setosa   2.1   1.2
2          4.9         3.0          1.4         0.2  setosa   1.6   1.2
3          4.7         3.2          1.3         0.2  setosa   1.9   1.1
4          4.6         3.1          1.5         0.2  setosa   1.6   1.3
5          5.0         3.6          1.4         0.2  setosa   2.2   1.2
6          5.4         3.9          1.7         0.4  setosa   2.2   1.3

Someone posted a solution loops and lapply (Calculate the difference between consecutive, grouped columns in a data.table) but I'm specifically looking for a dplyr solution.

Body:
Here's a less advanced approach using dplyr and tidyr verbs. First I gather the columns for differencing into long format, then take their differences vs. previous column, strip out NA's for the first columns which have no previous column, rename the column, spread out, and attach onto the original.

library(tidyverse)
iris %>%
  bind_cols(iris %>%
    rowid_to_column() %>%
    gather(col, val, Sepal.Width:Petal.Width) %>%
    group_by(rowid) %>%
    mutate(val = abs(val - lag(val))) %>%
    filter(!is.na(val)) %>%
    mutate(col = paste0("diff_", col)) %>%
    spread(col, val)  %>%
    select(contains("diff"))
  )

    Sepal.Length Sepal.Width Petal.Length Petal.Width    Species rowid diff_Petal.Length diff_Petal.Width
1            5.1         3.5          1.4         0.2     setosa     1               2.1              1.2
2            4.9         3.0          1.4         0.2     setosa     2               1.6              1.2
3            4.7         3.2          1.3         0.2     setosa     3               1.9              1.1
4            4.6         3.1          1.5         0.2     setosa     4               1.6              1.3
5            5.0         3.6          1.4         0.2     setosa     5               2.2              1.2
6            5.4         3.9          1.7         0.4     setosa     6               2.2              1.3
7            4.6         3.4          1.4         0.3     setosa     7               2.0              1.1


问:
How to do event.stopPropagation() to react-select input field when arrow keys and enter key pressed in ag grid custom cell editor
I'm using ag-grid for records editing.

How do I make a cell editor that does nothing when arrow and enter keys are pressed.

Similar to this code, but with react-select component

```<code>import React, { Component } from 'react'
import TextField from '@material-ui/core/TextField'
class TextCellEditor extends Component {
    constructor(props) {
        super(props);
        this.textInput = React.createRef();
    }

    onKeyDown(event) {
        if (event.keyCode === 39 || event.keyCode === 37) {
            event.stopPropagation();
        }
    }

    afterGuiAttached(param) {
        if (this.textInput) this.textInput.current.focus();
    }

    getValue() {
        return this.textInput.current.value;
    }

    isPopup(){
        return true
    }

    isCancelAfterEnd(){
        return false

    }

    componentDidMount() {
        this.textInput.current.addEventListener('keydown', this.onKeyDown);
    }

    render() {
        return (
            <TextField
                defaultValue={this.props.value}
                inputProps={{
                    ref:this.textInput
                }}
            />
        );
    }
}

export default TextCellEditor
</code>```

I've tried using refs and addeventListener but it doesn't work, here's my current code for react-select cell editor

```<code>import React, { Component } from 'react'
import CreatableSelect  from "react-select/lib/Creatable"
import { components } from 'react-select'
import axios from "axios"
import Cookies from 'js-cookie'
import IconButton from '@material-ui/core/IconButton'
import EditIcon from '@material-ui/icons/Edit'
import ReactDOM from 'react-dom'

//redux
import { connect } from 'react-redux'
import {
    setNotification,
    updateFullRecord,
    pushBreadcrumbs,
    pushFullRecord,
    setCFI,
    setFullView,
    pushModalRecord,
    setModalView,
    setCMI,
    toggleModal,
}
from '../../../actions/ActivityActions'

class ReactSelectCellEditor extends Component {

    constructor(props) {
        super(props);
        this.state = {
            selected : {
                value : "",
                labal : ""
            },
            suggestion :[]
        }
        this.handleChange = this.handleChange.bind(this)
        this.MTORef = React.createRef();
        this.InputRef = React.createRef();
        console.log("cell editor props:",this.props)
    }

    componentDidMount() {
        axios.post(this.props.host+"/api/"+this.props.model+"/options", {
            search  : "",
            limit   : 10
        },{
            headers: {
                Authorization: "Bearer "+Cookies.get("accessToken")
            }
        })
        .then(response => {
            var arr     = response.data.records
            var result  = arr.map(record =>({
                label :record[this.props.fieldAsLabel],
                value: record[this.props.fieldAsValue]
            }))
            this.setState({
                suggestion : [
                    ...result
                ]
            })
        })
    }

    getLabel=(id)=>{
        axios.get(this.props.host+"/api/"+this.props.model+"/"+id,{
            headers:{
                Authorization:"Bearer "+Cookies.get("accessToken")
            }
        })
    }

    handleClickEdit = () => {
        axios.post(this.props.host+"/api/"+this.props.model+"/"+this.state.selected.value, {
            search  : this.state.selected.value,
            limit   : 10
        },{
            headers: {
                Authorization: "Bearer "+Cookies.get("accessToken")
            }
        }).then((response)=>{
            this.props.pushModalRecord({
                ...response.data,
                formMode:"edit",
                _modal:true
            })
            this.props.saveFormState()
            this.props.setModalView(this.props.form)
            this.props.setCMI(this.props.Activity.currentModalIndex+1)
            this.props.toggleModal()
        })
    }

    handleCreateOption = (inputValue:any) => {
        this.props.pushModalRecord({
            [this.props.fieldAsLabel]:inputValue,
            formMode:"create",
            _modal:true
        })
        this.props.saveFormState()
        this.props.setModalView(this.props.form)
        this.props.setCMI(this.props.Activity.currentModalIndex+1)
        this.props.toggleModal()
    }

    handleChange(selected){
        selected = selected === null?"":selected
        this.setState({
            selected : {
                label : selected.label,
                value : selected.value
            }
        })
    }

    onKeyDown(event) {
        let key = event.which || event.keyCode;
        if (key === 37 ||  // left
            key === 39) {  // right
            event.stopPropagation();
        }
    }

    afterGuiAttached(param) {
        this.SelectRef.focus()
    }

    getValue() {
        return this.state.selected.value
    }

    isPopup() {
        return true
    }

    render() {
        return (
            <div>
            <div style={{minWidth:"200px",display:"flex"}}>
                <div style={{width:"160px"}}>
                <CreatableSelect
                    isLoading       = {false}
                    options         = {this.state.suggestion}
                    defaultValue    = {this.props.value !== undefined?{
                        label:this.props.label,
                        value:this.props.value
                    }:null}
                    onChange        = {this.handleChange}
                    onKeyDown       = {event=>this.onKeyDown(event)}
                    onCreateOption  = {this.handleCreateOption}
                    ref             = { ref => { this.MTORef = ref }}
                    isClearable

                />
                </div>
                {this.props.editable?<IconButton onClick={()=>this.handleClickEdit()}>
                    <EditIcon/>
                </IconButton>:""}
            </div>
            </div>
        )
    }
}

const mapStateToProps = (state) => {
    return {
        Global      :state.GlobalReducer,
        Activity    :state.ActivityReducer
    }
}

const mapDispatchToProps = (dispatch) => {
    return {
        setNotification: (isOpen,message,color)=>{
            dispatch(setNotification(isOpen,message,color))
        },
        updateFullRecord: (data,index) => {
            dispatch(updateFullRecord(data,index))
        },
        setCFI: (index) => {
            dispatch(setCFI(index))
        },
        pushFullRecord: (record) => {
            dispatch(pushFullRecord(record))
        },
        setFullView: (path) => {
            dispatch(setFullView(path))
        },
        pushBreadcrumbs: (data) => {
            dispatch(pushBreadcrumbs(data))
        },
        toggleModal : () => {
            dispatch(toggleModal())
        },
        pushModalRecord : (data) => {
            dispatch(pushModalRecord(data))
        },
        setModalView : (path) => {
            dispatch(setModalView(path))
        },
        setCMI : (data) => {
            dispatch(setCMI(data))
        },
    }
}

export default connect(mapStateToProps,mapDispatchToProps,null,{ forwardRef: true })(ReactSelectCellEditor)
</code>```

答:
You can use the suppressKeyboardEvent callback to ignore arrow and enter keys for the entire grid or for a particular cell. The callback should return true if the grid should suppress the events, or false to continue as normal.

The callback has the following signature:

export interface SuppressKeyboardEventParams extends IsColumnFuncParams {

```<code>   // the keyboard event the grid received. inspect this to see what key was pressed
   event: KeyboardEvent;

   // whether the cell is editing or not. sometimes you might want to suppress event
   // only when cell is editing.
   editing: boolean;

   node: RowNode; // row node
   data: any; // row data
   column: Column; // column
   colDef: ColDef; // column definition
   context: any; // context object
   api: GridApi | null | undefined; // grid API
   columnApi: ColumnApi | null | undefined; // column API
</code>```

}

The call back function may look like this -

```<code>function suppressEnterArrow(params) {
      let KEY_LEFT = 37;
      let KEY_UP = 38;
      let KEY_RIGHT = 39;
      let KEY_DOWN = 40;
      let KEY_ENTER = 13;
      let ignoredKeys = [KEY_LEFT, KEY_UP, KEY_RIGHT, KEY_ENTER, KEY_DOWN];
      var event = params.event;
      var key = event.which;
      var suppress = ignoredKeys.include(key) && params.editing &&
         params.colDef.cellEditor === <Your Text Cell Editor>;
      return suppress;
   }
</code>```

You can read more about it here - https://www.ag-grid.com/javascript-grid-keyboard-navigation/#suppressKeyboardEvents

Body:
I'm using ag-grid for records editing.

How do I make a cell editor that does nothing when arrow and enter keys are pressed.

Similar to this code, but with react-select component

import React, { Component } from 'react'
import TextField from '@material-ui/core/TextField'
class TextCellEditor extends Component {
    constructor(props) {
        super(props);
        this.textInput = React.createRef();
    }

    onKeyDown(event) {
        if (event.keyCode === 39 || event.keyCode === 37) {
            event.stopPropagation();
        }
    }

    afterGuiAttached(param) {
        if (this.textInput) this.textInput.current.focus();
    }

    getValue() {
        return this.textInput.current.value;
    }

    isPopup(){
        return true
    }

    isCancelAfterEnd(){
        return false

    }

    componentDidMount() {
        this.textInput.current.addEventListener('keydown', this.onKeyDown);
    }

    render() {
        return (
            <TextField
                defaultValue={this.props.value}
                inputProps={{
                    ref:this.textInput
                }}
            />
        );
    }
}

export default TextCellEditor

I've tried using refs and addeventListener but it doesn't work, here's my current code for react-select cell editor

import React, { Component } from 'react'
import CreatableSelect  from "react-select/lib/Creatable"
import { components } from 'react-select'
import axios from "axios"
import Cookies from 'js-cookie'
import IconButton from '@material-ui/core/IconButton'
import EditIcon from '@material-ui/icons/Edit'
import ReactDOM from 'react-dom'

//redux
import { connect } from 'react-redux'
import {
    setNotification,
    updateFullRecord,
    pushBreadcrumbs,
    pushFullRecord,
    setCFI,
    setFullView,
    pushModalRecord,
    setModalView,
    setCMI,
    toggleModal,
}
from '../../../actions/ActivityActions'

class ReactSelectCellEditor extends Component {

    constructor(props) {
        super(props);
        this.state = {
            selected : {
                value : "",
                labal : ""
            },
            suggestion :[]
        }
        this.handleChange = this.handleChange.bind(this)
        this.MTORef = React.createRef();
        this.InputRef = React.createRef();
        console.log("cell editor props:",this.props)
    }

    componentDidMount() {
        axios.post(this.props.host+"/api/"+this.props.model+"/options", {
            search  : "",
            limit   : 10
        },{
            headers: {
                Authorization: "Bearer "+Cookies.get("accessToken")
            }
        })
        .then(response => {
            var arr     = response.data.records
            var result  = arr.map(record =>({
                label :record[this.props.fieldAsLabel],
                value: record[this.props.fieldAsValue]
            }))
            this.setState({
                suggestion : [
                    ...result
                ]
            })
        })
    }

    getLabel=(id)=>{
        axios.get(this.props.host+"/api/"+this.props.model+"/"+id,{
            headers:{
                Authorization:"Bearer "+Cookies.get("accessToken")
            }
        })
    }

    handleClickEdit = () => {
        axios.post(this.props.host+"/api/"+this.props.model+"/"+this.state.selected.value, {
            search  : this.state.selected.value,
            limit   : 10
        },{
            headers: {
                Authorization: "Bearer "+Cookies.get("accessToken")
            }
        }).then((response)=>{
            this.props.pushModalRecord({
                ...response.data,
                formMode:"edit",
                _modal:true
            })
            this.props.saveFormState()
            this.props.setModalView(this.props.form)
            this.props.setCMI(this.props.Activity.currentModalIndex+1)
            this.props.toggleModal()
        })
    }

    handleCreateOption = (inputValue:any) => {
        this.props.pushModalRecord({
            [this.props.fieldAsLabel]:inputValue,
            formMode:"create",
            _modal:true
        })
        this.props.saveFormState()
        this.props.setModalView(this.props.form)
        this.props.setCMI(this.props.Activity.currentModalIndex+1)
        this.props.toggleModal()
    }

    handleChange(selected){
        selected = selected === null?"":selected
        this.setState({
            selected : {
                label : selected.label,
                value : selected.value
            }
        })
    }

    onKeyDown(event) {
        let key = event.which || event.keyCode;
        if (key === 37 ||  // left
            key === 39) {  // right
            event.stopPropagation();
        }
    }

    afterGuiAttached(param) {
        this.SelectRef.focus()
    }

    getValue() {
        return this.state.selected.value
    }

    isPopup() {
        return true
    }

    render() {
        return (

                <CreatableSelect
                    isLoading       = {false}
                    options         = {this.state.suggestion}
                    defaultValue    = {this.props.value !== undefined?{
                        label:this.props.label,
                        value:this.props.value
                    }:null}
                    onChange        = {this.handleChange}
                    onKeyDown       = {event=>this.onKeyDown(event)}
                    onCreateOption  = {this.handleCreateOption}
                    ref             = { ref => { this.MTORef = ref }}
                    isClearable

                />

                {this.props.editable?<IconButton onClick={()=>this.handleClickEdit()}>
                    <EditIcon/>
                </IconButton>:""}

        )
    }
}

const mapStateToProps = (state) => {
    return {
        Global      :state.GlobalReducer,
        Activity    :state.ActivityReducer
    }
}

const mapDispatchToProps = (dispatch) => {
    return {
        setNotification: (isOpen,message,color)=>{
            dispatch(setNotification(isOpen,message,color))
        },
        updateFullRecord: (data,index) => {
            dispatch(updateFullRecord(data,index))
        },
        setCFI: (index) => {
            dispatch(setCFI(index))
        },
        pushFullRecord: (record) => {
            dispatch(pushFullRecord(record))
        },
        setFullView: (path) => {
            dispatch(setFullView(path))
        },
        pushBreadcrumbs: (data) => {
            dispatch(pushBreadcrumbs(data))
        },
        toggleModal : () => {
            dispatch(toggleModal())
        },
        pushModalRecord : (data) => {
            dispatch(pushModalRecord(data))
        },
        setModalView : (path) => {
            dispatch(setModalView(path))
        },
        setCMI : (data) => {
            dispatch(setCMI(data))
        },
    }
}

export default connect(mapStateToProps,mapDispatchToProps,null,{ forwardRef: true })(ReactSelectCellEditor)

Body:
You can use the suppressKeyboardEvent callback to ignore arrow and enter keys for the entire grid or for a particular cell. The callback should return true if the grid should suppress the events, or false to continue as normal.

The callback has the following signature:

export interface SuppressKeyboardEventParams extends IsColumnFuncParams {

   // the keyboard event the grid received. inspect this to see what key was pressed
   event: KeyboardEvent;

   // whether the cell is editing or not. sometimes you might want to suppress event
   // only when cell is editing.
   editing: boolean;

   node: RowNode; // row node
   data: any; // row data
   column: Column; // column
   colDef: ColDef; // column definition
   context: any; // context object
   api: GridApi | null | undefined; // grid API
   columnApi: ColumnApi | null | undefined; // column API

}

The call back function may look like this -

function suppressEnterArrow(params) {
      let KEY_LEFT = 37;
      let KEY_UP = 38;
      let KEY_RIGHT = 39;
      let KEY_DOWN = 40;
      let KEY_ENTER = 13;
      let ignoredKeys = [KEY_LEFT, KEY_UP, KEY_RIGHT, KEY_ENTER, KEY_DOWN];
      var event = params.event;
      var key = event.which;
      var suppress = ignoredKeys.include(key) && params.editing &&
         params.colDef.cellEditor === <Your Text Cell Editor>;
      return suppress;
   }

You can read more about it here - https://www.ag-grid.com/javascript-grid-keyboard-navigation/#suppressKeyboardEvents


问:
SQL split values to multiple rows
I have table :

```<code>id | name
1  | a,b,c
2  | b
</code>```

i want output like this :

```<code>id | name
1  | a
1  | b
1  | c
2  | b
</code>```

答:
The original question was for MySQL and SQL in general. The example below is for the new versions of MySQL. Unfortunately, a generic query that would work on any SQL server is not possible. Some servers do no support CTE, others do not have substring_index, yet others have built-in functions for splitting a string into multiple rows.

--- the answer follows ---

Recursive queries are convenient when the server does not provide built-in functionality. They can also be the bottleneck.

The following query was written and tested on MySQL version 8.0.16. It will not work on version 5.7-. The old versions do not support Common Table Expression (CTE) and thus recursive queries.

```<code>with recursive
  input as (
        select 1 as id, 'a,b,c' as names
      union
        select 2, 'b'
    ),
  recurs as (
        select id, 1 as pos, names as remain, substring_index( names, ',', 1 ) as name
          from input
      union all
        select id, pos + 1, substring( remain, char_length( name ) + 2 ),
            substring_index( substring( remain, char_length( name ) + 2 ), ',', 1 )
          from recurs
          where char_length( remain ) > char_length( name )
    )
select id, name
  from recurs
  order by id, pos;
</code>```

Title: SQL split values to multiple rows

Body:
I have table :

id | name
1  | a,b,c
2  | b

i want output like this :

id | name
1  | a
1  | b
1  | c
2  | b

Body:
The original question was for MySQL and SQL in general. The example below is for the new versions of MySQL. Unfortunately, a generic query that would work on any SQL server is not possible. Some servers do no support CTE, others do not have substring_index, yet others have built-in functions for splitting a string into multiple rows.

--- the answer follows ---

Recursive queries are convenient when the server does not provide built-in functionality. They can also be the bottleneck.

The following query was written and tested on MySQL version 8.0.16. It will not work on version 5.7-. The old versions do not support Common Table Expression (CTE) and thus recursive queries.

with recursive
  input as (
        select 1 as id, 'a,b,c' as names
      union
        select 2, 'b'
    ),
  recurs as (
        select id, 1 as pos, names as remain, substring_index( names, ',', 1 ) as name
          from input
      union all
        select id, pos + 1, substring( remain, char_length( name ) + 2 ),
            substring_index( substring( remain, char_length( name ) + 2 ), ',', 1 )
          from recurs
          where char_length( remain ) > char_length( name )
    )
select id, name
  from recurs
  order by id, pos;


问:
jqplot zoom - happens only if zoomed till the borders
I am facing an issue with zooming using jqPlots.

I have a graph with multiple y-axes. I have the following lines of code for performing the zoom:

```<code>cursor: {
            showVerticalLine: true,
            //showTooltip: true,
            followMouse: true,
            showTooltipDataPosition: true,
            tooltipFormatString: '%s x:%s, y:%s',
            zoom: true,
            constrainOutsideZoom: false,
            clickReset: true
        }
</code>```

I am able to zoom with the above. However, the zoom happens only when I drag the zoom area to one of the borders. If I try to zoom somewhere within the canvas, it does not zoom.

Can someone tell me where I could be going wrong?

Thanks,
S.

答:
I actually have the same problem. In fact, the problem is that when you zoom inside the canvas the browser considers the click inside the canvas and execute the function clickReset. When your mouse finish outside the canvas it consider the click outside and doesn't execute the function. I tried on IE9 and it works because it doesn't consider the click during the zoom.

I think that this is a bug in the Jqplot library.

I searched for many hours and I didn't solve the problem. I hope that someone has a solution.

Body:
I am facing an issue with zooming using jqPlots.

I have a graph with multiple y-axes. I have the following lines of code for performing the zoom:

cursor: {
            showVerticalLine: true,
            //showTooltip: true,
            followMouse: true,
            showTooltipDataPosition: true,
            tooltipFormatString: '%s x:%s, y:%s',
            zoom: true,
            constrainOutsideZoom: false,
            clickReset: true
        }

I am able to zoom with the above. However, the zoom happens only when I drag the zoom area to one of the borders. If I try to zoom somewhere within the canvas, it does not zoom.

Can someone tell me where I could be going wrong?

Thanks,
S.


问:
Azure App Service - cannot store logs in azure storage
I would like to configure my diagnostic logs to be redirected to Blob or Table Storage. However the only option I see is Filesystem:

My goal is to collect these logs in splunk

答: Currently only .NET application logs can be written to the blob storage. Java, PHP, Node.js, Python application logs can only be stored on the file system (without code modifications to write logs to external storage). I'd recommend checking the documentation here