问:
How to count rows between 2 non empty cells with their intermediary empty cells in Google Sheets?
I'm trying to count each rows of empty cells between two non-empy cells and adding the upper non empty-cell count (or the lower non-empty cells count)  to the result when the empty cells/rows numbers are variable and irregular in this manner:

```<code>A1 Empty
A2 Non-empty
A3 Empty
A4 Empty
A5 Empty
A6 Empty
A7 Non-empty
</code>```

(with A2 to A5 being irregular — could be any number of intermediary empty rows/cells — i.e. 10, 2, 30, 5, etc., and variable — could be located in any location within Column A)

The result should return as follow:

```<code>=IFS(

AND(A2="",A3=""),"",

AND(A2="",A3<>""),"",

AND(A2<>"",A3<>""),ROWS(A2),

AND(A2<>"",A3=""),ROWS(A2:UP TO NEXT NON-EMPTY ROW BENEATH (NOT COMPRISED (or minus the next non-empty row(-1)))
</code>```

How do we program Google Sheets to count rows "UP TO NEXT NON-EMPTY ROW BENEATH (NOT COMPRISED (or minus the next ono empty row(-1)) when the emppty intermediary rows' count is variable/unknown for each occurence and irregular/can be any number of intremediary rows?

I have this data as example:

So far, I've come up with this partial solution:

```<code>=IFS(AND(A2="",A3=""),"", AND(A2="",A3<>""),"", AND(A2<>"",A3<>""),ROWS(A2), AND(A2<>"",A3=""),ROWS(A2:UP TO NEXT NON-EMPTY ROW BENEATH (NOT COMPRISED (or minus the next non-empty row(-1)))))
</code>```

The expected result should return as follows:

The Sheet copy:
https://docs.google.com/spreadsheets/d/1eLXdFINKVtS5Fxon8mIQDmBUTZokyY_Fb6tfWJRDOVI/edit?usp=sharing

Body:
I'm trying to count each rows of empty cells between two non-empy cells and adding the upper non empty-cell count (or the lower non-empty cells count)  to the result when the empty cells/rows numbers are variable and irregular in this manner:

A1 Empty
A2 Non-empty
A3 Empty
A4 Empty
A5 Empty
A6 Empty
A7 Non-empty

(with A2 to A5 being irregular — could be any number of intermediary empty rows/cells — i.e. 10, 2, 30, 5, etc., and variable — could be located in any location within Column A)

The result should return as follow:

=IFS(

AND(A2="",A3=""),"",

AND(A2="",A3<>""),"",

AND(A2<>"",A3<>""),ROWS(A2),

AND(A2<>"",A3=""),ROWS(A2:UP TO NEXT NON-EMPTY ROW BENEATH (NOT COMPRISED (or minus the next non-empty row(-1)))

How do we program Google Sheets to count rows "UP TO NEXT NON-EMPTY ROW BENEATH (NOT COMPRISED (or minus the next ono empty row(-1)) when the emppty intermediary rows' count is variable/unknown for each occurence and irregular/can be any number of intremediary rows?

I have this data as example:

So far, I've come up with this partial solution:

=IFS(AND(A2="",A3=""),"", AND(A2="",A3<>""),"", AND(A2<>"",A3<>""),ROWS(A2), AND(A2<>"",A3=""),ROWS(A2:UP TO NEXT NON-EMPTY ROW BENEATH (NOT COMPRISED (or minus the next non-empty row(-1)))))

The expected result should return as follows:

The Sheet copy:
https://docs.google.com/spreadsheets/d/1eLXdFINKVtS5Fxon8mIQDmBUTZokyY_Fb6tfWJRDOVI/edit?usp=sharing

Body:
I found a solution with a Monster formula but with simple iterative logics, and up to 50 intermediary blanks (for more only need to make the formula larger).

What I was lookind for was simply to print the cells/rows count of intermediary empty cells between 2 non-empty cells + adding to the count either the 1st non-empty cell or the last non-empty cell.

So for example if cell A1 and cell A9 have 8 empty cells between them, then return 8+1 (or 10-1).

The logics used is simple:
probe how many possible empty cells there can be between each 2 non-empty cells counting the 1st non-empty as well within column A (in the formula below the possibility is up to 50 empty cells), and for each case return the intermediary rows -1 (the last row).

The formula:

=IFS(AND(A1="",A2=""),"",AND(A1="",A2<>""),"",AND(A1<>"",A2<>""),ROWS(A1),AND(A1<>"",A2="",A3<>""),ROWS(A1:A3)-1,AND(A1<>"",A2="",A3="",A4<>""),ROWS(A1:A4)-1,AND(A1<>"",A2="",A3="",A4="",A5<>""),ROWS(A1:A5)-1,AND(A1<>"",A2="",A3="",A4="",A5="",A6<>""),ROWS(A1:A6)-1,AND(A1<>"",A2="",A3="",A4="",A5="",A6="",A7<>""),ROWS(A1:A7)-1,AND(A1<>"",A2="",A3="",A4="",A5="",A6="",A7="",A8<>""),ROWS(A1:A8)-1,AND(A1<>"",A2="",A3="",A4="",A5="",A6="",A7="",A8="",A9<>""),ROWS(A1:A9)-1,AND(A1<>"",A2="",A3="",A4="",A5="",A6="",A7="",A8="",A9="",A10<>""),ROWS(A1:A10)-1,AND(A1<>"",A2="",A3="",A4="",A5="",A6="",A7="",A8="",A9="",A10="",A11<>""),ROWS(A1:A11)-1,AND(A1<>"",A2="",A3="",A4="",A5="",A6="",A7="",A8="",A9="",A10="",A11="",A12<>""),ROWS(A1:A12)-1,AND(A1<>"",A2="",A3="",A4="",A5="",A6="",A7="",A8="",A9="",A10="",A11="",A12="",A13<>""),ROWS(A1:A13)-1,AND(A1<>"",A2="",A3="",A4="",A5="",A6="",A7="",A8="",A9="",A10="",A11="",A12="",A13="",A14<>""),ROWS(A1:A14)-1,AND(A1<>"",A2="",A3="",A4="",A5="",A6="",A7="",A8="",A9="",A10="",A11="",A12="",A13="",A14="",A15<>""),ROWS(A1:A15)-1,AND(A1<>"",A2="",A3="",A4="",A5="",A6="",A7="",A8="",A9="",A10="",A11="",A12="",A13="",A14="",A15="",A16<>""),ROWS(A1:A16)-1,AND(A1<>"",A2="",A3="",A4="",A5="",A6="",A7="",A8="",A9="",A10="",A11="",A12="",A13="",A14="",A15="",A16="",A17<>""),ROWS(A1:A17)-1,AND(A1<>"",A2="",A3="",A4="",A5="",A6="",A7="",A8="",A9="",A10="",A11="",A12="",A13="",A14="",A15="",A16="",A17="",A18<>""),ROWS(A1:A18)-1,AND(A1<>"",A2="",A3="",A4="",A5="",A6="",A7="",A8="",A9="",A10="",A11="",A12="",A13="",A14="",A15="",A16="",A17="",A18="",A19<>""),ROWS(A1:A19)-1,AND(A1<>"",A2="",A3="",A4="",A5="",A6="",A7="",A8="",A9="",A10="",A11="",A12="",A13="",A14="",A15="",A16="",A17="",A18="",A19="",A20<>""),ROWS(A1:A20)-1,AND(A1<>"",A2="",A3="",A4="",A5="",A6="",A7="",A8="",A9="",A10="",A11="",A12="",A13="",A14="",A15="",A16="",A17="",A18="",A19="",A20="",A21<>""),ROWS(A1:A21)-1,AND(A1<>"",A2="",A3="",A4="",A5="",A6="",A7="",A8="",A9="",A10="",A11="",A12="",A13="",A14="",A15="",A16="",A17="",A18="",A19="",A20="",A21="",A22<>""),ROWS(A1:A22)-1,AND(A1<>"",A2="",A3="",A4="",A5="",A6="",A7="",A8="",A9="",A10="",A11="",A12="",A13="",A14="",A15="",A16="",A17="",A18="",A19="",A20="",A21="",A22="",A23<>""),ROWS(A1:A23)-1,AND(A1<>"",A2="",A3="",A4="",A5="",A6="",A7="",A8="",A9="",A10="",A11="",A12="",A13="",A14="",A15="",A16="",A17="",A18="",A19="",A20="",A21="",A22="",A23="",A24<>""),ROWS(A1:A24)-1,AND(A1<>"",A2="",A3="",A4="",A5="",A6="",A7="",A8="",A9="",A10="",A11="",A12="",A13="",A14="",A15="",A16="",A17="",A18="",A19="",A20="",A21="",A22="",A23="",A24="",A25<>""),ROWS(A1:A25)-1,AND(A1<>"",A2="",A3="",A4="",A5="",A6="",A7="",A8="",A9="",A10="",A11="",A12="",A13="",A14="",A15="",A16="",A17="",A18="",A19="",A20="",A21="",A22="",A23="",A24="",A25="",A26<>""),ROWS(A1:A26)-1,AND(A1<>"",A2="",A3="",A4="",A5="",A6="",A7="",A8="",A9="",A10="",A11="",A12="",A13="",A14="",A15="",A16="",A17="",A18="",A19="",A20="",A21="",A22="",A23="",A24="",A25="",A26="",A27<>""),ROWS(A1:A27)-1,AND(A1<>"",A2="",A3="",A4="",A5="",A6="",A7="",A8="",A9="",A10="",A11="",A12="",A13="",A14="",A15="",A16="",A17="",A18="",A19="",A20="",A21="",A22="",A23="",A24="",A25="",A26="",A27="",A28<>""),ROWS(A1:A28)-1,AND(A1<>"",A2="",A3="",A4="",A5="",A6="",A7="",A8="",A9="",A10="",A11="",A12="",A13="",A14="",A15="",A16="",A17="",A18="",A19="",A20="",A21="",A22="",A23="",A24="",A25="",A26="",A27="",A28="",A29<>""),ROWS(A1:A29)-1,AND(A1<>"",A2="",A3="",A4="",A5="",A6="",A7="",A8="",A9="",A10="",A11="",A12="",A13="",A14="",A15="",A16="",A17="",A18="",A19="",A20="",A21="",A22="",A23="",A24="",A25="",A26="",A27="",A28="",A29="",A30<>""),ROWS(A1:A30)-1,AND(A1<>"",A2="",A3="",A4="",A5="",A6="",A7="",A8="",A9="",A10="",A11="",A12="",A13="",A14="",A15="",A16="",A17="",A18="",A19="",A20="",A21="",A22="",A23="",A24="",A25="",A26="",A27="",A28="",A29="",A30="",A31<>""),ROWS(A1:A31)-1,AND(A1<>"",A2="",A3="",A4="",A5="",A6="",A7="",A8="",A9="",A10="",A11="",A12="",A13="",A14="",A15="",A16="",A17="",A18="",A19="",A20="",A21="",A22="",A23="",A24="",A25="",A26="",A27="",A28="",A29="",A30="",A31="",A32<>""),ROWS(A1:A32)-1,AND(A1<>"",A2="",A3="",A4="",A5="",A6="",A7="",A8="",A9="",A10="",A11="",A12="",A13="",A14="",A15="",A16="",A17="",A18="",A19="",A20="",A21="",A22="",A23="",A24="",A25="",A26="",A27="",A28="",A29="",A30="",A31="",A32="",A33<>""),ROWS(A1:A33)-1,AND(A1<>"",A2="",A3="",A4="",A5="",A6="",A7="",A8="",A9="",A10="",A11="",A12="",A13="",A14="",A15="",A16="",A17="",A18="",A19="",A20="",A21="",A22="",A23="",A24="",A25="",A26="",A27="",A28="",A29="",A30="",A31="",A32="",A33="",A34<>""),ROWS(A1:A34)-1,AND(A1<>"",A2="",A3="",A4="",A5="",A6="",A7="",A8="",A9="",A10="",A11="",A12="",A13="",A14="",A15="",A16="",A17="",A18="",A19="",A20="",A21="",A22="",A23="",A24="",A25="",A26="",A27="",A28="",A29="",A30="",A31="",A32="",A33="",A34="",A35<>""),ROWS(A1:A35)-1,AND(A1<>"",A2="",A3="",A4="",A5="",A6="",A7="",A8="",A9="",A10="",A11="",A12="",A13="",A14="",A15="",A16="",A17="",A18="",A19="",A20="",A21="",A22="",A23="",A24="",A25="",A26="",A27="",A28="",A29="",A30="",A31="",A32="",A33="",A34="",A35="",A36<>""),ROWS(A1:A36)-1,AND(A1<>"",A2="",A3="",A4="",A5="",A6="",A7="",A8="",A9="",A10="",A11="",A12="",A13="",A14="",A15="",A16="",A17="",A18="",A19="",A20="",A21="",A22="",A23="",A24="",A25="",A26="",A27="",A28="",A29="",A30="",A31="",A32="",A33="",A34="",A35="",A36="",A37<>""),ROWS(A1:A37)-1,AND(A1<>"",A2="",A3="",A4="",A5="",A6="",A7="",A8="",A9="",A10="",A11="",A12="",A13="",A14="",A15="",A16="",A17="",A18="",A19="",A20="",A21="",A22="",A23="",A24="",A25="",A26="",A27="",A28="",A29="",A30="",A31="",A32="",A33="",A34="",A35="",A36="",A37="",A38<>""),ROWS(A1:A38)-1,AND(A1<>"",A2="",A3="",A4="",A5="",A6="",A7="",A8="",A9="",A10="",A11="",A12="",A13="",A14="",A15="",A16="",A17="",A18="",A19="",A20="",A21="",A22="",A23="",A24="",A25="",A26="",A27="",A28="",A29="",A30="",A31="",A32="",A33="",A34="",A35="",A36="",A37="",A38="",A39<>""),ROWS(A1:A39)-1,AND(A1<>"",A2="",A3="",A4="",A5="",A6="",A7="",A8="",A9="",A10="",A11="",A12="",A13="",A14="",A15="",A16="",A17="",A18="",A19="",A20="",A21="",A22="",A23="",A24="",A25="",A26="",A27="",A28="",A29="",A30="",A31="",A32="",A33="",A34="",A35="",A36="",A37="",A38="",A39="",A40<>""),ROWS(A1:A40)-1,AND(A1<>"",A2="",A3="",A4="",A5="",A6="",A7="",A8="",A9="",A10="",A11="",A12="",A13="",A14="",A15="",A16="",A17="",A18="",A19="",A20="",A21="",A22="",A23="",A24="",A25="",A26="",A27="",A28="",A29="",A30="",A31="",A32="",A33="",A34="",A35="",A36="",A37="",A38="",A39="",A40="",A41<>""),ROWS(A1:A41)-1,AND(A1<>"",A2="",A3="",A4="",A5="",A6="",A7="",A8="",A9="",A10="",A11="",A12="",A13="",A14="",A15="",A16="",A17="",A18="",A19="",A20="",A21="",A22="",A23="",A24="",A25="",A26="",A27="",A28="",A29="",A30="",A31="",A32="",A33="",A34="",A35="",A36="",A37="",A38="",A39="",A40="",A41="",A42<>""),ROWS(A1:A42)-1,AND(A1<>"",A2="",A3="",A4="",A5="",A6="",A7="",A8="",A9="",A10="",A11="",A12="",A13="",A14="",A15="",A16="",A17="",A18="",A19="",A20="",A21="",A22="",A23="",A24="",A25="",A26="",A27="",A28="",A29="",A30="",A31="",A32="",A33="",A34="",A35="",A36="",A37="",A38="",A39="",A40="",A41="",A42="",A43<>""),ROWS(A1:A43)-1,AND(A1<>"",A2="",A3="",A4="",A5="",A6="",A7="",A8="",A9="",A10="",A11="",A12="",A13="",A14="",A15="",A16="",A17="",A18="",A19="",A20="",A21="",A22="",A23="",A24="",A25="",A26="",A27="",A28="",A29="",A30="",A31="",A32="",A33="",A34="",A35="",A36="",A37="",A38="",A39="",A40="",A41="",A42="",A43="",A44<>""),ROWS(A1:A44)-1,AND(A1<>"",A2="",A3="",A4="",A5="",A6="",A7="",A8="",A9="",A10="",A11="",A12="",A13="",A14="",A15="",A16="",A17="",A18="",A19="",A20="",A21="",A22="",A23="",A24="",A25="",A26="",A27="",A28="",A29="",A30="",A31="",A32="",A33="",A34="",A35="",A36="",A37="",A38="",A39="",A40="",A41="",A42="",A43="",A44="",A45<>""),ROWS(A1:A45)-1,AND(A1<>"",A2="",A3="",A4="",A5="",A6="",A7="",A8="",A9="",A10="",A11="",A12="",A13="",A14="",A15="",A16="",A17="",A18="",A19="",A20="",A21="",A22="",A23="",A24="",A25="",A26="",A27="",A28="",A29="",A30="",A31="",A32="",A33="",A34="",A35="",A36="",A37="",A38="",A39="",A40="",A41="",A42="",A43="",A44="",A45="",A46<>""),ROWS(A1:A46)-1,AND(A1<>"",A2="",A3="",A4="",A5="",A6="",A7="",A8="",A9="",A10="",A11="",A12="",A13="",A14="",A15="",A16="",A17="",A18="",A19="",A20="",A21="",A22="",A23="",A24="",A25="",A26="",A27="",A28="",A29="",A30="",A31="",A32="",A33="",A34="",A35="",A36="",A37="",A38="",A39="",A40="",A41="",A42="",A43="",A44="",A45="",A46="",A47<>""),ROWS(A1:A47)-1,AND(A1<>"",A2="",A3="",A4="",A5="",A6="",A7="",A8="",A9="",A10="",A11="",A12="",A13="",A14="",A15="",A16="",A17="",A18="",A19="",A20="",A21="",A22="",A23="",A24="",A25="",A26="",A27="",A28="",A29="",A30="",A31="",A32="",A33="",A34="",A35="",A36="",A37="",A38="",A39="",A40="",A41="",A42="",A43="",A44="",A45="",A46="",A47="",A48<>""),ROWS(A1:A48)-1,AND(A1<>"",A2="",A3="",A4="",A5="",A6="",A7="",A8="",A9="",A10="",A11="",A12="",A13="",A14="",A15="",A16="",A17="",A18="",A19="",A20="",A21="",A22="",A23="",A24="",A25="",A26="",A27="",A28="",A29="",A30="",A31="",A32="",A33="",A34="",A35="",A36="",A37="",A38="",A39="",A40="",A41="",A42="",A43="",A44="",A45="",A46="",A47="",A48="",A49<>""),ROWS(A1:A49)-1,AND(A1<>"",A2="",A3="",A4="",A5="",A6="",A7="",A8="",A9="",A10="",A11="",A12="",A13="",A14="",A15="",A16="",A17="",A18="",A19="",A20="",A21="",A22="",A23="",A24="",A25="",A26="",A27="",A28="",A29="",A30="",A31="",A32="",A33="",A34="",A35="",A36="",A37="",A38="",A39="",A40="",A41="",A42="",A43="",A44="",A45="",A46="",A47="",A48="",A49="",A50<>""),ROWS(A1:A50)-1)

Here the images sheet of the result:

The Sheet

Can it be done in a simpler way but still with a single formula?

Thanks a lot for your next input!


来源: stackexchange

问:
How to fix "System.Data.OleDb.OleDbException: 'Syntax error in UPDATE statement.'"?
I have been getting a syntax error in my UPDATE datagridview code which happens to work in another .cs file. My group has been looking at different solutions online but everything won't work.

My group has been looking at different solutions online but everything won't seem to work.

```<code>        {
            connection.Open();
            OleDbCommand cmd = connection.CreateCommand();
            cmd.CommandType = CommandType.Text;
            cmd.CommandText = "Update Table1 set treatment = '" + treat.Text + "', remarks = '" + appRemarks.Text + "', cost = '" + treatCost.Text + "', Time = '" + textBox2.Text + "' where lastName = '" + Lastname.Text + "' ";

            cmd.ExecuteNonQuery();
            connection.Close();
            MessageBox.Show("Updated Successfully!");
        }
</code>```

The expected output should be Updated Successfully! and it should reflect in the database file after clicking the update button. Sometimes the output is "Microsoft Engine database" which does not save the changes.

The error says "System.Data.OleDb.OleDbException: 'Syntax error in UPDATE statement.'" pointing to cmd.ExecuteNonQuery();

答:
First, never use string concatenation to build a query. You're asking for a SQL Injection attack. The biggest thing I could see here is make sure that only columns that are string columns (varchar, char, text, etc..) have single-quoted values. Is cost a number? If so then it should be:

```<code>, cost=" + treatCost.Text + ",
</code>```

If cost is a number, also make sure that there isn't a currency amount in the input field. If someone puts in 1,422.00 it's not a number and will fail since , is for decoration.
If someone puts in $1422.00 it's not a number as $ is for decoration.
Either of these would fail the query.

ContentLicense: CC BY-SA 4.0

Body:
I have been getting a syntax error in my UPDATE datagridview code which happens to work in another .cs file. My group has been looking at different solutions online but everything won't work.

My group has been looking at different solutions online but everything won't seem to work.

        {
            connection.Open();
            OleDbCommand cmd = connection.CreateCommand();
            cmd.CommandType = CommandType.Text;
            cmd.CommandText = "Update Table1 set treatment = '" + treat.Text + "', remarks = '" + appRemarks.Text + "', cost = '" + treatCost.Text + "', Time = '" + textBox2.Text + "' where lastName = '" + Lastname.Text + "' ";

            cmd.ExecuteNonQuery();
            connection.Close();
            MessageBox.Show("Updated Successfully!");
        }

The expected output should be Updated Successfully! and it should reflect in the database file after clicking the update button. Sometimes the output is "Microsoft Engine database" which does not save the changes.

The error says "System.Data.OleDb.OleDbException: 'Syntax error in UPDATE statement.'" pointing to cmd.ExecuteNonQuery();

Body:
First, never use string concatenation to build a query. You're asking for a SQL Injection attack. The biggest thing I could see here is make sure that only columns that are string columns (varchar, char, text, etc..) have single-quoted values. Is cost a number? If so then it should be:

, cost=" + treatCost.Text + ",

If cost is a number, also make sure that there isn't a currency amount in the input field. If someone puts in 1,422.00 it's not a number and will fail since , is for decoration.
If someone puts in $1422.00 it's not a number as $ is for decoration.
Either of these would fail the query.


问:
Is there a concise way to check if an int variable is equal to a series of ints? | C#
Rather than something like this:

```<code>switch (id) {
case 2:
case 5:
case 11:
case 15:
...
}
</code>```

Is there a concise way to check if an int variable is equal to any one of a series of integers? Maybe something like if (id == {2|5|11|15}) ...?

答:
You could put all the ints into a HashSet and do a contains.</p>

```<code>Hashset<int> ids = new HashSet<int>() {...initialize...};

if(ids.Contains(id)){
...
}
</code>```

ContentLicense: CC BY-SA 3.0

Body:
Rather than something like this:

switch (id) {
case 2:
case 5:
case 11:
case 15:
...
}

Is there a concise way to check if an int variable is equal to any one of a series of integers? Maybe something like if (id == {2|5|11|15}) ...?

Body:
You could put all the ints into a HashSet and do a contains.

Hashset<int> ids = new HashSet<int>() {...initialize...};

if(ids.Contains(id)){
...
}


问:
How to ignore SSL validation in .net core 2.1
I am trying to call a web service that is deployed on a Linux Server that has a self-signed certificate from an application developed in .net core and deployed on an IIS server (Windows server 2012).

But when I try to call the endpoint the next error is thrown:

"Message": "The SSL connection could not be established, see inner
  exception.",
      "Description": "InnerError : System.Security.Authentication.AuthenticationException: Authentication
  failed, see inner exception. --->
  System.ComponentModel.Win32Exception: Mensaje recibido inesperado, o
  bien su formato es incorrecto\r\n   --- End of inner exception stack
  trace ---\r\n   at
  System.Net.Security.SslState.StartSendAuthResetSignal(ProtocolToken
  message, AsyncProtocolRequest asyncRequest, ExceptionDispatchInfo
  exception)\r\n   at
  System.Net.Security.SslState.CheckCompletionBeforeNextReceive(ProtocolToken
  message, AsyncProtocolRequest asyncRequest)\r\n   at
  System.Net.Security.SslState.StartSendBlob(Byte[] incoming, Int32
  count, AsyncProtocolRequest asyncRequest)\r\n   at
  System.Net.Security.SslState.ProcessReceivedBlob(Byte[] buffer, Int32
  count, AsyncProtocolRequest asyncRequest)\r\n   at
  System.Net.Security.SslState.StartReadFrame(Byte[] buffer, Int32
  readBytes, AsyncProtocolRequest asyncRequest)\r\n   at
  System.Net.Security.SslState.PartialFrameCallback(AsyncProtocolRequest
  asyncRequest)\r\n--- End of stack trace from previous location where
  exception was thrown ---\r\n   at
  System.Net.Security.SslState.ThrowIfExceptional()\r\n   at
  System.Net.Security.SslState.InternalEndProcessAuthentication(LazyAsyncResult
  lazyResult)\r\n   at
  System.Net.Security.SslState.EndProcessAuthentication(IAsyncResult
  result)\r\n   at
  System.Net.Security.SslStream.EndAuthenticateAsClient(IAsyncResult
  asyncResult)\r\n   at
  System.Net.Security.SslStream.<>c.b__47_1(IAsyncResult
  iar)\r\n   at
  System.Threading.Tasks.TaskFactory1.FromAsyncCoreLogic(IAsyncResult
  iar, Func2 endFunction, Action1 endAction, Task1 promise, Boolean
  requiresSynchronization)\r\n--- End of stack trace from previous
  location where exception was thrown ---\r\n   at
  System.Net.Http.ConnectHelper.EstablishSslConnectionAsyncCore(Stream
  stream, SslClientAuthenticationOptions sslOptions, CancellationToken
  cancellationToken) | stackTrace :    at
  System.Net.Http.ConnectHelper.EstablishSslConnectionAsyncCore(Stream
  stream, SslClientAuthenticationOptions sslOptions, CancellationToken
  cancellationToken)\r\n   at
  System.Threading.Tasks.ValueTask1.get_Result()\r\n   at
  System.Net.Http.HttpConnectionPool.CreateConnectionAsync(HttpRequestMessage
  request, CancellationToken cancellationToken)\r\n   at
  System.Threading.Tasks.ValueTask1.get_Result()\r\n   at
  System.Net.Http.HttpConnectionPool.WaitForCreatedConnectionAsync(ValueTask1
  creationTask)\r\n   at
  System.Threading.Tasks.ValueTask1.get_Result()\r\n   at
  System.Net.Http.HttpConnectionPool.SendWithRetryAsync(HttpRequestMessage
  request, Boolean doRequestAuth, CancellationToken
  cancellationToken)\r\n   at
  System.Net.Http.RedirectHandler.SendAsync(HttpRequestMessage request,
  CancellationToken cancellationToken)\r\n   at
  System.Net.Http.HttpClient.FinishSendAsyncBuffered(Task`1 sendTask,
  HttpRequestMessage request, CancellationTokenSource cts, Boolean
  disposeCts)\r\n   at
  ReservasProxy.Data.APIConnection.CallXMLFormDataApiPostAsyc(String
  body) in
  C:\gitProjects\ResevasProxy\ReservasProxy\ReservasProxy\Data\APIConnection.cs:line
  181\r\n

I already try the next solutions but they didn´t work.

Solution 1 :

```<code>          using (var httpClientHandler = new HttpClientHandler())
        {
            httpClientHandler.ServerCertificateCustomValidationCallback = (message, cert, chain, errors) => { return true; };
            // Make your request...
            //send request
            using (var httpClient = new HttpClient(httpClientHandler))
            {

                var content = new StringContent(body, Encoding.UTF8, "application/soap+xml");
                HttpResponseMessage response = await httpClient.PostAsync(_url, content);
                //var res = await response.Content.ReadAsAsync<T>();

            }

        }
</code>```

Solution 2:

```<code>            //send request
        using (var httpClient = new HttpClient())
        {
             ServicePointManager.ServerCertificateValidationCallback = delegate { return true; };
            ServicePointManager.SecurityProtocol = SecurityProtocolType.Tls;
            ServicePointManager.ServerCertificateValidationCallback += (sender, cert, chain, sslPolicyErrors) => true;
            var content = new StringContent(body, Encoding.UTF8, "application/soap+xml");
            HttpResponseMessage response = await httpClient.PostAsync(_url, content);

        }
</code>```

Solution 3:
Trying to import the certificate and then make the call but still not working.

```<code>const string certPath = @"C:\soaProdcer.cer";
var handler = new HttpClientHandler
            {
                ClientCertificateOptions = ClientCertificateOption.Manual,
                SslProtocols = System.Security.Authentication.SslProtocols.Tls
            };
            handler.ClientCertificates.Add(new System.Security.Cryptography.X509Certificates.X509Certificate(certPath));

            //send request
            using (var httpClient = new HttpClient(handler))
            {
                var content = new StringContent(body, Encoding.UTF8, "application/soap+xml");
                HttpResponseMessage response = await httpClient.PostAsync(_url, content);

            }
</code>```

I got the certificate using OpenSSL

```<code>>openssl s_client -showcerts -connect serversoa:443

No client certificate CA names sent
---
SSL handshake has read 774 bytes and written 493 bytes
---
New, TLSv1/SSLv3, Cipher is RC4-SHA
Server public key is 1024 bit
Secure Renegotiation IS supported
Compression: NONE
Expansion: NONE
No ALPN negotiated
SSL-Session:
    Protocol  : TLSv1
    Cipher    : RC4-SHA
    Session-ID: 4E0F69C75B8F041101562F7E9B3EA349
    Session-ID-ctx:
    Master-Key: 61A916A9B8AF26281B5F7A0138DF5E4C2A4B83995E0B3FDD2274BAD0D8E3C2B5E98AA7CCB48A6543F6814C2540B18848
    Key-Arg   : None
    PSK identity: None
    PSK identity hint: None
    SRP username: None
    Start Time: 1558979896
    Timeout   : 300 (sec)
    Verify return code: 18 (self signed certificate)
</code>```

I imported the certificate into the IIS server into the trusted root certification authorities.

答:
As Ilya said it wasn´t a problem with the certificate CA authority. The problem was that the client was trying to use a different version of TLS (1.2)
The solution was to specify the TLS version.

```<code>using (var httpClientHandler = new HttpClientHandler())
            {
                httpClientHandler.ServerCertificateCustomValidationCallback = (message, cert, chain, errors) => { return true; };
                httpClientHandler.SslProtocols = System.Security.Authentication.SslProtocols.Tls;
                //send request
                using (var httpClient = new HttpClient(httpClientHandler))
                {
                    var content = new StringContent(body, Encoding.UTF8, "application/soap+xml");
                    HttpResponseMessage response = await httpClient.PostAsync(_url, content);

                }
            }
</code>```

I used Wireshark to sniffer the traffic and see what was going on...

Client sending hello with version, not supported

The server closing the connection

After finishing the test in my computer and the tests were successful I deploy the application on IIS server. When I started testing my application on the server it started throwing the same exception as before.

Why?

It turned out that the server had deactivated the cipher (RC4) As the next figure shows.

So if you are using Windows like me you just need to check the ciphers that the certificate is using. As I mentioned before the Linux server was using a CR4 cipher in the certificate

Body:
I am trying to call a web service that is deployed on a Linux Server that has a self-signed certificate from an application developed in .net core and deployed on an IIS server (Windows server 2012).

But when I try to call the endpoint the next error is thrown:

"Message": "The SSL connection could not be established, see inner
  exception.",
      "Description": "InnerError : System.Security.Authentication.AuthenticationException: Authentication
  failed, see inner exception. --->
  System.ComponentModel.Win32Exception: Mensaje recibido inesperado, o
  bien su formato es incorrecto\r\n   --- End of inner exception stack
  trace ---\r\n   at
  System.Net.Security.SslState.StartSendAuthResetSignal(ProtocolToken
  message, AsyncProtocolRequest asyncRequest, ExceptionDispatchInfo
  exception)\r\n   at
  System.Net.Security.SslState.CheckCompletionBeforeNextReceive(ProtocolToken
  message, AsyncProtocolRequest asyncRequest)\r\n   at
  System.Net.Security.SslState.StartSendBlob(Byte[] incoming, Int32
  count, AsyncProtocolRequest asyncRequest)\r\n   at
  System.Net.Security.SslState.ProcessReceivedBlob(Byte[] buffer, Int32
  count, AsyncProtocolRequest asyncRequest)\r\n   at
  System.Net.Security.SslState.StartReadFrame(Byte[] buffer, Int32
  readBytes, AsyncProtocolRequest asyncRequest)\r\n   at
  System.Net.Security.SslState.PartialFrameCallback(AsyncProtocolRequest
  asyncRequest)\r\n--- End of stack trace from previous location where
  exception was thrown ---\r\n   at
  System.Net.Security.SslState.ThrowIfExceptional()\r\n   at
  System.Net.Security.SslState.InternalEndProcessAuthentication(LazyAsyncResult
  lazyResult)\r\n   at
  System.Net.Security.SslState.EndProcessAuthentication(IAsyncResult
  result)\r\n   at
  System.Net.Security.SslStream.EndAuthenticateAsClient(IAsyncResult
  asyncResult)\r\n   at
  System.Net.Security.SslStream.<>c.b__47_1(IAsyncResult
  iar)\r\n   at
  System.Threading.Tasks.TaskFactory1.FromAsyncCoreLogic(IAsyncResult
  iar, Func2 endFunction, Action1 endAction, Task1 promise, Boolean
  requiresSynchronization)\r\n--- End of stack trace from previous
  location where exception was thrown ---\r\n   at
  System.Net.Http.ConnectHelper.EstablishSslConnectionAsyncCore(Stream
  stream, SslClientAuthenticationOptions sslOptions, CancellationToken
  cancellationToken) | stackTrace :    at
  System.Net.Http.ConnectHelper.EstablishSslConnectionAsyncCore(Stream
  stream, SslClientAuthenticationOptions sslOptions, CancellationToken
  cancellationToken)\r\n   at
  System.Threading.Tasks.ValueTask1.get_Result()\r\n   at
  System.Net.Http.HttpConnectionPool.CreateConnectionAsync(HttpRequestMessage
  request, CancellationToken cancellationToken)\r\n   at
  System.Threading.Tasks.ValueTask1.get_Result()\r\n   at
  System.Net.Http.HttpConnectionPool.WaitForCreatedConnectionAsync(ValueTask1
  creationTask)\r\n   at
  System.Threading.Tasks.ValueTask1.get_Result()\r\n   at
  System.Net.Http.HttpConnectionPool.SendWithRetryAsync(HttpRequestMessage
  request, Boolean doRequestAuth, CancellationToken
  cancellationToken)\r\n   at
  System.Net.Http.RedirectHandler.SendAsync(HttpRequestMessage request,
  CancellationToken cancellationToken)\r\n   at
  System.Net.Http.HttpClient.FinishSendAsyncBuffered(Task`1 sendTask,
  HttpRequestMessage request, CancellationTokenSource cts, Boolean
  disposeCts)\r\n   at
  ReservasProxy.Data.APIConnection.CallXMLFormDataApiPostAsyc(String
  body) in
  C:\gitProjects\ResevasProxy\ReservasProxy\ReservasProxy\Data\APIConnection.cs:line
  181\r\n

I already try the next solutions but they didn´t work.

Solution 1 :

          using (var httpClientHandler = new HttpClientHandler())
        {
            httpClientHandler.ServerCertificateCustomValidationCallback = (message, cert, chain, errors) => { return true; };
            // Make your request...
            //send request
            using (var httpClient = new HttpClient(httpClientHandler))
            {

                var content = new StringContent(body, Encoding.UTF8, "application/soap+xml");
                HttpResponseMessage response = await httpClient.PostAsync(_url, content);
                //var res = await response.Content.ReadAsAsync<T>();

            }

        }

Solution 2:

            //send request
        using (var httpClient = new HttpClient())
        {
             ServicePointManager.ServerCertificateValidationCallback = delegate { return true; };
            ServicePointManager.SecurityProtocol = SecurityProtocolType.Tls;
            ServicePointManager.ServerCertificateValidationCallback += (sender, cert, chain, sslPolicyErrors) => true;
            var content = new StringContent(body, Encoding.UTF8, "application/soap+xml");
            HttpResponseMessage response = await httpClient.PostAsync(_url, content);

        }

Solution 3:
Trying to import the certificate and then make the call but still not working.

const string certPath = @"C:\soaProdcer.cer";
var handler = new HttpClientHandler
            {
                ClientCertificateOptions = ClientCertificateOption.Manual,
                SslProtocols = System.Security.Authentication.SslProtocols.Tls
            };
            handler.ClientCertificates.Add(new System.Security.Cryptography.X509Certificates.X509Certificate(certPath));

            //send request
            using (var httpClient = new HttpClient(handler))
            {
                var content = new StringContent(body, Encoding.UTF8, "application/soap+xml");
                HttpResponseMessage response = await httpClient.PostAsync(_url, content);

            }

I got the certificate using OpenSSL

>openssl s_client -showcerts -connect serversoa:443

No client certificate CA names sent
---
SSL handshake has read 774 bytes and written 493 bytes
---
New, TLSv1/SSLv3, Cipher is RC4-SHA
Server public key is 1024 bit
Secure Renegotiation IS supported
Compression: NONE
Expansion: NONE
No ALPN negotiated
SSL-Session:
    Protocol  : TLSv1
    Cipher    : RC4-SHA
    Session-ID: 4E0F69C75B8F041101562F7E9B3EA349
    Session-ID-ctx:
    Master-Key: 61A916A9B8AF26281B5F7A0138DF5E4C2A4B83995E0B3FDD2274BAD0D8E3C2B5E98AA7CCB48A6543F6814C2540B18848
    Key-Arg   : None
    PSK identity: None
    PSK identity hint: None
    SRP username: None
    Start Time: 1558979896
    Timeout   : 300 (sec)
    Verify return code: 18 (self signed certificate)

I imported the certificate into the IIS server into the trusted root certification authorities.

Body:
As Ilya said it wasn´t a problem with the certificate CA authority. The problem was that the client was trying to use a different version of TLS (1.2)
The solution was to specify the TLS version.

using (var httpClientHandler = new HttpClientHandler())
            {
                httpClientHandler.ServerCertificateCustomValidationCallback = (message, cert, chain, errors) => { return true; };
                httpClientHandler.SslProtocols = System.Security.Authentication.SslProtocols.Tls;
                //send request
                using (var httpClient = new HttpClient(httpClientHandler))
                {
                    var content = new StringContent(body, Encoding.UTF8, "application/soap+xml");
                    HttpResponseMessage response = await httpClient.PostAsync(_url, content);

                }
            }

I used Wireshark to sniffer the traffic and see what was going on...

Client sending hello with version, not supported

The server closing the connection

After finishing the test in my computer and the tests were successful I deploy the application on IIS server. When I started testing my application on the server it started throwing the same exception as before.

Why?

It turned out that the server had deactivated the cipher (RC4) As the next figure shows.

So if you are using Windows like me you just need to check the ciphers that the certificate is using. As I mentioned before the Linux server was using a CR4 cipher in the certificate


问:
Calculate the difference between two hours on PostgreSQL 9.4
Given a table as the following:

```<code>    create table meetings(
    id integer primary key,
    start_time varchar,
    end_time varchar
)
</code>```

Considering that the string stored in this table follow the format 'HH:MM' and have a 24 hours format, is there a command on PostgreSQL 9.4 that I can cast fields to time, calculate the difference between them, and return a single result of the counting of full hours available?

e.g: start_time: '08:00' - end_time: '12:00'
Result must be 4.

答:
In your particular case, assuming that you are working with clock values (both of them belonging to the same day), I would guess you can do this

```<code>(clock_to::time - clock_from::time) as duration
</code>```

Allow me to leave you a ready to run example:

```<code>with cte as (
  select '4:00'::varchar as clock_from, '14:00'::varchar as clock_to
)
select (clock_to::time - clock_from::time) as duration
from cte
</code>```

Body:
Given a table as the following:

    create table meetings(
    id integer primary key,
    start_time varchar,
    end_time varchar
)

Considering that the string stored in this table follow the format 'HH:MM' and have a 24 hours format, is there a command on PostgreSQL 9.4 that I can cast fields to time, calculate the difference between them, and return a single result of the counting of full hours available?

e.g: start_time: '08:00' - end_time: '12:00'
Result must be 4.

Body:
In your particular case, assuming that you are working with clock values (both of them belonging to the same day), I would guess you can do this

(clock_to::time - clock_from::time) as duration

Allow me to leave you a ready to run example:

with cte as (
  select '4:00'::varchar as clock_from, '14:00'::varchar as clock_to
)
select (clock_to::time - clock_from::time) as duration
from cte


问:
Filter a one to many relation record result
I need to filter the results given from a one to many relation directly from the model object, but I cant find the right way.
Here, the relations:

I have a User model that can subscript to many companies (company model), and a company can have many users subscripted to it, so, is a many to many relation.

In every company, this user has a personal info, so, every user, could have many profiles (profile model) one for each company that is subscripted to.
So It is a one to many relation.

Imagine I want to retrieve the company that a user is currently viewing directly from the model, this, Im achieving by filtering the many to many relation:

```<code>class User extends Authenticatable
{
///
 public function obtainLoggedOnCompany()
 {
   return $this->belongsToMany('app\Company', 'user_company', 'id', 'company_id')->withPivot('selected')->wherePivot('selected', 1)
 }
</code>```

Then, if I want to return the selected company in a blade view I just call:

Auth::user()->obtainLoggedOnCompany->first();

All thanks to the withPivot and wherePivot clause.

Different is the case when I want to retrieve the registered profile of a currently selected company, I tried:

```<code>public function obtainSelectedProfile()
{
$SelectedCompany= $this->obtainLoggedOnCompany->first();

return $this->hasMany('app\Profile','user_id')->where('company_id', '=', $SelectedCompany->company_id);
}
</code>```

But it throws a Trying to get property of non object Exception.
Is there another way to filter one to many relations directly in the model relation function?

Iam using Laravel 5.2

答:
You can achieve this by passing variable to eager loading and updating your relationship structure. Try this

User Model:

```<code>class User extends Authenticatable
{
    ///
    public function obtainLoggedOnCompany()
    {
         return $this->belongsToMany('App\Company', 'user_company', 'user_id', 'company_id');
    }

}
</code>```

Company Model:

```<code>class Company extends Model
{
    ///
    public function profile()
    {
        return $this->hasOne('App\Profile', 'company_id');
    }
}
</code>```

Example A use case of this:

```<code>$user_id = 1;
$user = User::where('id', $user_id)->with(['company' => function($query) use ($user_id) {

           return $query->with(['profile' => function($query2) use ($user_id) {
                                              return $query2->where('user_id', $user_id);
                                            }]);
        }])->first();
// $user variable contains user details, company details, and profile
</code>```

Body:
I need to filter the results given from a one to many relation directly from the model object, but I cant find the right way.
Here, the relations:

I have a User model that can subscript to many companies (company model), and a company can have many users subscripted to it, so, is a many to many relation.

In every company, this user has a personal info, so, every user, could have many profiles (profile model) one for each company that is subscripted to.
So It is a one to many relation.

Imagine I want to retrieve the company that a user is currently viewing directly from the model, this, Im achieving by filtering the many to many relation:

class User extends Authenticatable
{
///
 public function obtainLoggedOnCompany()
 {
   return $this->belongsToMany('app\Company', 'user_company', 'id', 'company_id')->withPivot('selected')->wherePivot('selected', 1)
 }

Then, if I want to return the selected company in a blade view I just call:

Auth::user()->obtainLoggedOnCompany->first();

All thanks to the withPivot and wherePivot clause.

Different is the case when I want to retrieve the registered profile of a currently selected company, I tried:

public function obtainSelectedProfile()
{
$SelectedCompany= $this->obtainLoggedOnCompany->first();

return $this->hasMany('app\Profile','user_id')->where('company_id', '=', $SelectedCompany->company_id);
}

But it throws a Trying to get property of non object Exception.
Is there another way to filter one to many relations directly in the model relation function?

Iam using Laravel 5.2

Body:
You can achieve this by passing variable to eager loading and updating your relationship structure. Try this

User Model:

class User extends Authenticatable
{
    ///
    public function obtainLoggedOnCompany()
    {
         return $this->belongsToMany('App\Company', 'user_company', 'user_id', 'company_id');
    }

}

Company Model:

class Company extends Model
{
    ///
    public function profile()
    {
        return $this->hasOne('App\Profile', 'company_id');
    }
}

Example A use case of this:

$user_id = 1;
$user = User::where('id', $user_id)->with(['company' => function($query) use ($user_id) {

           return $query->with(['profile' => function($query2) use ($user_id) {
                                              return $query2->where('user_id', $user_id);
                                            }]);
        }])->first();
// $user variable contains user details, company details, and profile


问:
TinyMCE 5: Disabled editor but allow to copy text
How to disable the Editor but allow the user to copy the text?

When I set disabled to true it's now possible to select and copy text.

```<code><Editor disabled={true} />
</code>```

答:
I've found a solution.

Just set the contenteditable attribute to false (you can delete the content).

```<code>// do not use this solution!
<Editor
  init={{
    init_instance_callback: editor => {
      editor.getBody().setAttrib('contenteditable', false);
    }
  }}
/>
</code>```

UPDATE:

```<code><Editor
  init={{
    init_instance_callback: editor => {
      editor.setMode('readonly');
    }
  }}
/>
</code>```

Body:
How to disable the Editor but allow the user to copy the text?

When I set disabled to true it's now possible to select and copy text.

<Editor disabled={true} />

Body:
I've found a solution.

Just set the contenteditable attribute to false (you can delete the content).

// do not use this solution!
<Editor
  init={{
    init_instance_callback: editor => {
      editor.getBody().setAttrib('contenteditable', false);
    }
  }}
/>

UPDATE:

<Editor
  init={{
    init_instance_callback: editor => {
      editor.setMode('readonly');
    }
  }}
/>


问:
How to convert a column in a csv file using Nifi?
I Have a raw csv file as below

```<code>   SVEIS , SVESID,SVETIME
   Quneter,53553,01122003010005
   renchure,37151,12092008011005
</code>```

now I need to change the data  from day month year to year day month as below

```<code>   SVEIS , SVESID,SVETIME
  Quneter,53553,2003-01-12 01:00:05
  renchure,37151,2008-12-09 01:10:05
</code>```

I need to change this using NIFI

I have used replace text processor but I am getting error like unable to process 10 of 10 records in nifi

答:
While both of the existing answers explain how to accomplish this task using String parsing via regular expressions, those solutions will be fairly complicated to change if the incoming data changes in any way. The question is for Apache NiFi, and the solution is to treat the CSV data as records and use the UpdateRecord processor. This processor allows you to use RecordPath syntax to specify the field (column) you're interested in and replace it with a new value, which can be static or determined via Expression Language. You can use the #toDate and #format methods to convert the string from the incoming format to the desired one (or simply insert the delimiters directly).

There are good articles about using the RecordPath mechanics as well.

Body:
I Have a raw csv file as below

   SVEIS , SVESID,SVETIME
   Quneter,53553,01122003010005
   renchure,37151,12092008011005

now I need to change the data  from day month year to year day month as below

   SVEIS , SVESID,SVETIME
  Quneter,53553,2003-01-12 01:00:05
  renchure,37151,2008-12-09 01:10:05

I need to change this using NIFI

I have used replace text processor but I am getting error like unable to process 10 of 10 records in nifi


问:
How do you see if a key includes a value and return the key up 2 levels? Alexa/JS
I want to see if a category is in a pack, and if it is, return that pack name.

So if my string was 'Pack1category1', I want to return 'pack1'.

How could I go about doing this?

```<code>{
    "paidTier": {
        "categoryPacks": {
            "pack1": {
                "categories": [
                    "Pack1category1",
                    "Pack1category2",
                    "Pack1category3",
                    "Pack1category4",
                    "Pack1category5",
                    "Pack1category6"
                ]
            },
            "pack2": {
                "categories": [
                    "Pack2category1",
                    "Pack2category2",
                    "Pack2category3",
                    "Pack2category4",
                    "Pack2category5",
                    "Pack2category6"
                ]
            }
        }
    }
}
</code>```

Something like this:

```<code>var string = 'Pack1category1'
//Loop through paidTier and find string
return 'pack1';
</code>```

or

```<code>var string = 'Pack2category5'
//Loop through paidTier and find string
return 'pack2';
</code>```

I've been at this for at least 10 hours and every method I've tried has failed. Please help! lol

答:
You can use Object.keys and filter and some

First get categoryPacks from original data

For each key's of categoryPacks we check for categories property if it includes keyToFind than we include it in final output else ignore it

let data = {"paidTier": {"categoryPacks": {"pack1": {"categories": ["Pack1category1","Pack1category2","Pack1category3","Pack1category4","Pack1category5","Pack1category6"]},"pack2": {"categories": ["Pack2category1","Pack2category2","Pack2category3","Pack2category4","Pack2category5","Pack2category6"]}}}}

let getKey = (keyToFind) => {
  let {categoryPacks} = data.paidTier
  let foundKeys = Object.keys(categoryPacks).filter(key => {
        return categoryPacks[key].categories.some(val => val === keyToFind)
  })
  return foundKeys
}

console.log(getKey('Pack1category1'))
console.log(getKey('Pack2category5'))
console.log(getKey('Pack2category22'))```

Body:
I want to see if a category is in a pack, and if it is, return that pack name.

So if my string was 'Pack1category1', I want to return 'pack1'.

How could I go about doing this?

{
    "paidTier": {
        "categoryPacks": {
            "pack1": {
                "categories": [
                    "Pack1category1",
                    "Pack1category2",
                    "Pack1category3",
                    "Pack1category4",
                    "Pack1category5",
                    "Pack1category6"
                ]
            },
            "pack2": {
                "categories": [
                    "Pack2category1",
                    "Pack2category2",
                    "Pack2category3",
                    "Pack2category4",
                    "Pack2category5",
                    "Pack2category6"
                ]
            }
        }
    }
}

Something like this:

var string = 'Pack1category1'
//Loop through paidTier and find string
return 'pack1';

or

var string = 'Pack2category5'
//Loop through paidTier and find string
return 'pack2';

I've been at this for at least 10 hours and every method I've tried has failed. Please help! lol


问:
Download a CSV file straight to the users download folder
Hi I want to have the option on my site for the user to download a CSV file. I have used the code below

```<code> <input type="button" value="Download as CSV file" window.location.href='call_log.csv'  " />
</code>```

This does work but when the button is clicked the file is opened in another tab on my browser, What I want to happen is a download straight to the users default download folder

I posted this question before and the response was to include headers ie

Content-Disposition: attachment; filename="call_log.csv"

The page is a php file and if I include headers the page does not load but trys to download the whole page .
Surely I cant put headers in the CSV file , can anyone help me please ?

Thanks

答:
Your server needs to bet set to execute your php script - you're right; there's no need to change that.

What you need to do is send the correct header to the server from your php script. Here's an example from php.net:

```<code><?php
// We'll be outputting a PDF
header('Content-type: application/pdf');

// It will be called downloaded.pdf
header('Content-Disposition: attachment; filename="downloaded.pdf"');

// The PDF source is in original.pdf
readfile('original.pdf');
?>
</code>```

For your csv file, the correct content type is text/csv

Body:
Hi I want to have the option on my site for the user to download a CSV file. I have used the code below

 <input type="button" value="Download as CSV file" window.location.href='call_log.csv'  " />

This does work but when the button is clicked the file is opened in another tab on my browser, What I want to happen is a download straight to the users default download folder

I posted this question before and the response was to include headers ie

Content-Disposition: attachment; filename="call_log.csv"

The page is a php file and if I include headers the page does not load but trys to download the whole page .
Surely I cant put headers in the CSV file , can anyone help me please ?

Thanks

Body:
Your server needs to bet set to execute your php script - you're right; there's no need to change that.

What you need to do is send the correct header to the server from your php script. Here's an example from php.net:

<?php
// We'll be outputting a PDF
header('Content-type: application/pdf');

// It will be called downloaded.pdf
header('Content-Disposition: attachment; filename="downloaded.pdf"');

// The PDF source is in original.pdf
readfile('original.pdf');
?>

For your csv file, the correct content type is text/csv


问:
how to handle sys.argv in pytest?
platform linux -- Python 3.6.7, pytest-4.4.0, py-1.8.0, pluggy-0.9.0

```<code>#example.py
try:
    import configparser
except ImportError:
    import ConfigParser as configparser

CONFIG = configparser.ConfigParser()
CONFIG.read(sys.argv[1])
ININFO = {i:dict(CONFIG.items(i)) for i in CONFIG.sections()}
DATANAME = ININFO['data']['name']

def somefunction(DATANAME):
    """
        This function will take lot of variables from ini file
    """
    print(DATANAME)
    s1 = "Pass"
    s2 = "Fail"
    s3 = "Pass"
    print(s1, s2, s3)
    return [s1, s2, s3]

def test_somefunction():
    """
        Test function
           - Will check whether all steps are passed or not.
    """
    status = somefunction()
    for sts in status:
        assert sts == 'Pass', "Test has Failed!"

if __name__ == "__main__":

    somefunction()

</code>```

Same like above code I have so many files and all have built-in tests

How I execute is

```<code>#sudo python3 example.py inifile.ini
</code>```

Please let me know How I can execute this with pytest and with out changing the code.

if i replace sys.argv[1] with filename this work fine as below

```<code>sudo python3 -m pytest -s
</code>```

Guide me how I can handle this.

I added and check below screenshot
error image

example ini file
test.ini

```<code>[data]
name = some.name
age = 22

[data1]
name = someother.name
age = 32
</code>```

答:
As I commented before you just have to create a python file to call pytest and arguments, from there pytest will be triggered.

```<code>$ python run.py example.py test.ini
</code>```

Here, run.py is as below

```<code>$ cat run.py
# run.py
import pytest
import sys

def main():
    # extract your arg here
    print('Extracted arg is ==> %s' % sys.argv[2])
    pytest.main([sys.argv[1]])

if __name__ == '__main__':
    main()
</code>```

example.py is your python script.

test.ini is your ini file.

Hoping this clarified your query.

All credits goes to this answer

Title: how to handle sys.argv in pytest?

Body:
platform linux -- Python 3.6.7, pytest-4.4.0, py-1.8.0, pluggy-0.9.0

#example.py
try:
    import configparser
except ImportError:
    import ConfigParser as configparser

CONFIG = configparser.ConfigParser()
CONFIG.read(sys.argv[1])
ININFO = {i:dict(CONFIG.items(i)) for i in CONFIG.sections()}
DATANAME = ININFO['data']['name']

def somefunction(DATANAME):
    """
        This function will take lot of variables from ini file
    """
    print(DATANAME)
    s1 = "Pass"
    s2 = "Fail"
    s3 = "Pass"
    print(s1, s2, s3)
    return [s1, s2, s3]

def test_somefunction():
    """
        Test function
           - Will check whether all steps are passed or not.
    """
    status = somefunction()
    for sts in status:
        assert sts == 'Pass', "Test has Failed!"

if __name__ == "__main__":

    somefunction()

Same like above code I have so many files and all have built-in tests

How I execute is

#sudo python3 example.py inifile.ini

Please let me know How I can execute this with pytest and with out changing the code.

if i replace sys.argv[1] with filename this work fine as below

sudo python3 -m pytest -s

Guide me how I can handle this.

I added and check below screenshot
error image

example ini file
test.ini

[data]
name = some.name
age = 22

[data1]
name = someother.name
age = 32

Body:
As I commented before you just have to create a python file to call pytest and arguments, from there pytest will be triggered.

$ python run.py example.py test.ini

Here, run.py is as below

$ cat run.py
# run.py
import pytest
import sys

def main():
    # extract your arg here
    print('Extracted arg is ==> %s' % sys.argv[2])
    pytest.main([sys.argv[1]])

if __name__ == '__main__':
    main()

example.py is your python script.

test.ini is your ini file.

Hoping this clarified your query.

All credits goes to this answer


问:
Problems making an awk between range of columns
I have a file called sds

```<code>$head sds
2557 386 fs://name/user/hive/ware/doc1/do_fact/date=20190313/fact=6
2593 393 fs://name/user/hive/ware/toc1/do_gas/idi_centr=6372/mes=20
2594 343 fs://name/user/hive/ware/dac2/do_gas2/idi_centr=6354/mes=21
349  307 fs://name/user/hive/ware/tec2/do_des/mes=25
340  332 fs://name/user/hive/ware/dc1/venta/year=2018/month=12
</code>```

I want delete /user/hive/ware and replace $7 ~ /_1$ for 1and other $7 for 2 using awk.

The code that I used was:

```<code>awk -F"/" '{ if ($7 ~ /_1$/)
print $1"//"$3"/1/"$7-$NF
else
print $1"//"$3"/2/"$7-$NF}' sds
</code>```

but the result is bad.

I would like and output like:

```<code>2557 386 fs://name/1/do_fact/date=20190313/fact=6
2593 393 fs://name/1/do_gas/idi_centr=6372/mes=20
2594 343 fs://name/2/do_gas2/idi_centr=6354/mes=21
349  307 fs://name/2/do_des/mes=25
340  332 fs://name/1/venta/year=2018/month=12
</code>```

答:
You can use awk and its gsub function to perform replacement on the selected columns.

```<code> awk 'BEGIN{FS=OFS="/"}{gsub("user/hive/ware/","");gsub(/^[^12]+/,"",$4)}1' inputfile
2557 386 fs://name/1/do_fact/date=20190313/fact=6
2593 393 fs://name/1/do_gas/idi_centr=6372/mes=20
2594 343 fs://name/2/do_gas2/idi_centr=6354/mes=21
349  307 fs://name/2/do_des/mes=25
340  332 fs://name/1/venta/year=2018/month=12
</code>```

Body:
I have a file called sds

$head sds
2557 386 fs://name/user/hive/ware/doc1/do_fact/date=20190313/fact=6
2593 393 fs://name/user/hive/ware/toc1/do_gas/idi_centr=6372/mes=20
2594 343 fs://name/user/hive/ware/dac2/do_gas2/idi_centr=6354/mes=21
349  307 fs://name/user/hive/ware/tec2/do_des/mes=25
340  332 fs://name/user/hive/ware/dc1/venta/year=2018/month=12

I want delete /user/hive/ware and replace $7 ~ /_1$ for 1and other $7 for 2 using awk.

The code that I used was:

awk -F"/" '{ if ($7 ~ /_1$/)
print $1"//"$3"/1/"$7-$NF
else
print $1"//"$3"/2/"$7-$NF}' sds

but the result is bad.

I would like and output like:

2557 386 fs://name/1/do_fact/date=20190313/fact=6
2593 393 fs://name/1/do_gas/idi_centr=6372/mes=20
2594 343 fs://name/2/do_gas2/idi_centr=6354/mes=21
349  307 fs://name/2/do_des/mes=25
340  332 fs://name/1/venta/year=2018/month=12

Body:
You can use awk and its gsub function to perform replacement on the selected columns.

 awk 'BEGIN{FS=OFS="/"}{gsub("user/hive/ware/","");gsub(/^[^12]+/,"",$4)}1' inputfile
2557 386 fs://name/1/do_fact/date=20190313/fact=6
2593 393 fs://name/1/do_gas/idi_centr=6372/mes=20
2594 343 fs://name/2/do_gas2/idi_centr=6354/mes=21
349  307 fs://name/2/do_des/mes=25
340  332 fs://name/1/venta/year=2018/month=12


问:
Get last price to see if profit or not. Print it in color
The Code is about the current price from the apple stock.
Now I want to show if they make profit or not.

Example:
current Price: 155.1

Price after that: 155.2

Now i want that it prints like that.

155.1 (First Price when program starts)

155.2 (Second Price) in green because profit to the previous price and if it drops like:

155.1 (Third Price) in red because there is no profit because previus value was 155.2

Hopefully you guys understood :D
My English is not that good

```<code>import bs4
import requests
from bs4 import BeautifulSoup

def parsePrice():
    r = requests.get('https://www.finanzen.net/realtimekurs/Apple')
    soup = BeautifulSoup(r.text,"lxml")
    price = soup.find_all('div',{'class':'price'})[0].find('span').text
    return price

while True:
    print("Price:"+str(parsePrice()))
</code>```

答:
You can achieve the colors by using the colorama lib. Also, I don't see where is your initial price, but nonetheless, switch your while statement for:

```<code>from colorama import init, Fore

init()

init_price = parsePrice()
while True():
    price = parsePrice()
    if (price == init_price):
        print(str(price))
    elif (price >= init_price):
        print(Fore.GREEN + str(price))
    else:
        print(Fore.RED + str(price))
</code>```

This way you will need to save your initial price and compare in each iteration of the while loop

Note that you will need to pip install colorama

EDIT:

If you need to compare always with the previous value, just update init_value by the end of the loop:

```<code>init_price = parsePrice()
while True():
    ...
    init_price = price
</code>```

Body:
The Code is about the current price from the apple stock.
Now I want to show if they make profit or not.

Example:
current Price: 155.1

Price after that: 155.2

Now i want that it prints like that.

155.1 (First Price when program starts)

155.2 (Second Price) in green because profit to the previous price and if it drops like:

155.1 (Third Price) in red because there is no profit because previus value was 155.2

Hopefully you guys understood :D
My English is not that good

import bs4
import requests
from bs4 import BeautifulSoup

def parsePrice():
    r = requests.get('https://www.finanzen.net/realtimekurs/Apple')
    soup = BeautifulSoup(r.text,"lxml")
    price = soup.find_all('div',{'class':'price'})[0].find('span').text
    return price

while True:
    print("Price:"+str(parsePrice()))

Body:
You can achieve the colors by using the colorama lib. Also, I don't see where is your initial price, but nonetheless, switch your while statement for:

from colorama import init, Fore

init()

init_price = parsePrice()
while True():
    price = parsePrice()
    if (price == init_price):
        print(str(price))
    elif (price >= init_price):
        print(Fore.GREEN + str(price))
    else:
        print(Fore.RED + str(price))

This way you will need to save your initial price and compare in each iteration of the while loop

Note that you will need to pip install colorama

EDIT:

If you need to compare always with the previous value, just update init_value by the end of the loop:

init_price = parsePrice()
while True():
    ...
    init_price = price


问:
What is wrong with my MainActivity.kt file?
I'm creating a Calculator Application.
Whenever a user changes the orientation of the device, the current app activity gets destroyed and recreated. So to fix that problem(i.e. get all the data back) I did this:

Declaring some variables

```<code>private const val STATE_OPERAND1 = "data"
private const val STATE_PENDING_OPERATION = "PENDING_OPERATION"
private const val STATE_OPERAND1_STORED = "data"
</code>```

Overriding the 'onSaveInstanceState' function

```<code>override fun onSaveInstanceState(outState: Bundle)
    super.onSaveInstanceState(outState)
    if (operand1 != null) {
        outState.putDouble(STATE_OPERAND1, operand1!!)
        outState.putBoolean(STATE_OPERAND1_STORED, true)
    }
    outState.putString(STATE_PENDING_OPERATION, pendingOperation)
}
</code>```

Overriding the 'onRestoreInstanceState' function

```<code>override fun onRestoreInstanceState(savedInstanceState: Bundle) {
    super.onRestoreInstanceState(savedInstanceState)
    operand1 = if (savedInstanceState.getBoolean(STATE_OPERAND1_STORED, false))
        savedInstanceState.getDouble(STATE_OPERAND1)
    else
        null
    result.setText(operand1.toString())    // Marked Line 1
    pendingOperation = savedInstanceState.getString(STATE_PENDING_OPERATION)
    displayOperation.text = pendingOperation
    }
</code>```

The 'Marked Line 1' in the 3rd code is not required, the reason I added is to find out the error. In this code the result test box clears it's previous text and has the text 'null' entered.

However, when I changed the declaration in 1
from private const val STATE_OPERAND1 = "data" to private const val STATE_OPERAND1 = "STATE_OPERAND1"

The result text box showed the text it was supposed to and everything worked properly. The application worked as long as all the three declaration in the 1st code were different. Why is this the case?

答:
With the initial declarations:

```<code>private const val STATE_OPERAND1 = "data"
private const val STATE_OPERAND1_STORED = "data"
</code>```

this line:

```<code>outState.putDouble(STATE_OPERAND1, operand1!!)
</code>```

sets inside the Bundle object the Double value operand1!! by the key "data".

The next line:

```<code>outState.putBoolean(STATE_OPERAND1_STORED, true)
</code>```

sets again (overwrites) inside the Bundle object the Boolean value true by the key "data".

The result is that the previous Double value is now lost and the only value that exists is the new Boolean value.

So what you have is only one Boolean value.

When you changed to:

```<code>private const val STATE_OPERAND1 = "STATE_OPERAND1"
private const val STATE_OPERAND1_STORED = "data"
</code>```

this conflict vanished, because you had 2 different keys and the 2 values were saved properly without overwriting each other.

Body:
I'm creating a Calculator Application.
Whenever a user changes the orientation of the device, the current app activity gets destroyed and recreated. So to fix that problem(i.e. get all the data back) I did this:

Declaring some variables

private const val STATE_OPERAND1 = "data"
private const val STATE_PENDING_OPERATION = "PENDING_OPERATION"
private const val STATE_OPERAND1_STORED = "data"

Overriding the 'onSaveInstanceState' function

override fun onSaveInstanceState(outState: Bundle)
    super.onSaveInstanceState(outState)
    if (operand1 != null) {
        outState.putDouble(STATE_OPERAND1, operand1!!)
        outState.putBoolean(STATE_OPERAND1_STORED, true)
    }
    outState.putString(STATE_PENDING_OPERATION, pendingOperation)
}

Overriding the 'onRestoreInstanceState' function

override fun onRestoreInstanceState(savedInstanceState: Bundle) {
    super.onRestoreInstanceState(savedInstanceState)
    operand1 = if (savedInstanceState.getBoolean(STATE_OPERAND1_STORED, false))
        savedInstanceState.getDouble(STATE_OPERAND1)
    else
        null
    result.setText(operand1.toString())    // Marked Line 1
    pendingOperation = savedInstanceState.getString(STATE_PENDING_OPERATION)
    displayOperation.text = pendingOperation
    }

The 'Marked Line 1' in the 3rd code is not required, the reason I added is to find out the error. In this code the result test box clears it's previous text and has the text 'null' entered.

However, when I changed the declaration in 1
from private const val STATE_OPERAND1 = "data" to private const val STATE_OPERAND1 = "STATE_OPERAND1"

The result text box showed the text it was supposed to and everything worked properly. The application worked as long as all the three declaration in the 1st code were different. Why is this the case?

Body:
With the initial declarations:

private const val STATE_OPERAND1 = "data"
private const val STATE_OPERAND1_STORED = "data"

this line:

outState.putDouble(STATE_OPERAND1, operand1!!)

sets inside the Bundle object the Double value operand1!! by the key "data".

The next line:

outState.putBoolean(STATE_OPERAND1_STORED, true)

sets again (overwrites) inside the Bundle object the Boolean value true by the key "data".

The result is that the previous Double value is now lost and the only value that exists is the new Boolean value.

So what you have is only one Boolean value.

When you changed to:

private const val STATE_OPERAND1 = "STATE_OPERAND1"
private const val STATE_OPERAND1_STORED = "data"

this conflict vanished, because you had 2 different keys and the 2 values were saved properly without overwriting each other.


问:
How can I sort variable number of columns with Linq C#?
The below code works for sorting two columns (by surname then first name), however I need to sort by a variable number of names (2-5 per entry). Adding another ThenBy split at whitespace causes an out of bounds exception. I understand why, but I was wondering if there is any way around this to get the code to work with Linq or if I need to go some other route. Apologies if this is simple, I'm completely new to C#. I have searched for an answer for a while and cannot find it.

The code below outputs to console:

```<code>Jimbo Crab
Jonathan Crab
Michael Crab
Steve Cruthers
Barry John
David Johnson
</code>```

Correctly ordered first by surname then by given name.

However the names I need to sort are of varying lengths, i.e:

Barry John

Daniel Johnson James

Steve Davidson Andrew Colins

Lorna Michael

Which should produce:

```<code>Steve Davidson Andrew Colins
Daniel Johnson James
Barry John
Lorna Michael
</code>```

These need to be sorted in reverse order, so by surname, then given names and finally forename.

Thanks in advance!

```<code>var listStr = new[] {
    "Barry John", "Steve Cruthers", "Michael Crab", "David Johnson", "Jonathan Crab", "Jimbo Crab"};

     var sorted = listStr
     .OrderBy(s => s.Split(' ')[1])
     .ThenBy(s => s.Split(' ')[0]);

     foreach (var s in sorted)
     {
         Console.WriteLine(s);
     }
}
</code>```

答:
It is easier and more efficient to split each string once, and then sort using the arrays. Finally you may join the arrays back to strings if you want.</p>

```<code>var sorted = listStr
    .Select(s => s.Split(' ')) // project string to an array
    .OrderBy(a => a[a.Length - 1]) // order by last element
    .ThenBy(a => a.Length > 2 ? a[1] : a[0]) // then order by middle element
    .ThenBy(a => a[0]) // then order by first element
    .Select(a => String.Join(" ", a)); // project back to a string
</code>```

Body:
The below code works for sorting two columns (by surname then first name), however I need to sort by a variable number of names (2-5 per entry). Adding another ThenBy split at whitespace causes an out of bounds exception. I understand why, but I was wondering if there is any way around this to get the code to work with Linq or if I need to go some other route. Apologies if this is simple, I'm completely new to C#. I have searched for an answer for a while and cannot find it.

The code below outputs to console:

Jimbo Crab
Jonathan Crab
Michael Crab
Steve Cruthers
Barry John
David Johnson

Correctly ordered first by surname then by given name.

However the names I need to sort are of varying lengths, i.e:

Barry John

Daniel Johnson James

Steve Davidson Andrew Colins

Lorna Michael

Which should produce:

Steve Davidson Andrew Colins
Daniel Johnson James
Barry John
Lorna Michael

These need to be sorted in reverse order, so by surname, then given names and finally forename.

Thanks in advance!

var listStr = new[] {
    "Barry John", "Steve Cruthers", "Michael Crab", "David Johnson", "Jonathan Crab", "Jimbo Crab"};

     var sorted = listStr
     .OrderBy(s => s.Split(' ')[1])
     .ThenBy(s => s.Split(' ')[0]);

     foreach (var s in sorted)
     {
         Console.WriteLine(s);
     }
}

Body:
It is easier and more efficient to split each string once, and then sort using the arrays. Finally you may join the arrays back to strings if you want.

var sorted = listStr
    .Select(s => s.Split(' ')) // project string to an array
    .OrderBy(a => a[a.Length - 1]) // order by last element
    .ThenBy(a => a.Length > 2 ? a[1] : a[0]) // then order by middle element
    .ThenBy(a => a[0]) // then order by first element
    .Select(a => String.Join(" ", a)); // project back to a string


问:
Mapping values to different values in list
The problem is to map a particular list in order to accumulate the time. A single change in digit accounts for 1 ms . However the clock resets after number 255.

```<code>list_val = [ 253 ,1,15,27,45,63,120,140,195,210,225,243,2,5,1]
</code>```

The output should be like

```<code>new_list = [ 1 ,3,17,29,47,65,122,142,197,212,227,245,257,260,510].
</code>```

Here is what I have tried

```<code>new_list = []
for i in range(len(list_val)):
      if i == 0:
          new_list.append(1)
      elif list_val[i-1] < list_val[i] :
          new_list[i] =new_list.append(list_val[i] - list_val[i-1] + new_list[i-1])
      elif list_val[i-1] > list_val[i] :
          new_list[i] = new_list.append(255 - list_val[i-1] + new_list[i-1])
      else: #list_val[i-1] == list_val[i]:
          new_list[i] = new_list.append(255 + list_val[i-1] + new_list[i-1])
</code>```

The following is the error
unsupported operand type(s) for +: 'int' and 'NoneType'

答:
What about this:

```<code>import numpy as np
list_val = [ 253 ,1,15,27,45,63,120,140,195,210,225,243,2,5,1]
new_list = np.cumsum(np.remainder(np.diff(list_val), 256))
</code>```

Basically what happens is:

first compute the differences list_val[i] - list_val[i-1] via the numpy diff function

transform the differences into values between 0 and 255 by computing the remainder of each difference by division with 256 (in mathematical terms the modulo term)

apply cumulative sum on the remainders

PS: I know the result is not exactly as what you gave as the expected output, but I struggle a bit to understand why the first 1 ms is statically always set in.

Body:
The problem is to map a particular list in order to accumulate the time. A single change in digit accounts for 1 ms . However the clock resets after number 255.

list_val = [ 253 ,1,15,27,45,63,120,140,195,210,225,243,2,5,1]

The output should be like

new_list = [ 1 ,3,17,29,47,65,122,142,197,212,227,245,257,260,510].

Here is what I have tried

new_list = []
for i in range(len(list_val)):
      if i == 0:
          new_list.append(1)
      elif list_val[i-1] < list_val[i] :
          new_list[i] =new_list.append(list_val[i] - list_val[i-1] + new_list[i-1])
      elif list_val[i-1] > list_val[i] :
          new_list[i] = new_list.append(255 - list_val[i-1] + new_list[i-1])
      else: #list_val[i-1] == list_val[i]:
          new_list[i] = new_list.append(255 + list_val[i-1] + new_list[i-1])

The following is the error
unsupported operand type(s) for +: 'int' and 'NoneType'

Body:
What about this:

import numpy as np
list_val = [ 253 ,1,15,27,45,63,120,140,195,210,225,243,2,5,1]
new_list = np.cumsum(np.remainder(np.diff(list_val), 256))

Basically what happens is:

first compute the differences list_val[i] - list_val[i-1] via the numpy diff function

transform the differences into values between 0 and 255 by computing the remainder of each difference by division with 256 (in mathematical terms the modulo term)

apply cumulative sum on the remainders

PS: I know the result is not exactly as what you gave as the expected output, but I struggle a bit to understand why the first 1 ms is statically always set in.


问:
Google Analytics Web
Recently i found out there is someone sharing that the had get a news and email from google and its about "Google are going to sunset the Google Analytics Mobile Apps"
We believe slowly it will replace by Firebase Analytics.

However, would like to know is it the google analytics Web will be affected as well?
Currently we are using Google Analytics Web for traffic track on the company website.
is it compulsory for us to migrate our website tracking from Google Analytics to Firebase Analytics?

Appreciate if anyone could advice and share some idea on these issue.

Thank you!

答: You do not need to do anything, the sunset only affects GA for apps.</p>

Title: Google Analytics Web


问:
c# Thread in 100% CPU
I have a complex system with several threads. sometimes i see the application in 100% cpu and force to restart the system. I have no idea which thread caused it and which code caused it.
I need something that will give me the state of each thread in the system (i.e. in which line the thread is now) so i can find which code causes the 100% CPU

(in java you have the thread dump kill -3 which gives you the state of each thread)

Can you help please?

答:
Tess's blog has some great debugging tutorials, including:
.NET Hang Debugging Walkthrough</p>

Title: c# Thread in 100% CPU


问:
Strings in 2D lists in Python
This is a normal 2D list in python containing what supposed to be white spaces:

```<code>shape = [
["", "", ""],
["", "", ""],
["", "", ""]]
</code>```

but when printing this array using for loop that's what happens:

```<code>['', '', '']
['', '', '']
['', '', '']
</code>```

isn't it supposed to show only white space ? How do I remove these single quot marks but leave the commas ?

答:
You can loop through your lists and replace the quotations with empty spaces

```<code>for x in shape:
print(str(x).replace("'", ""))
</code>```

Which outputs:

```<code>[, , ]
[, , ]
[, , ]
</code>```

Title: Strings in 2D lists in Python

Body:
This is a normal 2D list in python containing what supposed to be white spaces:

shape = [
["", "", ""],
["", "", ""],
["", "", ""]]

but when printing this array using for loop that's what happens:

['', '', '']
['', '', '']
['', '', '']

isn't it supposed to show only white space ? How do I remove these single quot marks but leave the commas ?

Body:
You can loop through your lists and replace the quotations with empty spaces

for x in shape:
print(str(x).replace("'", ""))

Which outputs:

[, , ]
[, , ]
[, , ]


问:
How to parse symbol ":" in Json String
I want to parse json string into JSONObject but the symbol ":" seems to parse the error

For example -> "time": "2019-05-28T16:30:29Z" will be wrong

But changed to "time": "20190526" is OK

This is the entire json object:

```<code>{
    "channel": 922875000,
    "sf": 12,
    "time": "2019-05-28T16:30:29Z",
    "gwip": "192.168.0.180",
    "gwid": "00001c497b431ff5",
    "repeater": "00000000ffffffff",
    "systype": 170,
    "rssi": -103,
    "snr": 20.5,
    "snr_max": 33,
    "snr_min": 18,
    "macAddr": "00000000aabb60ba",
    "data": "00000000",
    "frameCnt": 8,
    "fport": 3
}
</code>```

and the parse code:

```<code>    try {
        JSONObject sensorObject = new JSONObject(message.toString());
        SensorModel sensorModel = new Gson().fromJson(sensorObject.toString(), SensorModel.class);
    } catch (JSONException e) {
        logger.error(e.getMessage());
    }
</code>```

How can I let him keep the same "2019:05:26" content?

SensorModel:

```<code>@Entity
public class SensorModel {

@Id
@GeneratedValue(strategy = GenerationType.AUTO)
private long id;

@NotNull
private long channel;

@NotNull
private int sf;

@NotNull
private String time;

@NotNull
private String gwip;

@NotNull
private String gwid;

private String repeater;

private int systype;

private double rssi;

private double snr;

private double snr_max;

private double snr_min;

private String macAddr;

private String data;

private int frameCnt;

private int fport;

public void setId(long id) {
    this.id = id;
}

public void setChannel(long channel) {
    this.channel = channel;
}

public void setSf(int sf) {
    this.sf = sf;
}

public void setTime(String time) {
    this.time = time;
}

public void setGwip(String gwip) {
    this.gwip = gwip;
}

public void setGwid(String gwid) {
    this.gwid = gwid;
}

public void setRepeater(String repeater) {
    this.repeater = repeater;
}

public void setSystype(int systype) {
    this.systype = systype;
}

public void setRssi(double rssi) {
    this.rssi = rssi;
}

public void setSnr(double snr) {
    this.snr = snr;
}

public void setSnr_max(double snr_max) {
    this.snr_max = snr_max;
}

public void setSnr_min(double snr_min) {
    this.snr_min = snr_min;
}

public void setMacAddr(String macAddr) {
    this.macAddr = macAddr;
}

public void setData(String data) {
    this.data = data;
}

public void setFrameCnt(int frameCnt) {
    this.frameCnt = frameCnt;
}

public void setFport(int fport) {
    this.fport = fport;
}

public long getId() {
    return id;
}

public long getChannel() {
    return channel;
}

public int getSf() {
    return sf;
}

public String getTime() {
    return time;
}

public String getGwip() {
    return gwip;
}

public String getGwid() {
    return gwid;
}

public String getRepeater() {
    return repeater;
}

public int getSystype() {
    return systype;
}

public double getRssi() {
    return rssi;
}

public double getSnr() {
    return snr;
}

public double getSnr_max() {
    return snr_max;
}

public double getSnr_min() {
    return snr_min;
}

public String getMacAddr() {
    return macAddr;
}

public String getData() {
    return data;
}

public int getFrameCnt() {
    return frameCnt;
}

public int getFport() {
    return fport;
}
}
</code>```

答:
use ObjectMapper as follows:

```<code>import com.fasterxml.jackson.databind.ObjectMapper;
import java.util.Date;

public class JSONObject {
    private int channel;
    private int sf;
    private Date time;
    private String gwip;
    private String gwid;
    private String repeater;
    private int systype;
    private int rssi;
    private double snr;
    private double snr_min;
    private double snr_max;
    private String macAddr;
    private String data;
    private int frameCnt;
    private int fport;

    public int getChannel() {
        return channel;
    }

    public void setChannel(int channel) {
        this.channel = channel;
    }

    public int getSf() {
        return sf;
    }

    public void setSf(int sf) {
        this.sf = sf;
    }

    public Date getTime() {
        return time;
    }

    public void setTime(Date time) {
        this.time = time;
    }

    public String getGwip() {
        return gwip;
    }

    public void setGwip(String gwip) {
        this.gwip = gwip;
    }

    public String getGwid() {
        return gwid;
    }

    public void setGwid(String gwid) {
        this.gwid = gwid;
    }

    public String getRepeater() {
        return repeater;
    }

    public void setRepeater(String repeater) {
        this.repeater = repeater;
    }

    public int getSystype() {
        return systype;
    }

    public void setSystype(int systype) {
        this.systype = systype;
    }

    public int getRssi() {
        return rssi;
    }

    public void setRssi(int rssi) {
        this.rssi = rssi;
    }

    public double getSnr() {
        return snr;
    }

    public void setSnr(double snr) {
        this.snr = snr;
    }

    public double getSnr_min() {
        return snr_min;
    }

    public void setSnr_min(double snr_min) {
        this.snr_min = snr_min;
    }

    public double getSnr_max() {
        return snr_max;
    }

    public void setSnr_max(double snr_max) {
        this.snr_max = snr_max;
    }

    public String getMacAddr() {
        return macAddr;
    }

    public void setMacAddr(String macAddr) {
        this.macAddr = macAddr;
    }

    public String getData() {
        return data;
    }

    public void setData(String data) {
        this.data = data;
    }

    public int getFrameCnt() {
        return frameCnt;
    }

    public void setFrameCnt(int frameCnt) {
        this.frameCnt = frameCnt;
    }

    public int getFport() {
        return fport;
    }

    public void setFport(int fport) {
        this.fport = fport;
    }

    @Override
    public String toString() {
        return "JSONObject{" + "channel=" + channel + ", sf=" + sf + ", time=" + time + ", gwip=" + gwip + ", gwid=" + gwid + ", repeater=" + repeater + ", systype=" + systype + ", rssi=" + rssi + ", snr=" + snr + ", snr_min=" + snr_min + ", snr_max=" + snr_max + ", macAddr=" + macAddr + ", data=" + data + ", frameCnt=" + frameCnt + ", fport=" + fport + '}';
    }

    public static void main(String[] args) throws Exception {
        String json = "{\"channel\":922875000,\"sf\":12,\"time\":\"2019-05-28T16:30:29Z\",\"gwip\":\"192.168.0.180\",\"gwid\":\"00001c497b431ff5\",\"repeater\":\"00000000ffffffff\",\"systype\":170,\"rssi\":-103,\"snr\":20.5,\"snr_max\":33,\"snr_min\":18,\"macAddr\":\"00000000aabb60ba\",\"data\":\"00000000\",\"frameCnt\":8,\"fport\":3}";
        ObjectMapper objectMapper = new ObjectMapper();
        JSONObject obj = objectMapper.readValue(json, JSONObject.class);
        System.out.println(obj.toString());
    }
}
</code>```

Title: How to parse symbol ":" in Json String

Body:
I want to parse json string into JSONObject but the symbol ":" seems to parse the error

For example -> "time": "2019-05-28T16:30:29Z" will be wrong

But changed to "time": "20190526" is OK

This is the entire json object:

{
    "channel": 922875000,
    "sf": 12,
    "time": "2019-05-28T16:30:29Z",
    "gwip": "192.168.0.180",
    "gwid": "00001c497b431ff5",
    "repeater": "00000000ffffffff",
    "systype": 170,
    "rssi": -103,
    "snr": 20.5,
    "snr_max": 33,
    "snr_min": 18,
    "macAddr": "00000000aabb60ba",
    "data": "00000000",
    "frameCnt": 8,
    "fport": 3
}

and the parse code:

    try {
        JSONObject sensorObject = new JSONObject(message.toString());
        SensorModel sensorModel = new Gson().fromJson(sensorObject.toString(), SensorModel.class);
    } catch (JSONException e) {
        logger.error(e.getMessage());
    }

How can I let him keep the same "2019:05:26" content?

SensorModel:

@Entity
public class SensorModel {

@Id
@GeneratedValue(strategy = GenerationType.AUTO)
private long id;

@NotNull
private long channel;

@NotNull
private int sf;

@NotNull
private String time;

@NotNull
private String gwip;

@NotNull
private String gwid;

private String repeater;

private int systype;

private double rssi;

private double snr;

private double snr_max;

private double snr_min;

private String macAddr;

private String data;

private int frameCnt;

private int fport;

public void setId(long id) {
    this.id = id;
}

public void setChannel(long channel) {
    this.channel = channel;
}

public void setSf(int sf) {
    this.sf = sf;
}

public void setTime(String time) {
    this.time = time;
}

public void setGwip(String gwip) {
    this.gwip = gwip;
}

public void setGwid(String gwid) {
    this.gwid = gwid;
}

public void setRepeater(String repeater) {
    this.repeater = repeater;
}

public void setSystype(int systype) {
    this.systype = systype;
}

public void setRssi(double rssi) {
    this.rssi = rssi;
}

public void setSnr(double snr) {
    this.snr = snr;
}

public void setSnr_max(double snr_max) {
    this.snr_max = snr_max;
}

public void setSnr_min(double snr_min) {
    this.snr_min = snr_min;
}

public void setMacAddr(String macAddr) {
    this.macAddr = macAddr;
}

public void setData(String data) {
    this.data = data;
}

public void setFrameCnt(int frameCnt) {
    this.frameCnt = frameCnt;
}

public void setFport(int fport) {
    this.fport = fport;
}

public long getId() {
    return id;
}

public long getChannel() {
    return channel;
}

public int getSf() {
    return sf;
}

public String getTime() {
    return time;
}

public String getGwip() {
    return gwip;
}

public String getGwid() {
    return gwid;
}

public String getRepeater() {
    return repeater;
}

public int getSystype() {
    return systype;
}

public double getRssi() {
    return rssi;
}

public double getSnr() {
    return snr;
}

public double getSnr_max() {
    return snr_max;
}

public double getSnr_min() {
    return snr_min;
}

public String getMacAddr() {
    return macAddr;
}

public String getData() {
    return data;
}

public int getFrameCnt() {
    return frameCnt;
}

public int getFport() {
    return fport;
}
}

Body:
use ObjectMapper as follows:

import com.fasterxml.jackson.databind.ObjectMapper;
import java.util.Date;

public class JSONObject {
    private int channel;
    private int sf;
    private Date time;
    private String gwip;
    private String gwid;
    private String repeater;
    private int systype;
    private int rssi;
    private double snr;
    private double snr_min;
    private double snr_max;
    private String macAddr;
    private String data;
    private int frameCnt;
    private int fport;

    public int getChannel() {
        return channel;
    }

    public void setChannel(int channel) {
        this.channel = channel;
    }

    public int getSf() {
        return sf;
    }

    public void setSf(int sf) {
        this.sf = sf;
    }

    public Date getTime() {
        return time;
    }

    public void setTime(Date time) {
        this.time = time;
    }

    public String getGwip() {
        return gwip;
    }

    public void setGwip(String gwip) {
        this.gwip = gwip;
    }

    public String getGwid() {
        return gwid;
    }

    public void setGwid(String gwid) {
        this.gwid = gwid;
    }

    public String getRepeater() {
        return repeater;
    }

    public void setRepeater(String repeater) {
        this.repeater = repeater;
    }

    public int getSystype() {
        return systype;
    }

    public void setSystype(int systype) {
        this.systype = systype;
    }

    public int getRssi() {
        return rssi;
    }

    public void setRssi(int rssi) {
        this.rssi = rssi;
    }

    public double getSnr() {
        return snr;
    }

    public void setSnr(double snr) {
        this.snr = snr;
    }

    public double getSnr_min() {
        return snr_min;
    }

    public void setSnr_min(double snr_min) {
        this.snr_min = snr_min;
    }

    public double getSnr_max() {
        return snr_max;
    }

    public void setSnr_max(double snr_max) {
        this.snr_max = snr_max;
    }

    public String getMacAddr() {
        return macAddr;
    }

    public void setMacAddr(String macAddr) {
        this.macAddr = macAddr;
    }

    public String getData() {
        return data;
    }

    public void setData(String data) {
        this.data = data;
    }

    public int getFrameCnt() {
        return frameCnt;
    }

    public void setFrameCnt(int frameCnt) {
        this.frameCnt = frameCnt;
    }

    public int getFport() {
        return fport;
    }

    public void setFport(int fport) {
        this.fport = fport;
    }

    @Override
    public String toString() {
        return "JSONObject{" + "channel=" + channel + ", sf=" + sf + ", time=" + time + ", gwip=" + gwip + ", gwid=" + gwid + ", repeater=" + repeater + ", systype=" + systype + ", rssi=" + rssi + ", snr=" + snr + ", snr_min=" + snr_min + ", snr_max=" + snr_max + ", macAddr=" + macAddr + ", data=" + data + ", frameCnt=" + frameCnt + ", fport=" + fport + '}';
    }

    public static void main(String[] args) throws Exception {
        String json = "{\"channel\":922875000,\"sf\":12,\"time\":\"2019-05-28T16:30:29Z\",\"gwip\":\"192.168.0.180\",\"gwid\":\"00001c497b431ff5\",\"repeater\":\"00000000ffffffff\",\"systype\":170,\"rssi\":-103,\"snr\":20.5,\"snr_max\":33,\"snr_min\":18,\"macAddr\":\"00000000aabb60ba\",\"data\":\"00000000\",\"frameCnt\":8,\"fport\":3}";
        ObjectMapper objectMapper = new ObjectMapper();
        JSONObject obj = objectMapper.readValue(json, JSONObject.class);
        System.out.println(obj.toString());
    }
}


问:
Javascript don't substitute html in rails + Ajax
Still learning how to use Ajax in Rails.
I have a simple controller:

```<code>class PagineController < ApplicationController

  def cerca
  end

  def trova
    respond_to do |format|
      format.js {render layout: false }
    end
  end

end
</code>```

routes.rb:

```<code>  get '/cerca', to: 'pagine#cerca'
  post '/cerca', to: 'pagine#trova'
</code>```

This is trova.js.erb:

```<code>$('#search_table').html("<%= escape_javascript(render partial: 'search_result') %>");
</code>```

This is cerca.html.erb:

```<code><%= form_tag '/cerca', remote: true do %>
    <%= text_field_tag :name, params[:name], placeholder: 'Inserisci parte
        del nome del gioco' %>
    <%= submit_tag 'Cerca' %>
<% end %>

<h1> Results </h1>

<div id="search_table">
  <p>Here the partial</p>
</div>
</code>```

and this is the _search_result.html.erb

```<code>  <p> I'm running well </p>
</code>```

I'm expecting that, when i submit a search with the button, "Here the partial" will be substituted with "I'm running well".
But this is not happens.
In the log i see that _search_result.html.erb is correctly rendered, so all should run.

Why don't?

答:
Ok. I've resolved (for future references if someone needs), using different js:</p>

```<code>document.getElementById("search_table").innerHTML = "<%= j render 'search_result' %>"
</code>```

Body:
Still learning how to use Ajax in Rails.
I have a simple controller:

class PagineController < ApplicationController

  def cerca
  end

  def trova
    respond_to do |format|
      format.js {render layout: false }
    end
  end

end

routes.rb:

  get '/cerca', to: 'pagine#cerca'
  post '/cerca', to: 'pagine#trova'

This is trova.js.erb:

$('#search_table').html("<%= escape_javascript(render partial: 'search_result') %>");

This is cerca.html.erb:

<%= form_tag '/cerca', remote: true do %>
    <%= text_field_tag :name, params[:name], placeholder: 'Inserisci parte
        del nome del gioco' %>
    <%= submit_tag 'Cerca' %>
<% end %>

 Results

Here the partial

and this is the _search_result.html.erb

 I'm running well

I'm expecting that, when i submit a search with the button, "Here the partial" will be substituted with "I'm running well".
But this is not happens.
In the log i see that _search_result.html.erb is correctly rendered, so all should run.

Why don't?

Body:
Ok. I've resolved (for future references if someone needs), using different js:

document.getElementById("search_table").innerHTML = "<%= j render 'search_result' %>"


问:
LinearNDInterpolatorExtrapolate returns error with trivial example
I'm trying to use scipy's LinearNDInterpolatorExtrapolate.

The following minimal code should be as trivial as possible, yet it returns an error

```<code>from scipy.interpolate import NearestNDInterpolator
points = [[0,0,0], [1,0,0], [1,1,0],[0,1,0],[.5,.5,1]]
values = [1,2,3,4,5]
interpolator = NearestNDInterpolator(points,values)
interpolator([.5,.5,.8])
</code>```

returns

```<code>TypeError: only integer scalar arrays can be converted to a scalar index
</code>```

The error seems to come from line 81 of scipy.interpolate.ndgriddata [source]. Unfortunately I could not chase the error further, as I don't understand what tree.query is returning.

Is this a bug or I'm doing something wrong?

答:
Pass your input as arrays

```<code>interpolator = NearestNDInterpolator(np.array(points),np.array(
values))
</code>```

You can even pass many points:

```<code>interpolator([np.array([.5,.5,.8]),np.array([1,1,2])])

>>>> array([5,5])
</code>```

Body:
I'm trying to use scipy's LinearNDInterpolatorExtrapolate.

The following minimal code should be as trivial as possible, yet it returns an error

from scipy.interpolate import NearestNDInterpolator
points = [[0,0,0], [1,0,0], [1,1,0],[0,1,0],[.5,.5,1]]
values = [1,2,3,4,5]
interpolator = NearestNDInterpolator(points,values)
interpolator([.5,.5,.8])

returns

TypeError: only integer scalar arrays can be converted to a scalar index

The error seems to come from line 81 of scipy.interpolate.ndgriddata [source]. Unfortunately I could not chase the error further, as I don't understand what tree.query is returning.

Is this a bug or I'm doing something wrong?

Body:
Pass your input as arrays

interpolator = NearestNDInterpolator(np.array(points),np.array(
values))

You can even pass many points:

interpolator([np.array([.5,.5,.8]),np.array([1,1,2])])

>>>> array([5,5])


问:
Why does the char need to be dereferenced in this instance?
I've been doing some practice with trees in C for my undergraduate courses and I came about on very strange results.

This is the code that didn't output as expected. I have a tree with the root being the struct node * root, and the preorder function prints the data on each node on the tree.

```<code>struct node{
    char data;
    struct node * left;
    struct node * right;
};

struct node* newNode(char data){
    struct node* node = malloc(sizeof(struct node));
    node->data = data;
    node->left = NULL;
    node->right = NULL;
    return(node);
}

void preorder(struct node * root){
    //struct node * start = root;
    struct node * L;
    struct node * R;
    if(root!=NULL){
        printf("%c",root->data);
        preorder(root->left);
        preorder(root->right);
    }
}

int main(){
    struct node * root = newNode("a");
    root->left = newNode("b");
    root->right = newNode("c");
    root->left->left = newNode("d");
    root->left->right = newNode("e");
    root->right->left = newNode("f");
    root->right->right = newNode("g");
    preorder(root);
    return 0;
}
</code>```

I was expecting the output to be "abdecfg", but instead the terminal is outputting a weird result, as such; https://i.imgur.com/LudpUn7.png .
I get the GCC warning "[Warning] assignment makes integer from pointer without a cast", but I don't understand why.
If I use the dereference asterisk on the char inputs, the error stops, and I get the expected output, like this;

```<code>int main(){
    struct node * root = newNode(*"a");
    root->left = newNode(*"b");
    root->right = newNode(*"c");
    root->left->left = newNode(*"d");
    root->left->right = newNode(*"e");
    root->right->left = newNode(*"f");
    root->right->right = newNode(*"g");
    preorder(root);
    return 0;
}
</code>```

Please note that it does not work[1] if I put the dereference asterisk on the newNode input instead.

Thanks in advance for any help.

答: double quotes (") in C denote strings, which become char * (pointers).  You want single quotes (') to get char constants.

Body:
I've been doing some practice with trees in C for my undergraduate courses and I came about on very strange results.

This is the code that didn't output as expected. I have a tree with the root being the struct node * root, and the preorder function prints the data on each node on the tree.

struct node{
    char data;
    struct node * left;
    struct node * right;
};

struct node* newNode(char data){
    struct node* node = malloc(sizeof(struct node));
    node->data = data;
    node->left = NULL;
    node->right = NULL;
    return(node);
}

void preorder(struct node * root){
    //struct node * start = root;
    struct node * L;
    struct node * R;
    if(root!=NULL){
        printf("%c",root->data);
        preorder(root->left);
        preorder(root->right);
    }
}

int main(){
    struct node * root = newNode("a");
    root->left = newNode("b");
    root->right = newNode("c");
    root->left->left = newNode("d");
    root->left->right = newNode("e");
    root->right->left = newNode("f");
    root->right->right = newNode("g");
    preorder(root);
    return 0;
}

I was expecting the output to be "abdecfg", but instead the terminal is outputting a weird result, as such; https://i.imgur.com/LudpUn7.png .
I get the GCC warning "[Warning] assignment makes integer from pointer without a cast", but I don't understand why.
If I use the dereference asterisk on the char inputs, the error stops, and I get the expected output, like this;

int main(){
    struct node * root = newNode(*"a");
    root->left = newNode(*"b");
    root->right = newNode(*"c");
    root->left->left = newNode(*"d");
    root->left->right = newNode(*"e");
    root->right->left = newNode(*"f");
    root->right->right = newNode(*"g");
    preorder(root);
    return 0;
}

Please note that it does not work[1] if I put the dereference asterisk on the newNode input instead.

Thanks in advance for any help.


问:
CanCan and controllers without models
I'm using CanCan for authorization.  I define the model-action-user rules in /app/config/ability.rb and it's working fine.  I've added the line load_and_authorize_resource to my application_controller, and everything's done.

However, I also have numerous views and controllers that don't have a model underneath.  For example, trying to load a statistics page gives

```<code>NameError (uninitialized constant Statistic):
  activesupport (3.2.3) lib/active_support/inflector/methods.rb:229:in `block in constantize'
  activesupport (3.2.3) lib/active_support/inflector/methods.rb:228:in `each'
  activesupport (3.2.3) lib/active_support/inflector/methods.rb:228:in `constantize'
  ...
</code>```

Is there some way for CanCan to work with the controller+action instead of model+action?

答:
You can especify the controller within the ability.rb file:

ability.rb:

```<code>can :read, StatisticsController # ability.rb
</code>```

StatisticsController:

```<code>class StatisticsController < ApplicationController

  def read
    authorize! :read, current_user
  end
end
</code>```

Title: CanCan and controllers without models

Body:
I'm using CanCan for authorization.  I define the model-action-user rules in /app/config/ability.rb and it's working fine.  I've added the line load_and_authorize_resource to my application_controller, and everything's done.

However, I also have numerous views and controllers that don't have a model underneath.  For example, trying to load a statistics page gives

NameError (uninitialized constant Statistic):
  activesupport (3.2.3) lib/active_support/inflector/methods.rb:229:in `block in constantize'
  activesupport (3.2.3) lib/active_support/inflector/methods.rb:228:in `each'
  activesupport (3.2.3) lib/active_support/inflector/methods.rb:228:in `constantize'
  ...

Is there some way for CanCan to work with the controller+action instead of model+action?

Body:
You can especify the controller within the ability.rb file:

ability.rb:

can :read, StatisticsController # ability.rb

StatisticsController:

class StatisticsController < ApplicationController

  def read
    authorize! :read, current_user
  end
end