问:
JSP Search Function Using Mysql not working
I want to create search option on my project. And it is working when I am searching my records by id or phone_number (in my example named br_telefona) but it wont work when I search by first name or last name.

Also phone_number is set to be varchar in database setup same as first name and last name.

Here is my code for search:

```<code><%
                    Connection connection = null;
                    Statement statement = null;
                    ResultSet resultSet = null;
                    String id = request.getParameter("q");
                    try {
                        connection = DriverManager.getConnection(connectionUrl + database, userid, password);
                        statement = connection.createStatement();
                        String sql = "select * from buyers where first_name=" + id;
                        resultSet = statement.executeQuery(sql);
                        while (resultSet.next()) {
                %>
                <tr>
                    <td><%=resultSet.getString("first_name")%></td>
                    <td><%=resultSet.getString("last_name")%></td>
                    <td><%=resultSet.getString("email")%></td>
                    <td><%=resultSet.getString("phone_number")%></td>
                </tr>
                <%
                        }
                        connection.close();
                    } catch (Exception e) {
                        e.printStackTrace();
                    }
                %>
</code>```

Above code wont work but following one where I do query by phone_number is working just fine

```<code><%
                    Connection connection = null;
                    Statement statement = null;
                    ResultSet resultSet = null;
                    String id = request.getParameter("q");
                    try {
                        connection = DriverManager.getConnection(connectionUrl + database, userid, password);
                        statement = connection.createStatement();
                        String sql = "select * from buyers where phone_number=" + id;
                        resultSet = statement.executeQuery(sql);
                        while (resultSet.next()) {
                %>
                <tr>
                    <td><%=resultSet.getString("first_name")%></td>
                    <td><%=resultSet.getString("last_name")%></td>
                    <td><%=resultSet.getString("email")%></td>
                    <td><%=resultSet.getString("phone_number")%></td>
                </tr>
                <%
                        }
                        connection.close();
                    } catch (Exception e) {
                        e.printStackTrace();
                    }
                %>
</code>```

I also change first name from 'John' to 987654 and did

```<code>"select * from buyers where first_name=" + id;
</code>```

and it is working.

For some reason request.getParameter("q"); is only working when integer is inputed but not working for varchar.

Database engine is InnoDB, Charset/Collation latin1 / latin1_bin

答:
There are two ways in which you can make it work:

Recommended solution: Use PreparedStatement instead of Statement. This will help you in two prominent ways: (a) It will protect your application from SQL Injection. (b) You do not have to convert the input into text form explicitly by putting '' around it.

```<code>String sql = "SELECT * FROM buyers WHERE first_name=?";
PreparedStatement pstmt = connection.prepareStatement(sql);
pstmt.setString(1, id);
resultSet = pstm.executeQuery();
</code>```

Tactical solution: Convert the input into text form explicitly by putting '' around it.

```<code>String sql = "select * from buyers where first_name='" + id + "'";
</code>```

Body:
I want to create search option on my project. And it is working when I am searching my records by id or phone_number (in my example named br_telefona) but it wont work when I search by first name or last name.

Also phone_number is set to be varchar in database setup same as first name and last name.

Here is my code for search:

<%
                    Connection connection = null;
                    Statement statement = null;
                    ResultSet resultSet = null;
                    String id = request.getParameter("q");
                    try {
                        connection = DriverManager.getConnection(connectionUrl + database, userid, password);
                        statement = connection.createStatement();
                        String sql = "select * from buyers where first_name=" + id;
                        resultSet = statement.executeQuery(sql);
                        while (resultSet.next()) {
                %>

                    <%=resultSet.getString("first_name")%>
                    <%=resultSet.getString("last_name")%>
                    <%=resultSet.getString("email")%>
                    <%=resultSet.getString("phone_number")%>

                <%
                        }
                        connection.close();
                    } catch (Exception e) {
                        e.printStackTrace();
                    }
                %>

Above code wont work but following one where I do query by phone_number is working just fine

<%
                    Connection connection = null;
                    Statement statement = null;
                    ResultSet resultSet = null;
                    String id = request.getParameter("q");
                    try {
                        connection = DriverManager.getConnection(connectionUrl + database, userid, password);
                        statement = connection.createStatement();
                        String sql = "select * from buyers where phone_number=" + id;
                        resultSet = statement.executeQuery(sql);
                        while (resultSet.next()) {
                %>

                    <%=resultSet.getString("first_name")%>
                    <%=resultSet.getString("last_name")%>
                    <%=resultSet.getString("email")%>
                    <%=resultSet.getString("phone_number")%>

                <%
                        }
                        connection.close();
                    } catch (Exception e) {
                        e.printStackTrace();
                    }
                %>

I also change first name from 'John' to 987654 and did

"select * from buyers where first_name=" + id;

and it is working.

For some reason request.getParameter("q"); is only working when integer is inputed but not working for varchar.

Database engine is InnoDB, Charset/Collation latin1 / latin1_bin

Body:
There are two ways in which you can make it work:

Recommended solution: Use PreparedStatement instead of Statement. This will help you in two prominent ways: (a) It will protect your application from SQL Injection. (b) You do not have to convert the input into text form explicitly by putting '' around it.

String sql = "SELECT * FROM buyers WHERE first_name=?";
PreparedStatement pstmt = connection.prepareStatement(sql);
pstmt.setString(1, id);
resultSet = pstm.executeQuery();

Tactical solution: Convert the input into text form explicitly by putting '' around it.

String sql = "select * from buyers where first_name='" + id + "'";


来源: stackexchange

问:
programmatically set Paypal purchase 'value'
I'm trying to build my first paypal shopping payment system. Paypal helpfully provide some base code to aid with this:

```<code><div id="paypal-button-container"></div>
<script src="https://www.paypal.com/sdk/js?client-id=[MY-CLIENT-ID]&currency=GBP" data-sdk-integration-source="button-factory"></script>
<script>
  paypal.Buttons({
      style: {
          shape: 'rect',
          color: 'white',
          layout: 'vertical',
          label: 'paypal',

      },
      createOrder: function(data, actions) {
          return actions.order.create({
              purchase_units: [{
                  amount: {
                      value: '1'
                  }
              }]
          });
      },
      onApprove: function(data, actions) {
          return actions.order.capture().then(function(details) {
              alert('Transaction completed by ' + details.payer.name.given_name + '!');
          });
      }
  }).render('#paypal-button-container');
</script>
</code>```

I can't seem to figure out how to set the 'value' label inside the function inside of:

```<code>createOrder: function(data, actions) {
          return actions.order.create({
              purchase_units: [{
                  amount: {
                      value: '1'
                  }
              }]
          });
</code>```

My website is in bootstrap 4.5 with jQuery. On the site's index.html page I have 2 buttons that can be clicked to purchase two different services. Depending on which one the user selects, I use javascript to set the value in localStorage as follows: localStorage.setItem('serviceCost', $('#standard-cost').text()); This grabs a value from a span tag with ID 'standard-cost'. This is then used to set the text on the purchase.html page confirming for the user their selected item. I want to get the value from localStorage.getItem(serviceCost) and use it to set the cost for the 'value' key in the above function but everything I attempt is unsuccessful. The paypal script is embedded in a html page and the jQuery is in a separate file. The Paypal site doesn't offer any insight into this and I'm assuming this is a fairly common process, so how do you get a value from localStorage and pass it to the value variable in Paypal's generated code?

答:
```<code>              amount: {
                  value: localStorage.getItem('serviceCost')
              }
</code>```

Yep

ContentLicense: CC BY-SA 4.0

Body:
I'm trying to build my first paypal shopping payment system. Paypal helpfully provide some base code to aid with this:

I can't seem to figure out how to set the 'value' label inside the function inside of:

createOrder: function(data, actions) {
          return actions.order.create({
              purchase_units: [{
                  amount: {
                      value: '1'
                  }
              }]
          });

My website is in bootstrap 4.5 with jQuery. On the site's index.html page I have 2 buttons that can be clicked to purchase two different services. Depending on which one the user selects, I use javascript to set the value in localStorage as follows: localStorage.setItem('serviceCost', $('#standard-cost').text()); This grabs a value from a span tag with ID 'standard-cost'. This is then used to set the text on the purchase.html page confirming for the user their selected item. I want to get the value from localStorage.getItem(serviceCost) and use it to set the cost for the 'value' key in the above function but everything I attempt is unsuccessful. The paypal script is embedded in a html page and the jQuery is in a separate file. The Paypal site doesn't offer any insight into this and I'm assuming this is a fairly common process, so how do you get a value from localStorage and pass it to the value variable in Paypal's generated code?

Body:
              amount: {
                  value: localStorage.getItem('serviceCost')
              }

Yep


问:
Passing a generic object with type that is derived from the required type
Is it possible to pass a generic object as an argument with a class type that is derived from the expected class type?

The code below results in a compiler error, cannot convert from ItemObject<Equipment> to ItemObject<Item>, which I find odd because Equipment inherits from Item.

```<code>using System.Collections.Generic;

public abstract class Item { }

public abstract class Equipment : Item { }

public class ItemObject<T> where T : Item { }

public class EquipmentManager
{
    ItemObject<Equipment> equipment = new ItemObject<Equipment>();

    public void Unequip()
    {
        Inventory.instance.AddItem(equipment);
    }
}

public class Inventory
{
    public static Inventory instance;
    List<ItemObject<Item>> items = new List<ItemObject<Item>>();

    public void AddItem(ItemObject<Item> _item)
    {
        items.Add(_item);
    }

}
</code>```

答:
The problem here isn't that Equipment is inherited from Item. The issue is you are creating a specific type from a generic class. ItemObject<T>-> ItemObject<Equipment>. There is no explicit or implicit method to convert an ItemObject<Equipment> to an ItemObject<Item>.

Where the implicit conversion would work is if you had an ItemObject<Item> and tried to add an Equipment in place of an Item. In this case, the Equipment would be implicitly cast as an Item before being passed to ItemObject<Item>'s method.

Body:
Is it possible to pass a generic object as an argument with a class type that is derived from the expected class type?

The code below results in a compiler error, cannot convert from ItemObject<Equipment> to ItemObject<Item>, which I find odd because Equipment inherits from Item.

using System.Collections.Generic;

public abstract class Item { }

public abstract class Equipment : Item { }

public class ItemObject<T> where T : Item { }

public class EquipmentManager
{
    ItemObject<Equipment> equipment = new ItemObject<Equipment>();

    public void Unequip()
    {
        Inventory.instance.AddItem(equipment);
    }
}

public class Inventory
{
    public static Inventory instance;
    List<ItemObject<Item>> items = new List<ItemObject<Item>>();

    public void AddItem(ItemObject<Item> _item)
    {
        items.Add(_item);
    }

}


问:
How to create a dictionary from a given list?
I am trying to create a dictionary from my given list, knowing that the key will be the first letter of that word, and those have the same first letter would be added up to 1 key correspondingly. Can you guys help me out, please?

words= ['apple', 'bible','bird' ,'candy', 'day', 'elephant','friend']
```

答:
A more pythonic solution:

```<code>import collections

words= ['apple', 'bible','bird' ,'candy', 'day', 'elephant','friend']

d = collections.defaultdict(list)

for w in words:
    d[w[0]].append(w)

d = dict(d)
</code>```

Output

```<code>{
    "a": ["apple"],
    "b": ["bible", "bird"],
    "c": ["candy"],
    "d": ["day"],
    "e": ["elephant"],
    "f": ["friend"],
}
</code>```

Body:
A more pythonic solution:

import collections

words= ['apple', 'bible','bird' ,'candy', 'day', 'elephant','friend']

d = collections.defaultdict(list)

for w in words:
    d[w[0]].append(w)

d = dict(d)

Output

{
    "a": ["apple"],
    "b": ["bible", "bird"],
    "c": ["candy"],
    "d": ["day"],
    "e": ["elephant"],
    "f": ["friend"],
}


问:
Multiple input and print in one line
I am new to Python and I have one question about the same topic. I have this simple calculator but the thing is I want all inputs to be on a single line. For example to have print "Enter Numbers" and to be able to enter in the same line like num1-operator-num2 (5+2) and on the next line to have the print "The result is:"
Can anyone help with this one? :D</p>

```<code>num1 = float(input("Enter First Number:"))
op = input("Enter operator: ")
num2 = float(input("Enter Second Number:"))

if op == "+":
    print(num1 + num2)
elif op == "-":
    print(num1 - num2)
elif op == "*":
    print(num1 * num2)
elif op == "/":
    print(num1 / num2)
</code>```

答:
Here. You just need to add two arguments to the print function. First is the string, then the actual answer.

Code:

exp = input("Enter the expression you want to evaluate: ")

print("The answer is: ",eval(exp))
```

Hope this helps!

Title: Multiple input and print in one line

Body:
I am new to Python and I have one question about the same topic. I have this simple calculator but the thing is I want all inputs to be on a single line. For example to have print "Enter Numbers" and to be able to enter in the same line like num1-operator-num2 (5+2) and on the next line to have the print "The result is:"
Can anyone help with this one? :D

num1 = float(input("Enter First Number:"))
op = input("Enter operator: ")
num2 = float(input("Enter Second Number:"))

if op == "+":
    print(num1 + num2)
elif op == "-":
    print(num1 - num2)
elif op == "*":
    print(num1 * num2)
elif op == "/":
    print(num1 / num2)

Body:
Here. You just need to add two arguments to the print function. First is the string, then the actual answer.

Code:

exp = input("Enter the expression you want to evaluate: ")

print("The answer is: ",eval(exp))

Hope this helps!


问:
How to take a portion of one column to match with a portion of another column in pandas?
I am trying to clean up a large dataset. A sample of the dataset shows:

```<code>         Player Name        Headline
0        LeBron James       Woj: NBA. ESPN planning for a H-O-R-S-E tourna...
1        LeBron James       LeBron James suggests 5-10 games before playoffs
2        LeBron James       LeBron James overcomes Pelicans with 34/13/12
3        LeBron James       Anthony Davis (knee) won't play on Sunday
...      ...                ...
105180   Ryan Anderson      Ryan Anderson has first career double-double
105181   Ryan Anderson      Yi says he'll be back after All-Star break
105182   Ryan Anderson      Anderson stays hot in Nets win
</code>```

The problem I am having is that some headlines do not have anything to do with the player name (as you can see in row 0, 3, and 105181).

Question:

Is there a way to clean up the data so a portion of the "Player Name" column is featured in the "Headline" column? The rest that don't match would be removed from the new dataset made.

For example:

Row 0 would be removed since "LeBron" or "James" isn't in the "Headline" column.

Row 1 and 2 would stay the same.

Row 3 would be removed since "LeBron" or "James" isn't in the "Headline" column.

Row 105180 would stay the same.

Row 105181 would be removed since "Ryan" or "Anderson" isn't in the "Headline" column.

Row 105182 would stay the same since "Anderson" is in the "Player Name" and "Headline" column.

The new dataset will feature only the filtered data that has a portion of the "Player Name" column in the "Headline" column. I didn't know if there was a way to do this or if str.split should be used on the "Headline" column to split up the name from the rest of the headline then clean up from there.

答:
You can use split on each cell of the Player Name column and run an in check for each of the split words on the corresponding Headline. If any pass the in test, keep the row.

```<code>def any_words_included(x):
    return any(y in x["Headline"] for y in x["Player Name"].split())

df = df[df.apply(any_words_included, axis=1)]
</code>```

Provide the kwarg axis=1 to apply to filter on rows.

Body:
I am trying to clean up a large dataset. A sample of the dataset shows:

         Player Name        Headline
0        LeBron James       Woj: NBA. ESPN planning for a H-O-R-S-E tourna...
1        LeBron James       LeBron James suggests 5-10 games before playoffs
2        LeBron James       LeBron James overcomes Pelicans with 34/13/12
3        LeBron James       Anthony Davis (knee) won't play on Sunday
...      ...                ...
105180   Ryan Anderson      Ryan Anderson has first career double-double
105181   Ryan Anderson      Yi says he'll be back after All-Star break
105182   Ryan Anderson      Anderson stays hot in Nets win

The problem I am having is that some headlines do not have anything to do with the player name (as you can see in row 0, 3, and 105181).

Question:

Is there a way to clean up the data so a portion of the "Player Name" column is featured in the "Headline" column? The rest that don't match would be removed from the new dataset made.

For example:

Row 0 would be removed since "LeBron" or "James" isn't in the "Headline" column.

Row 1 and 2 would stay the same.

Row 3 would be removed since "LeBron" or "James" isn't in the "Headline" column.

Row 105180 would stay the same.

Row 105181 would be removed since "Ryan" or "Anderson" isn't in the "Headline" column.

Row 105182 would stay the same since "Anderson" is in the "Player Name" and "Headline" column.

The new dataset will feature only the filtered data that has a portion of the "Player Name" column in the "Headline" column. I didn't know if there was a way to do this or if str.split should be used on the "Headline" column to split up the name from the rest of the headline then clean up from there.

Body:
You can use split on each cell of the Player Name column and run an in check for each of the split words on the corresponding Headline. If any pass the in test, keep the row.

def any_words_included(x):
    return any(y in x["Headline"] for y in x["Player Name"].split())

df = df[df.apply(any_words_included, axis=1)]

Provide the kwarg axis=1 to apply to filter on rows.


问:
Return new Array that adds up every 2 values?
I am trying to create a method that will take in an array and return a new array that adds every 2 values to create one new value and move on to the next 2 values. If I have an array of {5,8,4,2} I want that array to become {13,6}. So far in my code I have it set up to where it creates an array of {5,8,4,2} and makes it into {13, 12, 6, 0} However, I don't want it to add that way. So I was wondering how do I get my program to skip over the 2nd value after doing the first addition? Also, how do I get rid of that useless zero at the end?</p>

```<code>import java.util.*;
import java.io.*;
public class reduceArray{
   public static int[] reduce(int[] currentArray){
   int[] newArray = new int[currentArray.length];

   for(int i = 0; i < currentArray.length -1; i++){

     newArray[i] = currentArray[i] + currentArray[i+1];

      }

     return newArray;

   }

   public static void main(String[] args){
       int[] arrayANew;
       int[] arrayA = {5,8,4,2};

       arrayANew= reduce(arrayA);

       System.out.println(Arrays.toString(arrayANew) );

    }
}
</code>```

答:
Just need to increment through the new array differently than the old one, as shown below.
(I also added changed it to be able to handle arrays of odd lengths and make newArray the right length)

import java.util.*;
import java.io.*;
class Scratch{
    public static int[] reduce(int[] currentArray){
        int[] newArray = new int[(int) Math.ceil((float) currentArray.length / 2)];

        if (newArray.length % 2 != 0) newArray[newArray.length - 1] = currentArray[currentArray.length - 1];

        for(int i = 0, j = 0; i < currentArray.length -1; i+=2, j++){
            newArray[j] = currentArray[i] + currentArray[i+1];
        }

        return newArray;
    }

    public static void main(String[] args){
        int[] arrayANew;
        int[] arrayA = {5,8,4,2};

        arrayANew= reduce(arrayA);

        System.out.println(Arrays.toString(arrayANew) );
    }
}
```

Body:
I am trying to create a method that will take in an array and return a new array that adds every 2 values to create one new value and move on to the next 2 values. If I have an array of {5,8,4,2} I want that array to become {13,6}. So far in my code I have it set up to where it creates an array of {5,8,4,2} and makes it into {13, 12, 6, 0} However, I don't want it to add that way. So I was wondering how do I get my program to skip over the 2nd value after doing the first addition? Also, how do I get rid of that useless zero at the end?

import java.util.*;
import java.io.*;
public class reduceArray{
   public static int[] reduce(int[] currentArray){
   int[] newArray = new int[currentArray.length];

   for(int i = 0; i < currentArray.length -1; i++){

     newArray[i] = currentArray[i] + currentArray[i+1];

      }

     return newArray;

   }

   public static void main(String[] args){
       int[] arrayANew;
       int[] arrayA = {5,8,4,2};

       arrayANew= reduce(arrayA);

       System.out.println(Arrays.toString(arrayANew) );

    }
}


问:
Guzzle certificate has expired
I have a certificate problem that I am looking for a solution to. The guzzle post request previously worked, but the destination url host root certificate has changed.

On the ubuntu command line, the curl call was successfully fixed with sudo update-ca-certificates.
So when I GET the https url from the command line, it works, but not with a guzzle client using php.

The Guzzle error is:

```<code>cURL error 60: SSL certificate problem: certificate has expired
</code>```

So when i use curl https://example.com command, its work.

I use a puppet that manages php fpm pools. I don't want to disable verification with ["verify" => false] option. Of course it works, but it's not safe.

答:
For ubuntu 14:04 version you can apply this method.
For ubuntu 16:04 or later you can apply this method.

If you have a problem with alpine image or docker and there has no way to up to upgrade base image, you can simply add RUN echo insecure >> ~/.curlrc into you Dockerfile.

Title: Guzzle certificate has expired

Body:
I have a certificate problem that I am looking for a solution to. The guzzle post request previously worked, but the destination url host root certificate has changed.

On the ubuntu command line, the curl call was successfully fixed with sudo update-ca-certificates.
So when I GET the https url from the command line, it works, but not with a guzzle client using php.

The Guzzle error is:

cURL error 60: SSL certificate problem: certificate has expired

So when i use curl https://example.com command, its work.

I use a puppet that manages php fpm pools. I don't want to disable verification with ["verify" => false] option. Of course it works, but it's not safe.


答:
You need to move the index you are accessing in currentArray over by two each time you go through your for loop:

```<code>public static int[] reduce(int[] currentArray) {
    int[] newArray = new int[currentArray.length / 2]; //needs to be half the length

    for(int i = 0; i < newArray.length; i++) { //use newArray's length since we are iterating over newArray
        newArray[i] = currentArray[2 * i] + currentArray[2 * i + 1]; //need to multiply indices by 2 to provide that "jumping" effect
    }

    return newArray;
}

public static void main(String[] args) {
    int[] arrayANew;
    int[] arrayA = { 5, 8, 4, 2 };
    arrayANew = reduce(arrayA);
    System.out.println(Arrays.toString(arrayANew));
}
</code>```

Note that this assumes the array has an even number of elements.  If you need it to also work with arrays of odd length, use the following:

```<code>public static int[] reduce(int[] currentArray) {
    int[] newArray = new int[currentArray.length / 2 + ((currentArray.length & 1) == 1 ? 1 : 0)]; //needs to be half the length

    for(int i = 0; i < newArray.length; i++) { //use newArray's length since we are iterating over newArray
        newArray[i] = currentArray[2 * i] + (2 * i + 1 >= currentArray.length ? 0 : currentArray[2 * i + 1]); //need to multiply indices by 2 to provide that "jumping" effect
    }

    return newArray;
}

public static void main(String[] args) {
    int[] arrayANew;
    int[] arrayA = { 5, 8, 4, 2 };
    arrayANew = reduce(arrayA);
    System.out.println(Arrays.toString(arrayANew));
}
</code>```

Title: Return new Array that adds up every 2 values?

Body:
You need to move the index you are accessing in currentArray over by two each time you go through your for loop:

public static int[] reduce(int[] currentArray) {
    int[] newArray = new int[currentArray.length / 2]; //needs to be half the length

    for(int i = 0; i < newArray.length; i++) { //use newArray's length since we are iterating over newArray
        newArray[i] = currentArray[2 * i] + currentArray[2 * i + 1]; //need to multiply indices by 2 to provide that "jumping" effect
    }

    return newArray;
}

public static void main(String[] args) {
    int[] arrayANew;
    int[] arrayA = { 5, 8, 4, 2 };
    arrayANew = reduce(arrayA);
    System.out.println(Arrays.toString(arrayANew));
}

Note that this assumes the array has an even number of elements.  If you need it to also work with arrays of odd length, use the following:

public static int[] reduce(int[] currentArray) {
    int[] newArray = new int[currentArray.length / 2 + ((currentArray.length & 1) == 1 ? 1 : 0)]; //needs to be half the length

    for(int i = 0; i < newArray.length; i++) { //use newArray's length since we are iterating over newArray
        newArray[i] = currentArray[2 * i] + (2 * i + 1 >= currentArray.length ? 0 : currentArray[2 * i + 1]); //need to multiply indices by 2 to provide that "jumping" effect
    }

    return newArray;
}

public static void main(String[] args) {
    int[] arrayANew;
    int[] arrayA = { 5, 8, 4, 2 };
    arrayANew = reduce(arrayA);
    System.out.println(Arrays.toString(arrayANew));
}


问:
Tableau calculated column based on another column
The following Tableau calculated field calculates properly for my entire dataset: sum([Total Risk])/sum([TotalACV])

However, there is an additional column called AccountNumber - there are 9000 unique account numbers in my data set and multiple entries per Account Number.

I would like to change the calculation above so it calculates based on the individual AccountNumber, not the entire data set.

答: {FIXED([AccountNumber]) : ([Account Risk %])}</p>


问:
Change color of Chrome's calendar icon in HTML Date Input
I am having some difficulty styling the HTML 5 Date input in Chrome.

Using mark up such as
<input type="date" max="2020-06-03" value="2020-06-01">, with some background and font color styling in CSS, renders in Chrome as:

I would like to make the calendar icon on the right hand side white, so it matches the color of the text.

::-webkit-calendar-picker-indicator looked like a possible candidate. Setting the background color on this changes the color behind the icon (as expected). However I can't find any parameter that has an effect on the icon color itself.

答:
I've managed to work around it for now using a CSS filter to invert the black color to white

```<code>::-webkit-calendar-picker-indicator {
    filter: invert(1);
}
</code>```

However this feels quite fragile and far from ideal.

Body:
I've managed to work around it for now using a CSS filter to invert the black color to white

::-webkit-calendar-picker-indicator {
    filter: invert(1);
}

However this feels quite fragile and far from ideal.


问:
FutureBuilder vs initState in Flutter
I want to load some data from an SQLite database in my Flutter application and show the results in a ListView. I am currently using a FutureBuilder widget to fetch the data asynchronously from the database and then build the ListView.

However, if I want to do some operations on the data - e.g. modify some information and save it to database - and then show the updated data in the ListView, I think I have to store the data in a local variable first and then call the setState() method to make changes to the data and re-build the page.

Is there any other better/preferred way to achieve the same without using FutureBuilder?

答:
https://stackoverflow.com/a/52021385/11252673

build() might be called several times - that's why this kind of initialization goes better on initState.

Title: FutureBuilder vs initState in Flutter


问:
I'm trying to write a player object that performs the simple task of moving on the canvas with WASD but doesn't move
Even tho everything seems fine at first glace, when I actually press on WASD it doesn't move. I'm trying to figure out if I should pass down "e" as some argument into the object or to call it somehow, but I'm not sure what's going wrong. Also I know this is a terrible way to implement WASD movement, I promise I will look into doing it better, but first I Want to manage to implement an object out of it before I branch out.</p>

```<code>const canvas = document.getElementById('canvas');
const ctx = canvas.getContext('2d');

const image = document.getElementById('player');

function Player() {
  this.location = {w: 200, h: 200, x: 20, y: 200, speed: 5, dx: 0, dy: 0};

  this.drawPlayer = function() {
    ctx.drawImage(image, this.location.x, this.location.y, this.location.w, this.location.h);
  }

  this.clear = function() {
    ctx.clearRect(0, 0, canvas.width, canvas.height);
  }

  this.newPos = function() {
    this.location.x += this.location.dx;
    this.location.y += this.location.dy;

    this.detectWalls();
  }

  this.detectWalls = function() {
    if(this.location.x < 0) {
      this.location.x = 0;
    }

    if(this.location.x + this.location.w > canvas.width) {
      this.location.x = canvas.width - this.location.w;
    }

    if(this.location.y < 0) {
      this.location.y = 0;
    }

    if(this.location.y + this.location.h > canvas.height) {
      this.location.y = canvas.height - this.location.h;
    }
  }

  this.moveUp = function() {
    this.location.dy = -this.location.speed;
    }

    this.moveDown = function() {
    this.location.dy = this.location.speed;
    }

    this.moveRight = function() {
    this.location.dx = this.location.speed;
    }

    this.moveLeft = function() {
    this.location.dx = -this.location.speed;
    }

    this.keyDown = function(e) {
      if (e.key === 'd') {
        this.moveRight();
      } else if (e.key === 'a') {
        this.moveLeft();
      } else if (e.key === 'w') {
        this.moveUp();
      } else if (e.key === 's') {
        this.moveDown();
      }
    }

    this.keyUp = function(e) {
      if (
        e.key == 'd' ||
        e.key == 'a' ||
        e.key == 'w' ||
        e.key == 's'
      ) {
        this.location.dx = 0;
        this.location.dx = 0;
      }
    }
}

let player = new Player();

function update() {
  player.clear();
  player.drawPlayer();
  player.newPos();

  requestAnimationFrame(update);
}

update();

document.addEventListener('keydown', keyDown);
document.addEventListener('keyup', keyUp);
</code>```

答:
Here start from something that actually moves the Player, then complicate it as much as you like

const canvas = document.getElementById('canvas');
const ctx = canvas.getContext('2d');
var image = new Image();
image.src="http://i.stack.imgur.com/UFBxY.png"
image.onload = update;

function Player() {
  this.location = { w: 80, h: 100, x: 50, y: 10, speed: 5 };

  this.drawPlayer = function() {
    ctx.drawImage(image, this.location.x, this.location.y, this.location.w, this.location.h);
  }

  this.clear = function() {
    ctx.clearRect(0, 0, canvas.width, canvas.height);
  }
}

let player = new Player();
function update() {
  player.clear();
  player.drawPlayer();
  requestAnimationFrame(update);
}

document.addEventListener("keydown", function(e) {
    if (e.key === 'd') {
      player.location.x += player.location.speed;
    } else if (e.key === 'a') {
      player.location.x += -player.location.speed;
    }
});```
<pre class="snippet-code-html lang-html prettyprint-override"><code><canvas id="canvas"></canvas></code>```

As you can see I removed a lot of your code just to focus on the problem of moving the player with the keys, you should do the same when asking a question, just keep your code example very small, that way is easier for others to start troubleshooting.

Body:
Even tho everything seems fine at first glace, when I actually press on WASD it doesn't move. I'm trying to figure out if I should pass down "e" as some argument into the object or to call it somehow, but I'm not sure what's going wrong. Also I know this is a terrible way to implement WASD movement, I promise I will look into doing it better, but first I Want to manage to implement an object out of it before I branch out.

const canvas = document.getElementById('canvas');
const ctx = canvas.getContext('2d');

const image = document.getElementById('player');

function Player() {
  this.location = {w: 200, h: 200, x: 20, y: 200, speed: 5, dx: 0, dy: 0};

  this.drawPlayer = function() {
    ctx.drawImage(image, this.location.x, this.location.y, this.location.w, this.location.h);
  }

  this.clear = function() {
    ctx.clearRect(0, 0, canvas.width, canvas.height);
  }

  this.newPos = function() {
    this.location.x += this.location.dx;
    this.location.y += this.location.dy;

    this.detectWalls();
  }

  this.detectWalls = function() {
    if(this.location.x < 0) {
      this.location.x = 0;
    }

    if(this.location.x + this.location.w > canvas.width) {
      this.location.x = canvas.width - this.location.w;
    }

    if(this.location.y < 0) {
      this.location.y = 0;
    }

    if(this.location.y + this.location.h > canvas.height) {
      this.location.y = canvas.height - this.location.h;
    }
  }

  this.moveUp = function() {
    this.location.dy = -this.location.speed;
    }

    this.moveDown = function() {
    this.location.dy = this.location.speed;
    }

    this.moveRight = function() {
    this.location.dx = this.location.speed;
    }

    this.moveLeft = function() {
    this.location.dx = -this.location.speed;
    }

    this.keyDown = function(e) {
      if (e.key === 'd') {
        this.moveRight();
      } else if (e.key === 'a') {
        this.moveLeft();
      } else if (e.key === 'w') {
        this.moveUp();
      } else if (e.key === 's') {
        this.moveDown();
      }
    }

    this.keyUp = function(e) {
      if (
        e.key == 'd' ||
        e.key == 'a' ||
        e.key == 'w' ||
        e.key == 's'
      ) {
        this.location.dx = 0;
        this.location.dx = 0;
      }
    }
}

let player = new Player();

function update() {
  player.clear();
  player.drawPlayer();
  player.newPos();

  requestAnimationFrame(update);
}

update();

document.addEventListener('keydown', keyDown);
document.addEventListener('keyup', keyUp);

Body:
Here start from something that actually moves the Player, then complicate it as much as you like

const canvas = document.getElementById('canvas');
const ctx = canvas.getContext('2d');
var image = new Image();
image.src="http://i.stack.imgur.com/UFBxY.png"
image.onload = update;

function Player() {
  this.location = { w: 80, h: 100, x: 50, y: 10, speed: 5 };

  this.drawPlayer = function() {
    ctx.drawImage(image, this.location.x, this.location.y, this.location.w, this.location.h);
  }

  this.clear = function() {
    ctx.clearRect(0, 0, canvas.width, canvas.height);
  }
}

let player = new Player();
function update() {
  player.clear();
  player.drawPlayer();
  requestAnimationFrame(update);
}

document.addEventListener("keydown", function(e) {
    if (e.key === 'd') {
      player.location.x += player.location.speed;
    } else if (e.key === 'a') {
      player.location.x += -player.location.speed;
    }
});

<canvas id="canvas"></canvas>

As you can see I removed a lot of your code just to focus on the problem of moving the player with the keys, you should do the same when asking a question, just keep your code example very small, that way is easier for others to start troubleshooting.


问:
Pydicom.read_file is only working with some Dicom images
I am making a python application that can convert a .dcm image to .jpg using the pydicom library. This is my code:

```<code>import pydicom
import cv2
import numpy as np

filename = 'testDicom.dcm'

#get pixel data from image
ds = pydicom.read_file(filename, force=True)
image = ds.pixel_array

new_img = []
max_value = None
min_value = None

#get maximum and minimum pixel values
for i in image:
    for l in i:
        if max_value:
            if l > max_value:
                max_value = l
        else:
            max_value = l

        if min_value:
            if l < min_value:
                min_value = l
        else:
            min_value = l

#use maximum and minimum pixel values to map pixel values between 0 and 255
for i in image:
    row = []
    for pixel in i:
        row.append((pixel - min_value) / (max_value / 255.0))
    new_img.append(row)

#convert to numpy array
new_img = np.array(new_img)

#save image
cv2.imwrite(filename.replace('.dcm', '.jpg'), new_img)
</code>```

I have tested it on two files. The first one,

```<code>https://github.com/MaxwellMarcus/Training-Data-Creator/blob/master/testDicom.dcm
</code>```

worked fine.

The second one,

```<code>https://github.com/MaxwellMarcus/Training-Data-Creator/blob/master/testDicom2.dcm
</code>```

gave an error:

```<code>Traceback (most recent call last):
  File "C:\Users\Max Marcus\github\Training-Data-Creator\creator.py", line 6, in <module>
    image = ds.pixel_array
  File "C:\Python38\lib\site-packages\pydicom\dataset.py", line 1615, in pixel_array
    self.convert_pixel_data()
  File "C:\Python38\lib\site-packages\pydicom\dataset.py", line 1324, in convert_pixel_data
    self._convert_pixel_data_without_handler()
  File "C:\Python38\lib\site-packages\pydicom\dataset.py", line 1409, in _convert_pixel_data_without_handler
    raise RuntimeError(msg + ', '.join(pkg_msg))
RuntimeError: The following handlers are available to decode the pixel data however they are missing required dependencies: GDCM (req. GDCM)
</code>```

Does anybody know why this is happening on only one of the two files, or how to fix it?

答:
You have a dataset that contains compressed Pixel Data. By itself pydicom can only handle Pixel Data that hasn't been compressed, but if you install one or more optional libraries then it can handle various compressions. This table tells you which package is required.

For JPEG Lossless, Non-hierarchical, 1st Order Prediction (1.2.840.10008.1.2.4.70), the only listed package available is GDCM, which unfortunately means you either require a Conda install (and on conda-forge its only available on Windows up to Python 3.6) or linux. Fortunately, there's an new package that I've been working on that also supports JPEG Lossless: pylibjpeg with the -libjpeg plugin.

```<code>$ pip install pylibjpeg pylibjpeg-libjpeg pydicom
</code>```

from pydicom import dcmread
import pylibjpeg

ds = dcmread("testDicom2.dcm")
arr = ds.pixel_array
```

<p>Looking at your data, I'd say the <em>Photometric Interpretation</em> value is wrong, too. Change it to YBR_FULL first:</p>

<pre class="lang-py prettyprint-override"><code>from pydicom import dcmread
import pylibjpeg

ds = dcmread("testDicom2.dcm")
ds.PhotometricInterpretation = 'YBR_FULL'
arr = ds.pixel_array
</code>```

Body:
I am making a python application that can convert a .dcm image to .jpg using the pydicom library. This is my code:

import pydicom
import cv2
import numpy as np

filename = 'testDicom.dcm'

#get pixel data from image
ds = pydicom.read_file(filename, force=True)
image = ds.pixel_array

new_img = []
max_value = None
min_value = None

#get maximum and minimum pixel values
for i in image:
    for l in i:
        if max_value:
            if l > max_value:
                max_value = l
        else:
            max_value = l

        if min_value:
            if l < min_value:
                min_value = l
        else:
            min_value = l

#use maximum and minimum pixel values to map pixel values between 0 and 255
for i in image:
    row = []
    for pixel in i:
        row.append((pixel - min_value) / (max_value / 255.0))
    new_img.append(row)

#convert to numpy array
new_img = np.array(new_img)

#save image
cv2.imwrite(filename.replace('.dcm', '.jpg'), new_img)

I have tested it on two files. The first one,

https://github.com/MaxwellMarcus/Training-Data-Creator/blob/master/testDicom.dcm

worked fine.

The second one,

https://github.com/MaxwellMarcus/Training-Data-Creator/blob/master/testDicom2.dcm

gave an error:

Traceback (most recent call last):
  File "C:\Users\Max Marcus\github\Training-Data-Creator\creator.py", line 6, in <module>
    image = ds.pixel_array
  File "C:\Python38\lib\site-packages\pydicom\dataset.py", line 1615, in pixel_array
    self.convert_pixel_data()
  File "C:\Python38\lib\site-packages\pydicom\dataset.py", line 1324, in convert_pixel_data
    self._convert_pixel_data_without_handler()
  File "C:\Python38\lib\site-packages\pydicom\dataset.py", line 1409, in _convert_pixel_data_without_handler
    raise RuntimeError(msg + ', '.join(pkg_msg))
RuntimeError: The following handlers are available to decode the pixel data however they are missing required dependencies: GDCM (req. GDCM)

Does anybody know why this is happening on only one of the two files, or how to fix it?

Body:
You have a dataset that contains compressed Pixel Data. By itself pydicom can only handle Pixel Data that hasn't been compressed, but if you install one or more optional libraries then it can handle various compressions. This table tells you which package is required.

For JPEG Lossless, Non-hierarchical, 1st Order Prediction (1.2.840.10008.1.2.4.70), the only listed package available is GDCM, which unfortunately means you either require a Conda install (and on conda-forge its only available on Windows up to Python 3.6) or linux. Fortunately, there's an new package that I've been working on that also supports JPEG Lossless: pylibjpeg with the -libjpeg plugin.

$ pip install pylibjpeg pylibjpeg-libjpeg pydicom

from pydicom import dcmread
import pylibjpeg

ds = dcmread("testDicom2.dcm")
arr = ds.pixel_array

Looking at your data, I'd say the Photometric Interpretation value is wrong, too. Change it to YBR_FULL first:

from pydicom import dcmread
import pylibjpeg

ds = dcmread("testDicom2.dcm")
ds.PhotometricInterpretation = 'YBR_FULL'
arr = ds.pixel_array


答:
You could use groupby as you seem to have several times the same player and then str.contains on the name of the player once split to get either part of the name.

```<code>df_ = df[df.groupby('Player Name')
           .apply(lambda x: x['Headline'].str.contains('|'.join(x.name.split(' '))))
           .reset_index(level=0, drop=True)]
print (df_)
          Player Name                                          Headline

1        LeBron James  LeBron James suggests 5-10 games before playoffs
2        LeBron James     LeBron James overcomes Pelicans with 34/13/12
105180  Ryan Anderson      Ryan Anderson has first career double-double
105182  Ryan Anderson                    Anderson stays hot in Nets win
</code>```

Title: How to take a portion of one column to match with a portion of another column in pandas?

Body:
You could use groupby as you seem to have several times the same player and then str.contains on the name of the player once split to get either part of the name.

df_ = df[df.groupby('Player Name')
           .apply(lambda x: x['Headline'].str.contains('|'.join(x.name.split(' '))))
           .reset_index(level=0, drop=True)]
print (df_)
          Player Name                                          Headline

1        LeBron James  LeBron James suggests 5-10 games before playoffs
2        LeBron James     LeBron James overcomes Pelicans with 34/13/12
105180  Ryan Anderson      Ryan Anderson has first career double-double
105182  Ryan Anderson                    Anderson stays hot in Nets win


问:
Can't assign multiple HTML elements in the .css() function
I have 4 divs filter1, filter2, filter3, filter4 and I have an anchor tag inside of them and an image, I want to make it so that when you hover on a filter div, the anchor tag gets the other color, the only problem is that I cannot change the color via JavaScript, which is what I am trying to achieve.

I want to change the color of the anchor when I hover (or in JS mouseOver) any of the filter div.

The only problem is I cannot define multiple HTML tags in the .css function in JavaScript.

I am trying to achieve this:

$(".filter1").mouseover(function () {
  $(".filter , li , a").css("color", "pink");
});
```

<p>The only problem is, now every .filter function, every <code>li</code> tag and every <code>anchor</code> tag in my HTML documents get color pink when I hover over any of these.</p>

<p>What I have right now:</p>

<pre class="lang-js prettyprint-override"><code>$(document).ready(function () {
  $(".filter1").mouseover(function () {
    $(".filter ").css("color", "pink");
  });
  $(".filter1").mouseout(function () {
    $(".filter li a").css("color", "#FFFF");
  });

  //also filter2, filter3, filter4 etc

});
</code>```

How can I resolve this?

答: You need to use .each() method to aply the css to all childs.

Body:
I have 4 divs filter1, filter2, filter3, filter4 and I have an anchor tag inside of them and an image, I want to make it so that when you hover on a filter div, the anchor tag gets the other color, the only problem is that I cannot change the color via JavaScript, which is what I am trying to achieve.

I want to change the color of the anchor when I hover (or in JS mouseOver) any of the filter div.

The only problem is I cannot define multiple HTML tags in the .css function in JavaScript.

I am trying to achieve this:

$(".filter1").mouseover(function () {
  $(".filter , li , a").css("color", "pink");
});

The only problem is, now every .filter function, every li tag and every anchor tag in my HTML documents get color pink when I hover over any of these.

What I have right now:

$(document).ready(function () {
  $(".filter1").mouseover(function () {
    $(".filter ").css("color", "pink");
  });
  $(".filter1").mouseout(function () {
    $(".filter li a").css("color", "#FFFF");
  });

  //also filter2, filter3, filter4 etc

});

How can I resolve this?


问:
SessionNotCreatedException: This version of ChromeDriver only supports Chrome version 84 using ChromeDriver and Chrome through Selenium and Python

I am using python 3 on windows 7, selenium, chromedriver version 84
  (latest) to automate my chrome browser.

I am using this script:

from selenium import webdriver
#import chromedriver_binary  # Adds chromedriver binary to path

driver = webdriver.Chrome()
driver.get("http://www.python.org")
```

<p>and I always get this error upon running it.</p>

<pre class="lang-py prettyprint-override"><code>Traceback (most recent call last):
  File "D:\Huzefa\Desktop\zzzzzz.py", line 4, in <module>
    driver = webdriver.Chrome()
  File "C:\Users\Huzefa\AppData\Local\Programs\Python\Python36\lib\site-packages\selenium\webdriver\chrome\webdriver.py", line 81, in __init__
    desired_capabilities=desired_capabilities)
  File "C:\Users\Huzefa\AppData\Local\Programs\Python\Python36\lib\site-packages\selenium\webdriver\remote\webdriver.py", line 157, in __init__
    self.start_session(capabilities, browser_profile)
  File "C:\Users\Huzefa\AppData\Local\Programs\Python\Python36\lib\site-packages\selenium\webdriver\remote\webdriver.py", line 252, in start_session
    response = self.execute(Command.NEW_SESSION, parameters)
  File "C:\Users\Huzefa\AppData\Local\Programs\Python\Python36\lib\site-packages\selenium\webdriver\remote\webdriver.py", line 321, in execute
    self.error_handler.check_response(response)
  File "C:\Users\Huzefa\AppData\Local\Programs\Python\Python36\lib\site-packages\selenium\webdriver\remote\errorhandler.py", line 242, in check_response
    raise exception_class(message, screen, stacktrace)
selenium.common.exceptions.SessionNotCreatedException: Message: session not created: This version of ChromeDriver only supports Chrome version 84
</code>```

My ChromeDriver is in path. Also i have used other versions of chromedriver but i am not able to navigate to a website!

答:
This error message...

```<code>selenium.common.exceptions.SessionNotCreatedException: Message: session not created: This version of ChromeDriver only supports Chrome version 84
</code>```

...implies that the ChromeDriver was unable to initiate/spawn a new Browsing Context i.e. Chrome Browser session.

Analysis

Your main issue is the incompatibility between the version of the binaries you are using as follows:

You are using chromedriver=84

Release Notes of chromedriver=84 clearly mentions:

Supports Chrome version 84

Presumably you are using chrome=83 the latest push for Chrome.

So there is a clear mismatch between ChromeDriver v84 and the Chrome Browser v83

Solution

There are two (2) solutions to this issue.

The easiest solution would be to download and start using chromedriver=83.0.4103.39

If you want to continue with chromedriver=84 you have to download the latest Chromium binary from either of the official development repositories:

The Chromium Projects

chromium.appspot

Chrome Canary - Nightly build for developers

Additionally also ensure that:

Selenium is upgraded to  current levels Version 3.141.59.

If your base Web Client version is too old, then uninstall it and install a recent GA and released version of Web Client.

Clean your Project Workspace through your IDE and Rebuild your project with required dependencies only.

If your base Web Client version is too old, then uninstall it and install a recent GA and released version of Web Client.

Take a System Reboot.

Execute your @Test as non-root user.

Always invoke driver.quit() within tearDown(){} method to close & destroy the WebDriver and Web Client instances gracefully.

Body:
I am using python 3 on windows 7, selenium, chromedriver version 84
  (latest) to automate my chrome browser.

I am using this script:

from selenium import webdriver
#import chromedriver_binary  # Adds chromedriver binary to path

driver = webdriver.Chrome()
driver.get("http://www.python.org")

and I always get this error upon running it.

Traceback (most recent call last):
  File "D:\Huzefa\Desktop\zzzzzz.py", line 4, in <module>
    driver = webdriver.Chrome()
  File "C:\Users\Huzefa\AppData\Local\Programs\Python\Python36\lib\site-packages\selenium\webdriver\chrome\webdriver.py", line 81, in __init__
    desired_capabilities=desired_capabilities)
  File "C:\Users\Huzefa\AppData\Local\Programs\Python\Python36\lib\site-packages\selenium\webdriver\remote\webdriver.py", line 157, in __init__
    self.start_session(capabilities, browser_profile)
  File "C:\Users\Huzefa\AppData\Local\Programs\Python\Python36\lib\site-packages\selenium\webdriver\remote\webdriver.py", line 252, in start_session
    response = self.execute(Command.NEW_SESSION, parameters)
  File "C:\Users\Huzefa\AppData\Local\Programs\Python\Python36\lib\site-packages\selenium\webdriver\remote\webdriver.py", line 321, in execute
    self.error_handler.check_response(response)
  File "C:\Users\Huzefa\AppData\Local\Programs\Python\Python36\lib\site-packages\selenium\webdriver\remote\errorhandler.py", line 242, in check_response
    raise exception_class(message, screen, stacktrace)
selenium.common.exceptions.SessionNotCreatedException: Message: session not created: This version of ChromeDriver only supports Chrome version 84

My ChromeDriver is in path. Also i have used other versions of chromedriver but i am not able to navigate to a website!

Body:
This error message...

selenium.common.exceptions.SessionNotCreatedException: Message: session not created: This version of ChromeDriver only supports Chrome version 84

...implies that the ChromeDriver was unable to initiate/spawn a new Browsing Context i.e. Chrome Browser session.

Analysis

Your main issue is the incompatibility between the version of the binaries you are using as follows:

You are using chromedriver=84

Release Notes of chromedriver=84 clearly mentions:

Supports Chrome version 84

Presumably you are using chrome=83 the latest push for Chrome.

So there is a clear mismatch between ChromeDriver v84 and the Chrome Browser v83

Solution

There are two (2) solutions to this issue.

The easiest solution would be to download and start using chromedriver=83.0.4103.39

If you want to continue with chromedriver=84 you have to download the latest Chromium binary from either of the official development repositories:

The Chromium Projects

chromium.appspot

Chrome Canary - Nightly build for developers

Additionally also ensure that:

Selenium is upgraded to  current levels Version 3.141.59.

If your base Web Client version is too old, then uninstall it and install a recent GA and released version of Web Client.

Clean your Project Workspace through your IDE and Rebuild your project with required dependencies only.

If your base Web Client version is too old, then uninstall it and install a recent GA and released version of Web Client.

Take a System Reboot.

Execute your @Test as non-root user.

Always invoke driver.quit() within tearDown(){} method to close & destroy the WebDriver and Web Client instances gracefully.


问:
Recent items with RibbonGallery: MVVM way to avoid last clicked item from remaining selected
Actually it sounds like a basic question, but I could not find a proper MVVM way to keep the lastest clicked item from remaining selected.

I use a RibbonGallery to display a list of recently opened projects:

XAML:

<RibbonGallery Grid.Row         = "1"
               CanUserFilter    = "False"
               Command          = "{Binding cmdOpenRecent}"

               ScrollViewer.VerticalScrollBarVisibility = "Auto">

    <RibbonGalleryCategory Background   = "Transparent"
                           ItemsSource  = "{Binding RecentProjects}">

        <RibbonGalleryCategory.ItemsPanel>
            <ItemsPanelTemplate>
                <StackPanel Orientation="Vertical" IsItemsHost="True"/>
            </ItemsPanelTemplate>
        </RibbonGalleryCategory.ItemsPanel>

    </RibbonGalleryCategory>

</RibbonGallery>
```

When I select an entry, the command gets called and I can open the file.

The issue now is that the last clicked entry remains selected and that there does not seem to be a clean way to avoid this:

Is there any proper MVVM way without code behind to avoid this behavior?! Many thanks in advance!!!

答:
For the records, I did not find a decent way to achieve the aforementioned clearing of the last selected item in the list.

So I proceeded as follows (to me it feels more like a dirty hack/workaround...):

I bound the SelectedItem property of the RibbonGallery to a property of the ViewModel for the sole purpose of resetting this value to null...

<RibbonGallery Grid.Row         = "1"
               CanUserFilter    = "False"
               Command          = "{Binding cmdOpenRecent}"
               CommandParameter = "{Binding RelativeSource={RelativeSource Self}, Path=SelectedItem}"
               SelectedItem     = "{Binding RecentSelectedLessonBook}"

               ScrollViewer.VerticalScrollBarVisibility = "Auto">

    <RibbonGalleryCategory Background   = "Transparent"
                           ItemsSource  = "{Binding RecentLessonBooks}">

        <RibbonGalleryCategory.ItemsPanel>
            <ItemsPanelTemplate>
                <StackPanel Orientation="Vertical" IsItemsHost="True"/>
            </ItemsPanelTemplate>
        </RibbonGalleryCategory.ItemsPanel>

        <RibbonGalleryCategory.ItemTemplate>
            <DataTemplate DataType="proptypes:SettingRecentLessonBook">
                <TextBlock Text="{Binding bookName}" ToolTip="{Binding bookFolder}" />
            </DataTemplate>
        </RibbonGalleryCategory.ItemTemplate>

    </RibbonGalleryCategory>

</RibbonGallery>
```

If there is a better MVVM way of achieving this.... YOU ARE WELCOME! :)

Body:
Actually it sounds like a basic question, but I could not find a proper MVVM way to keep the lastest clicked item from remaining selected.

I use a RibbonGallery to display a list of recently opened projects:

XAML:

<RibbonGallery Grid.Row         = "1"
               CanUserFilter    = "False"
               Command          = "{Binding cmdOpenRecent}"

               ScrollViewer.VerticalScrollBarVisibility = "Auto">

    <RibbonGalleryCategory Background   = "Transparent"
                           ItemsSource  = "{Binding RecentProjects}">

        <RibbonGalleryCategory.ItemsPanel>
            <ItemsPanelTemplate>
                <StackPanel Orientation="Vertical" IsItemsHost="True"/>
            </ItemsPanelTemplate>
        </RibbonGalleryCategory.ItemsPanel>

    </RibbonGalleryCategory>

</RibbonGallery>

When I select an entry, the command gets called and I can open the file.

The issue now is that the last clicked entry remains selected and that there does not seem to be a clean way to avoid this:

Is there any proper MVVM way without code behind to avoid this behavior?! Many thanks in advance!!!

Body:
For the records, I did not find a decent way to achieve the aforementioned clearing of the last selected item in the list.

So I proceeded as follows (to me it feels more like a dirty hack/workaround...):

I bound the SelectedItem property of the RibbonGallery to a property of the ViewModel for the sole purpose of resetting this value to null...

<RibbonGallery Grid.Row         = "1"
               CanUserFilter    = "False"
               Command          = "{Binding cmdOpenRecent}"
               CommandParameter = "{Binding RelativeSource={RelativeSource Self}, Path=SelectedItem}"
               SelectedItem     = "{Binding RecentSelectedLessonBook}"

               ScrollViewer.VerticalScrollBarVisibility = "Auto">

    <RibbonGalleryCategory Background   = "Transparent"
                           ItemsSource  = "{Binding RecentLessonBooks}">

        <RibbonGalleryCategory.ItemsPanel>
            <ItemsPanelTemplate>
                <StackPanel Orientation="Vertical" IsItemsHost="True"/>
            </ItemsPanelTemplate>
        </RibbonGalleryCategory.ItemsPanel>

        <RibbonGalleryCategory.ItemTemplate>
            <DataTemplate DataType="proptypes:SettingRecentLessonBook">
                <TextBlock Text="{Binding bookName}" ToolTip="{Binding bookFolder}" />
            </DataTemplate>
        </RibbonGalleryCategory.ItemTemplate>

    </RibbonGalleryCategory>

</RibbonGallery>

If there is a better MVVM way of achieving this.... YOU ARE WELCOME! :)


问:
React - functional component does not return updated variable values
I have a class Component FooPage which renders an imported functional Component BarForm. I pass handleSubmit as a prop to BarForm and want to capture the inputData value. The issue is the value is returned as the initial value.

To help debugging: before I submit, the latest value of inputData was logged correctly, and the submit did not trigger re-rendering. Still, FooPage console logs "initial value". What's more, changing onSubmit callback from handleSubmit(inputData) to arrow function (event) => handleSubmit(inputData)(event) fixes the problem.

While I know I can achieve this by useState, I want to understand why the updated inputData is returned as initial value even without re-rendering, and why using arrow function  as callback fixed the problem.

const BarForm = ({ handleSubmit }) => {
  let inputData = "initial value"
  console.log("I just re-rendered.") //Check BarForm did not re-render when submit.
  return (
    <form onSubmit={ handleSubmit(inputData) }> {/* won't work, but arrow function does */}
      <input
        onChange = {(event) => {
          inputData = event.target.value; //update inputData
          console.log(inputData); //confirm the value of inputData before submit
        }}
        />
      <button type="submit">Submit</button> {/* But */}
    </form>
  )
}

class FooPage extends React.Component {
  handleSubmit = (inputData) => (event) => {
    event.preventDefault(); //Don't re-render
    console.log(inputData); //See the output
  }

  render() {
    return (
      <BarForm handleSubmit = {this.handleSubmit} />
    )
  }
}

ReactDOM.render(<FooPage />, document.getElementById("app"));```
<pre class="snippet-code-html lang-html prettyprint-override"><code><script src="https://unpkg.com/react@16/umd/react.production.min.js" crossorigin></script>
<script src="https://unpkg.com/react-dom@16/umd/react-dom.production.min.js" crossorigin></script>

<div id="app"></div></code>```

答:
When you set <form onSubmit={ handleSubmit(inputData) }>, what you are actually doing in this case is calling the handleSubmit from FooPage function which returns a new function with inputData as captured when the component was first rendered as part of the function's scope.

When you call it with the arrow function, you don't actually create a new function when the component renders. You create the function onSubmit.


问:
Slicing lists based on several parameters
I have posted a similar question several times but it was closed or redirected to another post that wasn't answering my question. I hope this time this post stays.

I have a df with US census data. I grouped states with their correspondent counties. There's also another column with population ordered from high to low. The only thing I am trying to do is to slice it so I only get the three first most populous counties for each state. The final result should display the three most populous states based on their three most populous counties.

Here's so far my code:

```<code>def answer_six():
    cdf = census_df[census_df['SUMLEV'] == 50]
    columns_to_keep = ['STNAME', 'CTYNAME', 'CENSUS2010POP']
    cdf = cdf[columns_to_keep]
    cdf = cdf.sort_values('CENSUS2010POP', ascending=False)
    cdf = cdf.groupby('STNAME')
    cdf = cdf.apply(pd.DataFrame.sort_values, 'CENSUS2010POP', ascending=False).head(100)
#    cdf = [i for i in cdf['STNAME'][:3] if all(cdf['STNAME']) == all(cdf['STNAME'])]
    return cdf
answer_six()
</code>```

Here's a sample of my data:

```<code>    STNAME  CTYNAME           CENSUS2010POP
37  Alabama Jefferson County    658466
49  Alabama Mobile County   412992
45  Alabama Madison County  334811
51  Alabama Montgomery County   229363
59  Alabama Shelby County   195085
63  Alabama Tuscaloosa County   194656
2   Alabama Baldwin County  182265
41  Alabama Lee County  140247
52  Alabama Morgan County   119490
8   Alabama Calhoun County  118572
28  Alabama Etowah County   104430
35  Alabama Houston County  101547
48  Alabama Marshall County 93019
39  Alabama Lauderdale County   92709
58  Alabama St. Clair County    83593
42  Alabama Limestone County    82782
61  Alabama Talladega County    82291
22  Alabama Cullman County  80406
26  Alabama Elmore County   79303
25  Alabama DeKalb County   71109
64  Alabama Walker County   67023
5   Alabama Blount County   57322
1   Alabama Autauga County  54571
17  Alabama Colbert County  54428
36  Alabama Jackson County  53227
57  Alabama Russell County  52947
23  Alabama Dale County 50251
16  Alabama Coffee County   49948
24  Alabama Dallas County   43820
11  Alabama Chilton County  43643
... ... ... ... ...
80  Alaska  Kenai Peninsula Borough 55400
79  Alaska  Juneau City and Borough 31275
72  Alaska  Bethel Census Area  17013
</code>```

答:
I am guessing what you are looking for is cdf.groupby('STNAME').head(3) after you sort the cdf?

P.S. perhaps your questions keep getting closed because of duplicate questions? like:
Pandas get topmost n records within each group

Body:
I have posted a similar question several times but it was closed or redirected to another post that wasn't answering my question. I hope this time this post stays.

I have a df with US census data. I grouped states with their correspondent counties. There's also another column with population ordered from high to low. The only thing I am trying to do is to slice it so I only get the three first most populous counties for each state. The final result should display the three most populous states based on their three most populous counties.

Here's so far my code:

def answer_six():
    cdf = census_df[census_df['SUMLEV'] == 50]
    columns_to_keep = ['STNAME', 'CTYNAME', 'CENSUS2010POP']
    cdf = cdf[columns_to_keep]
    cdf = cdf.sort_values('CENSUS2010POP', ascending=False)
    cdf = cdf.groupby('STNAME')
    cdf = cdf.apply(pd.DataFrame.sort_values, 'CENSUS2010POP', ascending=False).head(100)
#    cdf = [i for i in cdf['STNAME'][:3] if all(cdf['STNAME']) == all(cdf['STNAME'])]
    return cdf
answer_six()

Here's a sample of my data:

    STNAME  CTYNAME           CENSUS2010POP
37  Alabama Jefferson County    658466
49  Alabama Mobile County   412992
45  Alabama Madison County  334811
51  Alabama Montgomery County   229363
59  Alabama Shelby County   195085
63  Alabama Tuscaloosa County   194656
2   Alabama Baldwin County  182265
41  Alabama Lee County  140247
52  Alabama Morgan County   119490
8   Alabama Calhoun County  118572
28  Alabama Etowah County   104430
35  Alabama Houston County  101547
48  Alabama Marshall County 93019
39  Alabama Lauderdale County   92709
58  Alabama St. Clair County    83593
42  Alabama Limestone County    82782
61  Alabama Talladega County    82291
22  Alabama Cullman County  80406
26  Alabama Elmore County   79303
25  Alabama DeKalb County   71109
64  Alabama Walker County   67023
5   Alabama Blount County   57322
1   Alabama Autauga County  54571
17  Alabama Colbert County  54428
36  Alabama Jackson County  53227
57  Alabama Russell County  52947
23  Alabama Dale County 50251
16  Alabama Coffee County   49948
24  Alabama Dallas County   43820
11  Alabama Chilton County  43643
... ... ... ... ...
80  Alaska  Kenai Peninsula Borough 55400
79  Alaska  Juneau City and Borough 31275
72  Alaska  Bethel Census Area  17013


问:
MongoDB Stitch GraphQL Custom Mutation Resolver returning null
GraphQL is a newer feature for MongoDB Stitch, and I know it is in beta, so thank you for your help in advance. I am excited about using GraphQL directly in Stitch so I am hoping that maybe I just overlooked something.

The documentation for the return Payload displays the use of bsonType, but when actually entering the JSON Schema for the payload type it asks for you to use "type" instead of "bsonType". It still works using "bsonType" to me which is odd as long as at least one of the properties uses "type".

Below is the function:

```<code>      const mongodb = context.services.get("mongodb-atlas");
      const collection = mongodb.db("<database>").collection("<collection>");
      const query = { _id: BSON.ObjectId(input.id) }
      const update = {
        "$push": {
          "notes": {
            "createdBy": context.user.id,
            "createdAt": new Date,
            "text": input.text
          }
        }
      };

      const options = { returnNewDocument: true }

      collection.findOneAndUpdate(query, update, options).then(updatedDocument => {
        if(updatedDocument) {
      console.log(`Successfully updated document: ${updatedDocument}.`)
    } else {
      console.log("No document matches the provided query.")
    }
    return {
      _id: updatedDocument._id,
      notes: updatedDocument.notes
    }
  })
  .catch(err => console.error(`Failed to find and update document: ${err}`))
}
</code>```

Here is the Input Type in the customer resolver:

```<code>  "type": "object",
  "title": "AddNoteToLeadInput",
  "required": [
    "id",
    "text"
  ],
  "properties": {
    "id": {
      "type": "string"
    },
    "text": {
      "type": "string"
    }
  }
}
</code>```

Below is the Payload Type:

```<code>{
  "type": "object",
  "title": "AddNoteToLeadPayload",
  "properties": {
    "_id": {
      "type": "objectId"
    },
    "notes": {
      "type": "array",
      "items": {
        "type": "object",
        "properties": {
          "createdAt": {
            "type": "string"
          },
          "createdBy": {
            "type": "string"
          },
          "text": {
            "type": "string"
          }
        }
      }
    }
  }
}
</code>```

When entering the wrong "type" the error states:

Expected valid values are:[array boolean integer number null object string]

When entering the wrong "bsonType" the error states:

Expected valid values are:[string object array objectId boolean bool null regex date timestamp int long decimal double number binData]

I've tried every combination I can think of including changing all "bsonType" to "type". I also tried changing the _id to a string when using "type" or objectId when "bsonType". No matter what combination I try when I use the mutation it does what it is supposed to and adds the note into the lead, but the return payload always displays null. I need it to return the _id and note so that it will update the InMemoryCache in Apollo on the front end.

答:
Hi Bernard – There is an unfortunate bug in the custom resolver form UI at the moment which doesn't allow you to only use bsonType in the input/payload types – we are working on addressing this.  In actually you should be able to use either type/bsonType or a mix of the two as long as they agree with your data.  I think that the payload type definition you want is likely:

```<code>{
  "type": "object",
  "title": "AddNoteToLeadPayload",
  "properties": {
    "_id": {
      "bsonType": "objectId"
    },
    "notes": {
      "type": "array",
      "items": {
        "type": "object",
        "properties": {
          "createdAt": {
            "bsonType": "date"
          },
          "createdBy": {
            "type": "string"
          },
          "text": {
            "type": "string"
          }
        }
      }
    }
  }
}
</code>```

If that doesn't work, it might be helpful to give us a sample of the data that you would like returned.

Body:
GraphQL is a newer feature for MongoDB Stitch, and I know it is in beta, so thank you for your help in advance. I am excited about using GraphQL directly in Stitch so I am hoping that maybe I just overlooked something.

The documentation for the return Payload displays the use of bsonType, but when actually entering the JSON Schema for the payload type it asks for you to use "type" instead of "bsonType". It still works using "bsonType" to me which is odd as long as at least one of the properties uses "type".

Below is the function:

      const mongodb = context.services.get("mongodb-atlas");
      const collection = mongodb.db("<database>").collection("<collection>");
      const query = { _id: BSON.ObjectId(input.id) }
      const update = {
        "$push": {
          "notes": {
            "createdBy": context.user.id,
            "createdAt": new Date,
            "text": input.text
          }
        }
      };

      const options = { returnNewDocument: true }

      collection.findOneAndUpdate(query, update, options).then(updatedDocument => {
        if(updatedDocument) {
      console.log(`Successfully updated document: ${updatedDocument}.`)
    } else {
      console.log("No document matches the provided query.")
    }
    return {
      _id: updatedDocument._id,
      notes: updatedDocument.notes
    }
  })
  .catch(err => console.error(`Failed to find and update document: ${err}`))
}

Here is the Input Type in the customer resolver:

  "type": "object",
  "title": "AddNoteToLeadInput",
  "required": [
    "id",
    "text"
  ],
  "properties": {
    "id": {
      "type": "string"
    },
    "text": {
      "type": "string"
    }
  }
}

Below is the Payload Type:

{
  "type": "object",
  "title": "AddNoteToLeadPayload",
  "properties": {
    "_id": {
      "type": "objectId"
    },
    "notes": {
      "type": "array",
      "items": {
        "type": "object",
        "properties": {
          "createdAt": {
            "type": "string"
          },
          "createdBy": {
            "type": "string"
          },
          "text": {
            "type": "string"
          }
        }
      }
    }
  }
}

When entering the wrong "type" the error states:

Expected valid values are:[array boolean integer number null object string]

When entering the wrong "bsonType" the error states:

Expected valid values are:[string object array objectId boolean bool null regex date timestamp int long decimal double number binData]

I've tried every combination I can think of including changing all "bsonType" to "type". I also tried changing the _id to a string when using "type" or objectId when "bsonType". No matter what combination I try when I use the mutation it does what it is supposed to and adds the note into the lead, but the return payload always displays null. I need it to return the _id and note so that it will update the InMemoryCache in Apollo on the front end.

Body:
Hi Bernard – There is an unfortunate bug in the custom resolver form UI at the moment which doesn't allow you to only use bsonType in the input/payload types – we are working on addressing this.  In actually you should be able to use either type/bsonType or a mix of the two as long as they agree with your data.  I think that the payload type definition you want is likely:

{
  "type": "object",
  "title": "AddNoteToLeadPayload",
  "properties": {
    "_id": {
      "bsonType": "objectId"
    },
    "notes": {
      "type": "array",
      "items": {
        "type": "object",
        "properties": {
          "createdAt": {
            "bsonType": "date"
          },
          "createdBy": {
            "type": "string"
          },
          "text": {
            "type": "string"
          }
        }
      }
    }
  }
}

If that doesn't work, it might be helpful to give us a sample of the data that you would like returned.


问:
Multicolumn Model for QCompleter
I'm trying to work with QCompleter for autocompletion on a QComboBox. The two pictures below show the populated combobox(left) and a QCompleter on the column 1 (right).

This example works fine as long as the model columns for the QComboBox and QCompleter are the same. But it would be much more intuitive for this example for QCompleter to use column 0 (city/state), but still have QComboBox use column 1 (airport code). Here is the code:

```<code>from PyQt5.QtCore import pyqtSlot, QObject
from PyQt5.QtWidgets import (QApplication, QMainWindow, QComboBox,
                             QCompleter, QTableView, QLabel)
from PyQt5.QtSql import (QSqlQuery, QSqlQueryModel, QSqlDatabase)
import sys
import sqlite3

class MainWindow(QMainWindow):
    def __init__(self, parent=None):
        super(MainWindow, self).__init__()

        self.setGeometry(300, 300, 400, 300)

        fid = open('example.db', 'w')
        fid.close()

        db = QSqlDatabase.addDatabase("QSQLITE")
        db.setDatabaseName('example.db')
        db.open()
        query = QSqlQuery(db)

        query.exec_('CREATE TABLE "airports" ("city" TEXT, "code" TEXT)')

        airports = [('Aberdeen, SD','ABR'), ('Abilene, TX','ABI'),
                    ('Adak Island, AK','ADK'), ('Akiachak, AK','KKI'),
                    ('Akiak, AK','AKI'), ('Akron/Canton, OH','CAK'),
                    ('Akuton, AK','KQA'), ('Alakanuk, AK','AUK'),
                    ('Alamogordo, NM','ALM'), ('Alamosa, CO','ALS'),
                    ('Albany, NY','ALB'), ('Albuquerque, NM','ABQ')]
        for item in airports:
            sql = 'INSERT INTO airports(city, code) VALUES(?, ?)'
            query.prepare(sql)
            query.addBindValue(item[0])
            query.addBindValue(item[1])
            query.exec_()

        query.exec_('SELECT * FROM airports')

        model =  QSqlQueryModel()
        model.setQuery(query)

        self.cb = QComboBox(parent = self)
        self.cb.setModel(model)
        self.cb.setModelColumn(1)
        self.cb.setView(QTableView(self.cb))
        self.cb.setGeometry(50,50, 250, 50)
        self.cb.currentIndexChanged.connect(self.indexer)

        self.label = QLabel(parent = self)
        self.label.setGeometry(20,200, 250, 50)

        self.cb.view().setMinimumWidth(500)
        self.cb.setEditable(True)

        self.completer = QCompleter()
        self.completer.setCaseSensitivity(False)
        self.cb.setCompleter(self.completer)
        self.completer.setModel(model)
        self.completer.setCompletionColumn(1)
        self.completer.setPopup(QTableView())
        self.completer.popup().setMinimumWidth(500)
        self.completer.popup().setMinimumHeight(500)

        self.completer.activated.connect(self.activatedHandler)

    @pyqtSlot(QObject)
    def activatedHandler(self, arg):
        pass

    def indexer(self, idx):
        self.label.setText('%d' % idx)

app = QApplication(sys.argv)
main = MainWindow(None)
main.show()
sys.exit(app.exec_())
</code>```

If I change the QCompleter to use column zero, i.e.

```<code>self.completer.setCompletionColumn(0)
</code>```

then the correct combobox row is selected after the completer does it's thing, but the displayed text is the city/state and not the aiport code(below left and middle). Further if the user presses enter then the combobox tries to use the text to select a row, but cannot find it and resets combobox row to -1. (below right). Is there any way to change this behavior so that the desired text (airport code) is shown in the combobox?

答:
By default the QCompleter uses the text of the model completionColumn to do the search and the autocomplete, so therefore there are conflicts, a possible solution is to override the pathFromIndex method and return the appropriate text

```<code>class CustomCompleter(QCompleter):
    def pathFromIndex(self, index):
        sibling_index = index.sibling(index.row(), 1)
        return super().pathFromIndex(sibling_index)
</code>```

```<code>self.completer = CustomCompleter()
</code>```

I can't reproduce the second issue so I'll wait for OP feedback.

Title: Multicolumn Model for QCompleter

Body:
I'm trying to work with QCompleter for autocompletion on a QComboBox. The two pictures below show the populated combobox(left) and a QCompleter on the column 1 (right).

This example works fine as long as the model columns for the QComboBox and QCompleter are the same. But it would be much more intuitive for this example for QCompleter to use column 0 (city/state), but still have QComboBox use column 1 (airport code). Here is the code:

from PyQt5.QtCore import pyqtSlot, QObject
from PyQt5.QtWidgets import (QApplication, QMainWindow, QComboBox,
                             QCompleter, QTableView, QLabel)
from PyQt5.QtSql import (QSqlQuery, QSqlQueryModel, QSqlDatabase)
import sys
import sqlite3

class MainWindow(QMainWindow):
    def __init__(self, parent=None):
        super(MainWindow, self).__init__()

        self.setGeometry(300, 300, 400, 300)

        fid = open('example.db', 'w')
        fid.close()

        db = QSqlDatabase.addDatabase("QSQLITE")
        db.setDatabaseName('example.db')
        db.open()
        query = QSqlQuery(db)

        query.exec_('CREATE TABLE "airports" ("city" TEXT, "code" TEXT)')

        airports = [('Aberdeen, SD','ABR'), ('Abilene, TX','ABI'),
                    ('Adak Island, AK','ADK'), ('Akiachak, AK','KKI'),
                    ('Akiak, AK','AKI'), ('Akron/Canton, OH','CAK'),
                    ('Akuton, AK','KQA'), ('Alakanuk, AK','AUK'),
                    ('Alamogordo, NM','ALM'), ('Alamosa, CO','ALS'),
                    ('Albany, NY','ALB'), ('Albuquerque, NM','ABQ')]
        for item in airports:
            sql = 'INSERT INTO airports(city, code) VALUES(?, ?)'
            query.prepare(sql)
            query.addBindValue(item[0])
            query.addBindValue(item[1])
            query.exec_()

        query.exec_('SELECT * FROM airports')

        model =  QSqlQueryModel()
        model.setQuery(query)

        self.cb = QComboBox(parent = self)
        self.cb.setModel(model)
        self.cb.setModelColumn(1)
        self.cb.setView(QTableView(self.cb))
        self.cb.setGeometry(50,50, 250, 50)
        self.cb.currentIndexChanged.connect(self.indexer)

        self.label = QLabel(parent = self)
        self.label.setGeometry(20,200, 250, 50)

        self.cb.view().setMinimumWidth(500)
        self.cb.setEditable(True)

        self.completer = QCompleter()
        self.completer.setCaseSensitivity(False)
        self.cb.setCompleter(self.completer)
        self.completer.setModel(model)
        self.completer.setCompletionColumn(1)
        self.completer.setPopup(QTableView())
        self.completer.popup().setMinimumWidth(500)
        self.completer.popup().setMinimumHeight(500)

        self.completer.activated.connect(self.activatedHandler)

    @pyqtSlot(QObject)
    def activatedHandler(self, arg):
        pass

    def indexer(self, idx):
        self.label.setText('%d' % idx)

app = QApplication(sys.argv)
main = MainWindow(None)
main.show()
sys.exit(app.exec_())

If I change the QCompleter to use column zero, i.e.

self.completer.setCompletionColumn(0)

then the correct combobox row is selected after the completer does it's thing, but the displayed text is the city/state and not the aiport code(below left and middle). Further if the user presses enter then the combobox tries to use the text to select a row, but cannot find it and resets combobox row to -1. (below right). Is there any way to change this behavior so that the desired text (airport code) is shown in the combobox?

Body:
By default the QCompleter uses the text of the model completionColumn to do the search and the autocomplete, so therefore there are conflicts, a possible solution is to override the pathFromIndex method and return the appropriate text

class CustomCompleter(QCompleter):
    def pathFromIndex(self, index):
        sibling_index = index.sibling(index.row(), 1)
        return super().pathFromIndex(sibling_index)

self.completer = CustomCompleter()

I can't reproduce the second issue so I'll wait for OP feedback.


问:
CSS Media Query using multiple using the and logical operator not working as expected
I have added the following media query to my code:

```<code>@media screen and (min-width: 700px) and (max-width: 800px){
    body {
        margin: 50px;
    }

    body, p {
        font-size: 1.6rem;
        font-size: 16px;
    }

    #title {
        font-size: 4rem;
        font-size: 40px;
    }
}
</code>```

However, when displaying the page in a macBook 13, which has a screen bigger than the max-width of 800px, the styling is still following the media query above instead of the code outside of the media query.

Here's the link to the GitHub repo with the full HTML and CSS code:
MVP survey-form repo

It's a single page project.

Thanks.

答:
Media Queries are very sensitive to size changes and differences. So one possible solution is to type in media queries for all devices instead of just one. This allows you to make the program more responsive to size changes and makes the program not confuse the different sizes that the user may have.

I like to use this site for media queries to account for all screen resolutions and sizes:
https://responsivedesign.is/develop/browser-feature-support/media-queries-for-common-device-breakpoints/

Also, be sure to put <meta name="viewport" content="width=device-width, initial-scale=1.0"> in your  tags to make it even more repsonsive.

Body:
I have added the following media query to my code:

@media screen and (min-width: 700px) and (max-width: 800px){
    body {
        margin: 50px;
    }

    body, p {
        font-size: 1.6rem;
        font-size: 16px;
    }

    #title {
        font-size: 4rem;
        font-size: 40px;
    }
}

However, when displaying the page in a macBook 13, which has a screen bigger than the max-width of 800px, the styling is still following the media query above instead of the code outside of the media query.

Here's the link to the GitHub repo with the full HTML and CSS code:
MVP survey-form repo

It's a single page project.

Thanks.

Body:
Media Queries are very sensitive to size changes and differences. So one possible solution is to type in media queries for all devices instead of just one. This allows you to make the program more responsive to size changes and makes the program not confuse the different sizes that the user may have.

I like to use this site for media queries to account for all screen resolutions and sizes:
https://responsivedesign.is/develop/browser-feature-support/media-queries-for-common-device-breakpoints/

Also, be sure to put <meta name="viewport" content="width=device-width, initial-scale=1.0"> in your <head> tags to make it even more repsonsive.


问:
Nginx random variables
Good morning programmers,
I'm trying to create random variables on nginx, (I have OpenResty nginx+lua).
Here is an example of a static variable:

```<code>set $teste 123;
</code>```

So is it possible to turn this static variable random?

答:
You need to provide random seed, otherwise you'll get the same values each time the server is restarted.

There I use resty.random.bytes (that internally uses  RAND_pseudo_bytes or RAND_bytes from OpenSSL) to provide <s>cryptographically strong</s> pseudo-random seed on nginx worker start.

UPD: You should use resty_random.bytes(n, true) for really cryptographically strong pseudo-random value. If the second argument is true, RAND_bytes will be used instead of RAND_pseudo_byte. But in this case you'll have to deal with possible exhaustion of the entropy pool. That is, resty_random.bytes(n, true) could return nil if there is no enough randomness to ensure an unpredictable byte sequence.

```<code>http {

    init_worker_by_lua_block {
        local resty_random = require('resty.random')
        -- use random byte (0..255 int) as a seed
        local seed = string.byte(resty_random.bytes(1))
        math.randomseed(seed)
    }

    server {
        listen 8888;

        location = / {
            set_by_lua_block $random {
                return math.random(1, 100)
            }

            echo "random number: $random";

        }
    }
}
</code>```

Title: Nginx random variables

Body:
Good morning programmers,
I'm trying to create random variables on nginx, (I have OpenResty nginx+lua).
Here is an example of a static variable:

set $teste 123;

So is it possible to turn this static variable random?

Body:
You need to provide random seed, otherwise you'll get the same values each time the server is restarted.

There I use resty.random.bytes (that internally uses  RAND_pseudo_bytes or RAND_bytes from OpenSSL) to provide <s>cryptographically strong</s> pseudo-random seed on nginx worker start.

UPD: You should use resty_random.bytes(n, true) for really cryptographically strong pseudo-random value. If the second argument is true, RAND_bytes will be used instead of RAND_pseudo_byte. But in this case you'll have to deal with possible exhaustion of the entropy pool. That is, resty_random.bytes(n, true) could return nil if there is no enough randomness to ensure an unpredictable byte sequence.

http {

    init_worker_by_lua_block {
        local resty_random = require('resty.random')
        -- use random byte (0..255 int) as a seed
        local seed = string.byte(resty_random.bytes(1))
        math.randomseed(seed)
    }

    server {
        listen 8888;

        location = / {
            set_by_lua_block $random {
                return math.random(1, 100)
            }

            echo "random number: $random";

        }
    }
}


问:
Order by match on multiple columns (and with mutiple conditions)
My issue is I want to order by match on a specific search string.

This is the logic:

If the  title, author or  isbn are the same as search, show these books first

If the  title, author or  isbn are the like  %search, show these books second

If the  title, author or  isbn are the like search%, show these books third

I'm using SQLAlchemy, Flask and PostgreSQL

This is the code:

```<code>#keep an unformatted version of search, to be able to order
    unformattedSearch = search
    search = "%" + search + "%"

    result = db.execute("SELECT title, author, isbn FROM books WHERE \
        LOWER(title) LIKE LOWER(:search) OR \
        LOWER(isbn) LIKE LOWER(:search) OR \
        LOWER(author) LIKE LOWER(:search) \
        ORDER BY \
        CASE \
            WHEN title = :search THEN 0 \
            WHEN author = :search THEN 1 \
            WHEN isbn = :search THEN 2 \
            \
            WHEN title LIKE string_agg(:unformattedSearch,'%') THEN 3\
            WHEN author LIKE string_agg(:unformattedSearch,'%') THEN 4 \
            WHEN isbn LIKE string_agg(:unformattedSearch,'%') THEN 5 \
            \
            WHEN title LIKE string_agg('%',:unformattedSearch) THEN 6 \
            WHEN author LIKE string_agg('%',:unformattedSearch) THEN 7 \
            WHEN isbn  LIKE string_agg('%',:unformattedSearch) THEN 8 \
        ELSE 9 \
        END",
        {"search": search, "unformattedSearch": unformattedSearch}).fetchall()
</code>```

This is the error I'm getting:

column "books.title" must appear in the GROUP BY clause or be used in
  an aggregate function

答:
You are mixing string aggregation (which is what string_agg() does) and string concatenation (which is what you want). So Postgres understands your query  as an aggregation one, and bad things happen. You can use || to concatenate strings.

Also, you should fix your where clause so it really does pattern matching (as of now, it is looking for exact matches on the parameter) - ilike comes handy to avoid lower() on both operands.

Finally, you can use booleans in the order by clause so shorten the query.

```<code>select title, author, isbn
from books
where
       title  ilike '%' || :search || '%'
    or isbn   ilike '%' || :search || '%'
    or author ilike '%' || :search || '%'
order by
    (title  = :search) desc,
    (author = :search) desc,
    (isbn   = :search) desc,
    (title  ilike :search || '%') desc,
    (author ilike :search || '%') desc,
    (isbn   ilike :search || '%') desc,
    (title  ilike '%' || :search) desc,
    (author ilike '%' || :search) desc,
    (isbn   ilike '%' || :search) desc
</code>```

Body:
My issue is I want to order by match on a specific search string.

This is the logic:

If the  title, author or  isbn are the same as search, show these books first

If the  title, author or  isbn are the like  %search, show these books second

If the  title, author or  isbn are the like search%, show these books third

I'm using SQLAlchemy, Flask and PostgreSQL

This is the code:

#keep an unformatted version of search, to be able to order
    unformattedSearch = search
    search = "%" + search + "%"

    result = db.execute("SELECT title, author, isbn FROM books WHERE \
        LOWER(title) LIKE LOWER(:search) OR \
        LOWER(isbn) LIKE LOWER(:search) OR \
        LOWER(author) LIKE LOWER(:search) \
        ORDER BY \
        CASE \
            WHEN title = :search THEN 0 \
            WHEN author = :search THEN 1 \
            WHEN isbn = :search THEN 2 \
            \
            WHEN title LIKE string_agg(:unformattedSearch,'%') THEN 3\
            WHEN author LIKE string_agg(:unformattedSearch,'%') THEN 4 \
            WHEN isbn LIKE string_agg(:unformattedSearch,'%') THEN 5 \
            \
            WHEN title LIKE string_agg('%',:unformattedSearch) THEN 6 \
            WHEN author LIKE string_agg('%',:unformattedSearch) THEN 7 \
            WHEN isbn  LIKE string_agg('%',:unformattedSearch) THEN 8 \
        ELSE 9 \
        END",
        {"search": search, "unformattedSearch": unformattedSearch}).fetchall()

This is the error I'm getting:

column "books.title" must appear in the GROUP BY clause or be used in
  an aggregate function

Body:
You are mixing string aggregation (which is what string_agg() does) and string concatenation (which is what you want). So Postgres understands your query  as an aggregation one, and bad things happen. You can use || to concatenate strings.

Also, you should fix your where clause so it really does pattern matching (as of now, it is looking for exact matches on the parameter) - ilike comes handy to avoid lower() on both operands.

Finally, you can use booleans in the order by clause so shorten the query.

select title, author, isbn
from books
where
       title  ilike '%' || :search || '%'
    or isbn   ilike '%' || :search || '%'
    or author ilike '%' || :search || '%'
order by
    (title  = :search) desc,
    (author = :search) desc,
    (isbn   = :search) desc,
    (title  ilike :search || '%') desc,
    (author ilike :search || '%') desc,
    (isbn   ilike :search || '%') desc,
    (title  ilike '%' || :search) desc,
    (author ilike '%' || :search) desc,
    (isbn   ilike '%' || :search) desc