问:
How to load from database with condition
I am new to programming and I have my hands on a web app from a company and tried to mess around and do some changes. The app was built with PHP, MySQL, and CodeIgniter, as I was told, and it's used from the company to manage orders.

When a user wants to see the orders he clicks on the specified button and the app loads all the orders from the database, but because there are more than 10.000 orders it's slow at load. So, I want to add an option where the first load happens to get only the orders of the last 6 months and if the user wants to view older orders then I should add a button or something similar and load the rest.

<?php
 $count=1;
 $this->db->order_by("order_number", "desc");
 $completed_orders=$this->db->get_where('orders' , array(
                                        'order_status' => 'completed',
                                        'category' => 'mesoportes'
                                        ))->result_array();
 foreach ($completed_orders as $row):
?>
```

Any idea how i may do that.

答:
What are you trying to achieve is the perfect definition to apply pagination. Pagination will help your app split the database data into individual pages, which is an efficient method of showing a large number of records in a small space. However, you want to apply a huge chuck data query. Six months is a long time and you can get many orders in that period.

What can I do?

First, I will try to solve it using your original idea. To that end, you just need to create a new get_completed_orders() function that receives two parameters $start_date, and  $end_date. There parameters should be added to the get_where. I guessing the name of your date is order_datetime and compare it with the previous parameters.

$start_date = '2018-11-01';
$end_date = '2019-05-31';
$completed_orders = get_completed_orders($start_date, $end_date);

function get_completed_orders($start_date, $end_date){
    return $this->db->get_where(
        'orders',
        array(
            'order_status' => 'completed',
            'category' => 'mesoportes',
            'order_datetime >=' => $start_date,
            'order_datetime <' => $end_date
        )
    )->order_by('order_number', 'desc')->result_array();
}
```

<p>That approach will bring all the completed orders between the two dates. Yeah, but that is still not effective for a mobile application or a web application. Specially for a user interface. <strong>Then, how can I make it more efficient?</strong> Well, if you open your gmail, you will get the last 20 emails, and the using pagination will you move back and forwards according your needs. They don't show you thousandth of emails from the last six months, right? So, if we follow that idea we can all add a <code>$limit</code>, and <code>$offset</code> to the <code>get_completed_orders()</code> to create a pagination like approach. </p>

<pre class="lang-php prettyprint-override"><code>$start_date = '2018-11-01';
$end_date = '2019-05-31';
$limit = 20; // max number of orders
$offset = $prev_offset + $limit; // where is gonna to start
$completed_orders = get_completed_orders($start_date, $end_date, $limit, $offset);
$prev_offset = $offset;

// Function implementation
function get_completed_orders($start_date, $end_date, $limit, $offset) {
    return $this->db->get_where(
        'orders',
        array(
            'order_status' => 'completed',
            'category' => 'mesoportes',
            'order_datetime >=' => $start_date,
            'order_datetime <' => $end_date
        ),
        $limit,
        $offset
    )->order_by('order_number', 'desc')->result_array();
}
</code>```

Now, your interface will receive only 20 completed orders for each page. So you need to modify your interface to support this new feature.

Body:
I am new to programming and I have my hands on a web app from a company and tried to mess around and do some changes. The app was built with PHP, MySQL, and CodeIgniter, as I was told, and it's used from the company to manage orders.

When a user wants to see the orders he clicks on the specified button and the app loads all the orders from the database, but because there are more than 10.000 orders it's slow at load. So, I want to add an option where the first load happens to get only the orders of the last 6 months and if the user wants to view older orders then I should add a button or something similar and load the rest.

<?php
 $count=1;
 $this->db->order_by("order_number", "desc");
 $completed_orders=$this->db->get_where('orders' , array(
                                        'order_status' => 'completed',
                                        'category' => 'mesoportes'
                                        ))->result_array();
 foreach ($completed_orders as $row):
?>

Any idea how i may do that.

Body:
What are you trying to achieve is the perfect definition to apply pagination. Pagination will help your app split the database data into individual pages, which is an efficient method of showing a large number of records in a small space. However, you want to apply a huge chuck data query. Six months is a long time and you can get many orders in that period.

What can I do?

First, I will try to solve it using your original idea. To that end, you just need to create a new get_completed_orders() function that receives two parameters $start_date, and  $end_date. There parameters should be added to the get_where. I guessing the name of your date is order_datetime and compare it with the previous parameters.

$start_date = '2018-11-01';
$end_date = '2019-05-31';
$completed_orders = get_completed_orders($start_date, $end_date);

function get_completed_orders($start_date, $end_date){
    return $this->db->get_where(
        'orders',
        array(
            'order_status' => 'completed',
            'category' => 'mesoportes',
            'order_datetime >=' => $start_date,
            'order_datetime <' => $end_date
        )
    )->order_by('order_number', 'desc')->result_array();
}

That approach will bring all the completed orders between the two dates. Yeah, but that is still not effective for a mobile application or a web application. Specially for a user interface. Then, how can I make it more efficient? Well, if you open your gmail, you will get the last 20 emails, and the using pagination will you move back and forwards according your needs. They don't show you thousandth of emails from the last six months, right? So, if we follow that idea we can all add a $limit, and $offset to the get_completed_orders() to create a pagination like approach.

$start_date = '2018-11-01';
$end_date = '2019-05-31';
$limit = 20; // max number of orders
$offset = $prev_offset + $limit; // where is gonna to start
$completed_orders = get_completed_orders($start_date, $end_date, $limit, $offset);
$prev_offset = $offset;

// Function implementation
function get_completed_orders($start_date, $end_date, $limit, $offset) {
    return $this->db->get_where(
        'orders',
        array(
            'order_status' => 'completed',
            'category' => 'mesoportes',
            'order_datetime >=' => $start_date,
            'order_datetime <' => $end_date
        ),
        $limit,
        $offset
    )->order_by('order_number', 'desc')->result_array();
}

Now, your interface will receive only 20 completed orders for each page. So you need to modify your interface to support this new feature.


来源: stackexchange

问:
Join strings by space using pandas aggregate function
I have a CSV file that contains rows with some similar id's. I found a nice approach doing this with dataframe and I found the code doing this from [this] 1 post.

Sample CSV file:

```<code>    id               messages
0   11  I am not driving home
1   11      Please pick me up
2   11     I don't have money
3  103   The car already park
4  103     No need for ticket
5  104       I will buy a car
6  104       I will buy a car
</code>```

Desired output is:

Sample CSV file:

```<code>id   messages
011   I am not driving home Please pick me up I don't have money
103   The car already park No need for ticket
104   I will buy a car
</code>```

Now the code that I have so far is:

aggregation_functions = {'message':'sum'}
df_new = df.groupby(df['id']).aggregate(aggregation_functions)

```
<p>Now what I am getting with this code is:</p>
```id   messages
011   I am not driving homePlease pick me upI don't have money
103   The car already parkNo need for ticket
104   I will buy a car
```
<p>I just want to have the space between words (eg. "homePlease" > "home Please") and avoid redundancy such as having two times of <code>I will buy a car</code>.</p>
<p>I already checked the post 2 but I couldn't find my answer.</p>
<p>Also do i need to use <code>.reindex(columns=df.columns)</code> after the <code>aggregate(aggregation_functions)</code></p>
<p>Like:</p>
```df_new = df.groupby(df['id']).aggregate(aggregation_functions).reindex(columns=df.columns)
```

答:
So it will be drop_duplicates first , the agg join

```<code>df.drop_duplicates().groupby('id',as_index=False).messages.agg(' '.join)
</code>```

ContentLicense: CC BY-SA 4.0

Body:
I have a CSV file that contains rows with some similar id's. I found a nice approach doing this with dataframe and I found the code doing this from [this] 1 post.

Sample CSV file:

    id               messages
0   11  I am not driving home
1   11      Please pick me up
2   11     I don't have money
3  103   The car already park
4  103     No need for ticket
5  104       I will buy a car
6  104       I will buy a car

Desired output is:

Sample CSV file:

id   messages
011   I am not driving home Please pick me up I don't have money
103   The car already park No need for ticket
104   I will buy a car

Now the code that I have so far is:

aggregation_functions = {'message':'sum'}
df_new = df.groupby(df['id']).aggregate(aggregation_functions)

Now what I am getting with this code is:

id   messages
011   I am not driving homePlease pick me upI don't have money
103   The car already parkNo need for ticket
104   I will buy a car

I just want to have the space between words (eg. "homePlease" > "home Please") and avoid redundancy such as having two times of I will buy a car.

I already checked the post 2 but I couldn't find my answer.

Also do i need to use .reindex(columns=df.columns) after the aggregate(aggregation_functions)

Like:

df_new = df.groupby(df['id']).aggregate(aggregation_functions).reindex(columns=df.columns)

Body:
So it will be drop_duplicates first , the agg join

df.drop_duplicates().groupby('id',as_index=False).messages.agg(' '.join)


问:
Unexpected end of JSON input in MongoDB Compass
I want to import data of type JSON in MongoDB compass,
the import function gives this error
" unexpected end of JSON input "

there is a some of my JSON file

[
   {
      "id":4,
      "user":"test@example.com",
      "date1":"2019-03-01",
      "date2":"2019-04-01",
      "statut":"Good",
      "guest_number":4
   }
]
```

答:
You can also use the command line of mongodb like this :</p>

```<code>db.user.insert(
[
    {
     "id" : 4,
     "user" : "test@example.com",
     "date1" : "2019-03-01",
     "date2" : "2019-04-01",
     "statut" : "Good",
     "guest_number" : 4
    },
    {
     "id" : 5,
     "user" : "test2@example.com",
     "date1" : "2019-03-01",
     "date2" : "2019-04-01",
     "statut" : "Good",
     "guest_number" : 4
    }
]
</code>```

Body:
You can also use the command line of mongodb like this :

db.user.insert(
[
    {
     "id" : 4,
     "user" : "test@example.com",
     "date1" : "2019-03-01",
     "date2" : "2019-04-01",
     "statut" : "Good",
     "guest_number" : 4
    },
    {
     "id" : 5,
     "user" : "test2@example.com",
     "date1" : "2019-03-01",
     "date2" : "2019-04-01",
     "statut" : "Good",
     "guest_number" : 4
    }
]


问:
How can i combine an array of objects into another array of objects while also combining the common keys
I'm trying sort an array of objects into another array of objects but also combining the common keys (in this case the key updatedAt)

Example:

```<code>const arr = [
     { id: '5c65ded933767500010c22a6',
       createdAt: '2019-02-14T21:34:17.181Z',
       updatedAt: '2019-02-14T21:38:01.251Z',
       userId: '5b213937cdcd57002d128aa5',
       phoneNumber: '(514) 578-9586',
       orderId: '5c65ded346e0fb000698f102',
       paymentMethods: [],
       shopName: 'test1',
       amount: 3.47,
       type: 'CASHBACK',
       status: 'COMPLETED',
       currency: 'CAD' },
     { id: '5c5226777de2c4000139de58',
       createdAt: '2019-01-30T22:34:31.648Z',
       updatedAt: '2019-01-30T22:37:01.246Z',
       userId: '5b213937cdcd57002d128aa5',
       phoneNumber: '(514) 578-9586',
       orderId: '5c52267146e0fb0006dc852a',
       paymentMethods: [],
       shopName: 'test2',
       amount: 0.24,
       type: 'CASHBACK',
       status: 'COMPLETED',
       currency: 'CAD' },
     { id: '5c019c07c9e77c0001c5ceb8',
       createdAt: '2018-11-30T20:22:31.392Z',
       updatedAt: '2019-01-17T15:53:24.410Z',
       userId: '5b213937cdcd57002d128aa5',
       phoneNumber: null,
       orderId: '5c019bfcc9e77c0006ba4f77',
       paymentMethods: [],
       shopName: 'test3',
       amount: 1.12,
       type: 'CASHBACK',
       status: 'COMPLETED',
       currency: 'CAD' },
     { id: '5c0195cac9e77c0001c5ceb5',
       createdAt: '2018-11-30T19:55:54.646Z',
       updatedAt: '2019-01-17T15:53:12.624Z',
       userId: '5b213937cdcd57002d128aa5',
       phoneNumber: null,
       orderId: '5c0195bfc9e77c0006b3873f',
       paymentMethods: [],
       shopName: 'test4',
       amount: 1.15,
       type: 'CASHBACK',
       status: 'COMPLETED',
       currency: 'CAD' } ]
</code>```

into:

```<code>[
  {
    date: '2019-01-30T22:37:01.246Z',
    transactions: [
     {'...THE TRANSACTIONS THAT OCURED ON THE SAME DATE...'},
     {'...THE TRANSACTIONS THAT OCURED ON THE SAME DATE...'},
     {'...THE TRANSACTIONS THAT OCURED ON THE SAME DATE...'},
    ]
  },
  {
    date: '2019-01-14T22:37:01.246Z',
    transactions: [
     {'...THE TRANSACTIONS THAT OCURED ON THE SAME DATE...'},
     {'...THE TRANSACTIONS THAT OCURED ON THE SAME DATE...'},
     {'...THE TRANSACTIONS THAT OCURED ON THE SAME DATE...'},
    ]
  }
]
</code>```

I've tried using multiple loops but it just seems inefficient so i later tried using lodash and that also seems ineficient

here is my attempt using lodash

```<code>const mapDaysToTransactions = (transactions) => {
  const mappedTransactions = transactions.reduce((acc, next) => {
  return acc.concat({
    day: next.updatedAt,
    transactions: next
  })
}, [])
const groupedBydays = _.groupBy(mappedTransactions, el => moment(el.day).format('MMMM, d'))
  return Object.keys(groupedBydays).map(d => {
    return {
      date: groupedBydays[d][0].day,
      transactions: _.flattenDeep(groupedBydays[d])
    }
  })
}

</code>```

I get the expected result with the function above but i want to know if there is a 'better' more optimal way to go about a situation like this.

UPDATE: Another solution using a single reduce

```<code>const mapDaysToTransactions = (transactions) => {

  const mapped = transactions.reduce((acc, next) => {
  return acc.concat({
    day: next.updatedAt,
    transactions: next
  })
  }, [])

  return mapped.reduce((acc, transaction) => {
    const date = moment(transaction.day).format('MMMM, d');
    const iso = transaction.day
    const index = acc.findIndex(t => t.date === date);
    const idx = acc.indexOf(date)
  if (idx !== -1) {
    const transactionsByDate = acc[idx];
    const newAcc = [
      ...acc.slice(0, idx),
      ...acc.slice(idx + 1, acc.length),
    ]
    return newAcc.concat({
      date,
      day: iso,
      transactions: transactionsByDate.transactions.concat(transaction),
    });
  }

  return acc.concat({
    date,
    day: iso,
    transactions: [transaction],
  });
 }, []);
}

</code>```

答:
In reduce you're creating a new array first instead you can use object and group values based on date and than create an array

const arr = [{ id: '5c65ded933767500010c22a6',createdAt: '2019-02-14T21:34:17.181Z',updatedAt: '2019-02-14T21:38:01.251Z',userId: '5b213937cdcd57002d128aa5',phoneNumber: '(514) 578-9586',orderId: '5c65ded346e0fb000698f102',paymentMethods: [],shopName: 'test1',amount: 3.47,type: 'CASHBACK',status: 'COMPLETED',currency: 'CAD' },{ id: '5c5226777de2c4000139de58',createdAt: '2019-01-30T22:34:31.648Z',updatedAt: '2019-01-30T22:37:01.246Z',userId: '5b213937cdcd57002d128aa5',phoneNumber: '(514) 578-9586',orderId: '5c52267146e0fb0006dc852a',paymentMethods: [],shopName: 'test2',amount: 0.24,type: 'CASHBACK',status: 'COMPLETED',currency: 'CAD' },{ id: '5c019c07c9e77c0001c5ceb8',createdAt: '2018-11-30T20:22:31.392Z',updatedAt: '2019-01-17T15:53:24.410Z',userId: '5b213937cdcd57002d128aa5',phoneNumber: null,orderId: '5c019bfcc9e77c0006ba4f77',paymentMethods: [],shopName: 'test3',amount: 1.12,type: 'CASHBACK',status: 'COMPLETED',currency: 'CAD' },{ id: '5c0195cac9e77c0001c5ceb5',createdAt: '2018-11-30T19:55:54.646Z',updatedAt: '2019-01-17T15:53:12.624Z',userId: '5b213937cdcd57002d128aa5',phoneNumber: null,orderId: '5c0195bfc9e77c0006b3873f',paymentMethods: [],shopName: 'test4',amount: 1.15,type: 'CASHBACK',status: 'COMPLETED',currency: 'CAD' } ]

let final = arr.reduce((op,inp) => {
  let date = inp.updatedAt.substr(0,10)
  op[date] = op[date] || {date, transaction:[]}
  op[date].transaction.push(inp)
  return op
},{})

console.log(Object.values(final))```

Body:
I'm trying sort an array of objects into another array of objects but also combining the common keys (in this case the key updatedAt)

Example:

const arr = [
     { id: '5c65ded933767500010c22a6',
       createdAt: '2019-02-14T21:34:17.181Z',
       updatedAt: '2019-02-14T21:38:01.251Z',
       userId: '5b213937cdcd57002d128aa5',
       phoneNumber: '(514) 578-9586',
       orderId: '5c65ded346e0fb000698f102',
       paymentMethods: [],
       shopName: 'test1',
       amount: 3.47,
       type: 'CASHBACK',
       status: 'COMPLETED',
       currency: 'CAD' },
     { id: '5c5226777de2c4000139de58',
       createdAt: '2019-01-30T22:34:31.648Z',
       updatedAt: '2019-01-30T22:37:01.246Z',
       userId: '5b213937cdcd57002d128aa5',
       phoneNumber: '(514) 578-9586',
       orderId: '5c52267146e0fb0006dc852a',
       paymentMethods: [],
       shopName: 'test2',
       amount: 0.24,
       type: 'CASHBACK',
       status: 'COMPLETED',
       currency: 'CAD' },
     { id: '5c019c07c9e77c0001c5ceb8',
       createdAt: '2018-11-30T20:22:31.392Z',
       updatedAt: '2019-01-17T15:53:24.410Z',
       userId: '5b213937cdcd57002d128aa5',
       phoneNumber: null,
       orderId: '5c019bfcc9e77c0006ba4f77',
       paymentMethods: [],
       shopName: 'test3',
       amount: 1.12,
       type: 'CASHBACK',
       status: 'COMPLETED',
       currency: 'CAD' },
     { id: '5c0195cac9e77c0001c5ceb5',
       createdAt: '2018-11-30T19:55:54.646Z',
       updatedAt: '2019-01-17T15:53:12.624Z',
       userId: '5b213937cdcd57002d128aa5',
       phoneNumber: null,
       orderId: '5c0195bfc9e77c0006b3873f',
       paymentMethods: [],
       shopName: 'test4',
       amount: 1.15,
       type: 'CASHBACK',
       status: 'COMPLETED',
       currency: 'CAD' } ]

into:

[
  {
    date: '2019-01-30T22:37:01.246Z',
    transactions: [
     {'...THE TRANSACTIONS THAT OCURED ON THE SAME DATE...'},
     {'...THE TRANSACTIONS THAT OCURED ON THE SAME DATE...'},
     {'...THE TRANSACTIONS THAT OCURED ON THE SAME DATE...'},
    ]
  },
  {
    date: '2019-01-14T22:37:01.246Z',
    transactions: [
     {'...THE TRANSACTIONS THAT OCURED ON THE SAME DATE...'},
     {'...THE TRANSACTIONS THAT OCURED ON THE SAME DATE...'},
     {'...THE TRANSACTIONS THAT OCURED ON THE SAME DATE...'},
    ]
  }
]

I've tried using multiple loops but it just seems inefficient so i later tried using lodash and that also seems ineficient

here is my attempt using lodash

const mapDaysToTransactions = (transactions) => {
  const mappedTransactions = transactions.reduce((acc, next) => {
  return acc.concat({
    day: next.updatedAt,
    transactions: next
  })
}, [])
const groupedBydays = _.groupBy(mappedTransactions, el => moment(el.day).format('MMMM, d'))
  return Object.keys(groupedBydays).map(d => {
    return {
      date: groupedBydays[d][0].day,
      transactions: _.flattenDeep(groupedBydays[d])
    }
  })
}

I get the expected result with the function above but i want to know if there is a 'better' more optimal way to go about a situation like this.

UPDATE: Another solution using a single reduce

const mapDaysToTransactions = (transactions) => {

  const mapped = transactions.reduce((acc, next) => {
  return acc.concat({
    day: next.updatedAt,
    transactions: next
  })
  }, [])

  return mapped.reduce((acc, transaction) => {
    const date = moment(transaction.day).format('MMMM, d');
    const iso = transaction.day
    const index = acc.findIndex(t => t.date === date);
    const idx = acc.indexOf(date)
  if (idx !== -1) {
    const transactionsByDate = acc[idx];
    const newAcc = [
      ...acc.slice(0, idx),
      ...acc.slice(idx + 1, acc.length),
    ]
    return newAcc.concat({
      date,
      day: iso,
      transactions: transactionsByDate.transactions.concat(transaction),
    });
  }

  return acc.concat({
    date,
    day: iso,
    transactions: [transaction],
  });
 }, []);
}


问:
How to get the average value from the firebase realtime database
My question is about getting the Avg rating from the database, and then updating the average rating every time a row is added.
This is the structure of my database in firebase.

I am trying to retrieve the Average rating of each ID (number like 299536), and update it every time new data/row is added for the same id.
I am using Firebase Realtime Database.
Any help is appreciated. I am using react.js. Should I create an action for this?

答:
You could use a cloud function to do this. Lets use a onCreate listener to average the total each time theres a write.

```<code>export const ratingAvg = functions.database
 .ref("ratings/{userId}/{recordId}")
 .onCreate(async (snapshot, context) => {
 const data = snapshot.val(); // rating obj (user, userPhoto, date, comment?, rating)
 const userId = context.params.userId; // this is your userId
 const transactionId = context.params.transactionId; // the uid of the record

 const profileAvg = await admin
  .database()
  .ref(`ratings/${userId}/`)
  .once("value");

  //' if avgRating exists average with new rating else use new rating.
  const newAvg = profileAvg.val().avgRating
  ? ((profileAvg.val().avgRating + data.rating) / 2).toFixed(2)
  : data.rating;

  // write new average
  return admin
   .database()
   .ref(`ratings/${userId}/`)
   .update({
     avgRating: newAvg
   })
   .then(res => {
     console.log(res);
   })
   .catch(err => {
     console.log(err);
   });
 });
</code>```

Body:
You could use a cloud function to do this. Lets use a onCreate listener to average the total each time theres a write.

export const ratingAvg = functions.database
 .ref("ratings/{userId}/{recordId}")
 .onCreate(async (snapshot, context) => {
 const data = snapshot.val(); // rating obj (user, userPhoto, date, comment?, rating)
 const userId = context.params.userId; // this is your userId
 const transactionId = context.params.transactionId; // the uid of the record

 const profileAvg = await admin
  .database()
  .ref(`ratings/${userId}/`)
  .once("value");

  //' if avgRating exists average with new rating else use new rating.
  const newAvg = profileAvg.val().avgRating
  ? ((profileAvg.val().avgRating + data.rating) / 2).toFixed(2)
  : data.rating;

  // write new average
  return admin
   .database()
   .ref(`ratings/${userId}/`)
   .update({
     avgRating: newAvg
   })
   .then(res => {
     console.log(res);
   })
   .catch(err => {
     console.log(err);
   });
 });


问:
Uncaught SyntaxError: Unexpected identifier with php inside js
I have this code inside php tag which itself is inside a script tag. Why does it give me that error?</p>

```<code>print("document.getElementById(\"userComment\").innerHTML=\"
              <div style=\"background:url('assets/images/userImages/{$row4['image']}') no-repeat; width: 3em; height: 3em; background-position: center; background-size: 210%; border-radius: 50%;\">
              </div>\";");
</code>```

答:
You're getting messed up by quoting problems. This would be a good place to use a here-string, so you don't need to worry about PHP quotes.

And in the JavaScript, use a template literal rather than a double-quoted string. This will allow you to have newlines in the string, and also avoid the problem of nested double quotes.

```<code>echo <<<EOS
document.getElementById("userComment").innerHTML=`
    <div style="background:url('assets/images/userImages/{$row4['image']}') no-repeat; width: 3em; height: 3em; background-position: center; background-size: 210%; border-radius: 50%;">
    </div>`;
EOS ;
</code>```

Or get out of PHP mode into literal output:

```<code>?>
document.getElementById("userComment").innerHTML=`
    <div style="background:url('assets/images/userImages/<?php echo $row4['image']; ?>') no-repeat; width: 3em; height: 3em; background-position: center; background-size: 210%; border-radius: 50%;">
    </div>`;
<?php
</code>```

Body:
I have this code inside php tag which itself is inside a script tag. Why does it give me that error?

print("document.getElementById(\"userComment\").innerHTML=\"

\";");

Body:
You're getting messed up by quoting problems. This would be a good place to use a here-string, so you don't need to worry about PHP quotes.

And in the JavaScript, use a template literal rather than a double-quoted string. This will allow you to have newlines in the string, and also avoid the problem of nested double quotes.

echo <<<EOS
document.getElementById("userComment").innerHTML=`
    <div style="background:url('assets/images/userImages/{$row4['image']}') no-repeat; width: 3em; height: 3em; background-position: center; background-size: 210%; border-radius: 50%;">
    </div>`;
EOS ;

Or get out of PHP mode into literal output:

?>
document.getElementById("userComment").innerHTML=`
    <div style="background:url('assets/images/userImages/<?php echo $row4['image']; ?>') no-repeat; width: 3em; height: 3em; background-position: center; background-size: 210%; border-radius: 50%;">
    </div>`;
<?php


问:
How to combine getElementById with different Id name
It is possible to combine getElementById with different id name? How to achieve it?

function onOpen(){
    var x1 = document.getElementById("header");
    var x2 = document.getElementById("menu");
    var x3 = document.getElementById("program");
    x1.style.filter = "blur(5px)"
    x2.style.filter = "blur(5px)"
    x3.style.filter = "blur(5px)"
}
```

答:
You could use querySelectorAll and than iterate using NodeList.forEach()

function onOpen(){
  const els = document.querySelectorAll("#header, #menu, #program");
  els.forEach(el => el.style.filter = "blur(5px)");
}

onOpen();```
<pre class="snippet-code-html lang-html prettyprint-override"><code><div id="header">TEST</div>
<div id="menu">TEST</div>
<div id="program">TEST</div></code>```

Or if you want to pollute HTML with an extra class, you could use

function onOpen(){
  const els = document.querySelectorAll(".onOpenBlur");
  els.forEach(el => el.style.filter = "blur(5px)");
}

onOpen();```
<pre class="snippet-code-html lang-html prettyprint-override"><code><div class="onOpenBlur" id="header">TEST</div>
<div class="onOpenBlur" id="menu">TEST</div>
<div class="onOpenBlur" id="program">TEST</div></code>```

that way, in the future, all you have to do is add the same class to any number of elements, instead of nesting a new ID into JS...

Pick the one that best fits. Or you can even use both: '#header, #menu, .onOpenBlur'

https://developer.mozilla.org/en-US/docs/Web/API/NodeList/forEach

https://developer.mozilla.org/en-US/docs/Web/API/Document/querySelectorAll

A slightly different approach

Another idea would be to just add a class to body and let CSS do the magic:

function toggleOpen(){
  document.documentElement.classList.toggle('is-open')
}

toggleOpen();```
<pre class="snippet-code-css lang-css prettyprint-override"><code>.is-open .on-open-blur {
  filter: blur(5px);
}</code>```

TEST

TEST

TEST
```

Body:
You could use querySelectorAll and than iterate using NodeList.forEach()

function onOpen(){
  const els = document.querySelectorAll("#header, #menu, #program");
  els.forEach(el => el.style.filter = "blur(5px)");
}

onOpen();

<div id="header">TEST</div>
<div id="menu">TEST</div>
<div id="program">TEST</div>

Or if you want to pollute HTML with an extra class, you could use

function onOpen(){
  const els = document.querySelectorAll(".onOpenBlur");
  els.forEach(el => el.style.filter = "blur(5px)");
}

onOpen();

<div class="onOpenBlur" id="header">TEST</div>
<div class="onOpenBlur" id="menu">TEST</div>
<div class="onOpenBlur" id="program">TEST</div>

that way, in the future, all you have to do is add the same class to any number of elements, instead of nesting a new ID into JS...

Pick the one that best fits. Or you can even use both: '#header, #menu, .onOpenBlur'

https://developer.mozilla.org/en-US/docs/Web/API/NodeList/forEach

https://developer.mozilla.org/en-US/docs/Web/API/Document/querySelectorAll

A slightly different approach

Another idea would be to just add a class to body and let CSS do the magic:

function toggleOpen(){
  document.documentElement.classList.toggle('is-open')
}

toggleOpen();

.is-open .on-open-blur {
  filter: blur(5px);
}

<div class="on-open-blur" id="header">TEST</div>
<div class="on-open-blur" id="menu">TEST</div>
<div class="on-open-blur" id="program">TEST</div>


问:
Gstreamer C Code is failed with streaming stopped, reason not-negotiated (-4)
I am learning Gstreamer and whatever I have achieved through Gstreamer tools, I am trying to implement the same with gstreamer application using C language.

Below command streamed a mp4 video file successfully:
gst-launch-1.0.exe -v filesrc location=file.mp4 ! qtdemux ! h264parse ! avdec_h264 ! videoconvert ! autovideosink

I tried the same with C code and also used the "pad-added" Elements Signals to create pads and linked to the next element i.e. parser (h264parser).

So, it got failed with streaming stopped, reason not-negotiated.

Complete Output:
Now playing: file.mp4
Running...
A new pad video_0 was created for demux
element demux will be linked to parser
Error: Internal data stream error.
Debug Information: ../gst/isomp4/qtdemux.c(6607): gst_qtdemux_loop (): /GstPipeline:video-play/GstQTDemux:demux:
streaming stopped, reason not-negotiated (-4)
Returned, stopping playback...
Freeing pipeline...
Completed. Goodbye!

```<code>#include <gst/gst.h>
#include <stdlib.h>
#include <string.h>

#define INPUT_FILE "file.mp4"

static gboolean bus_call(GstBus *bus, GstMessage *msg, gpointer data)
{
    GMainLoop *loop = (GMainLoop *)data;

    switch (GST_MESSAGE_TYPE(msg)) {
        gchar  *debug;
        GError *error;

    case GST_MESSAGE_EOS:
        g_print("End of stream\n");
        g_main_loop_quit(loop);
        break;

    case GST_MESSAGE_ERROR:

        gst_message_parse_error(msg, &error, &debug);
        g_free(debug);

        g_printerr("Error: %s\n", error->message);
        g_printerr("Debug Information: %s\n", debug);
        g_error_free(error);

        g_main_loop_quit(loop);
        break;
    default:
        break;
    }

    return TRUE;
}

static void on_pad_added(GstElement *element, GstPad *pad, gpointer data)
{
    gchar *name;
    GstElement *parse = (GstElement *)data;

    name = gst_pad_get_name(pad);
    g_print("A new pad %s was created for %s\n", name, gst_element_get_name(element));
    g_free(name);

    g_print("element %s will be linked to %s\n",
        gst_element_get_name(element),
        gst_element_get_name(parse));

    gst_element_link(element, parse);
}

int main(int argc, char *argv[])
{
    GMainLoop *loop;
    GstElement *pipeline, *source, *demux, *parser, *decoder, *sink, *fpssink;
    GstBus *bus;
    guint bus_watch_id;

    const gchar *input_file = INPUT_FILE;

    /* Initialization */
    gst_init(&argc, &argv);
    loop = g_main_loop_new(NULL, FALSE);

    /* Create gstreamer elements */
    pipeline = gst_pipeline_new("video-play");
    source = gst_element_factory_make("filesrc", "file-source");
    demux = gst_element_factory_make("qtdemux", "demux");
    parser = gst_element_factory_make("h264parse", "h264-parser");
    decoder = gst_element_factory_make("avdec_h264", "decoder");
    sink = gst_element_factory_make("d3dvideosink", "video-output");

    if (!pipeline || !source || !demux || !parser || !decoder || !sink) {
        g_printerr("One element could not be created. Exiting.\n");
        return -1;
    }

    /* Set input video file for source element */
    g_object_set(G_OBJECT(source), "location", input_file, NULL);

    /* we add a message handler */
    bus = gst_pipeline_get_bus(GST_PIPELINE(pipeline));
    bus_watch_id = gst_bus_add_watch(bus, bus_call, loop);
    gst_object_unref(bus);

    /* Add all elements into the pipeline */
    /* pipeline---[ filesrc + qtdemux + h264parse + avdec_h264 + d3dvideosink ] */
    gst_bin_add_many(GST_BIN(pipeline), source, demux, parser, decoder, sink, NULL);

    /* Link the elements filesrc->demux together */

    if (gst_element_link(source, demux) != TRUE) {
        g_printerr("Element source->demux could not be linked.\n");
        gst_object_unref(pipeline);
        return -1;
    }
    /* h264parse -> avdec_h264 -> d3dvideosink */

    if (gst_element_link_many(parser, decoder, sink, NULL) != TRUE) {
            g_printerr("Many Elements could not be linked.\n");
            gst_object_unref(pipeline);
            return -1;
    }

    g_signal_connect(demux, "pad-added", G_CALLBACK(on_pad_added), parser);

    /* Set the pipeline to "playing" state */
    g_print("Now playing: %s\n", input_file);
    if (gst_element_set_state(pipeline,
        GST_STATE_PLAYING) == GST_STATE_CHANGE_FAILURE) {
        g_printerr("Unable to set the pipeline to the playing state.\n");
        gst_object_unref(pipeline);
        return -1;
    }

    g_print("Running...\n");
    g_main_loop_run(loop);

    /* Free resources and change state to NULL */
    gst_object_unref(bus);
    g_print("Returned, stopping playback...\n");
    gst_element_set_state(pipeline, GST_STATE_NULL);
    g_print("Freeing pipeline...\n");
    gst_object_unref(GST_OBJECT(pipeline));
    g_print("Completed. Goodbye!\n");
    return 0;
}
</code>```

Can you guys please let me know how to link these pads to the h264parser element to stream the video file. If possible, please explain how does these pads work in Gstreamer tools and applications

答:
Below command streamed a mp4 video file successfully:
gst-launch-1.0.exe -v filesrc location=file.mp4 ! qtdemux ! h264parse
! avdec_h264 ! videoconvert ! autovideosink

Ideally your pipeline should be :

gst-launch-1.0.exe -v filesrc location=file.mp4 ! qtdemux name=d
d.video_0 ! queue ! h264parse ! avdec_h264 ! videoconvert !
autovideosink

If you inspect qtdemux (gst-inspect-1.0 qtdemux), you will notice that the SINK pads have the below caps:

Capabilities:
video/quicktime
video/mj2
audio/x-m4a
application/x-3gp

And if you inspect h264parse (gst-inspect-1.0 h264parse) , you will notice that the SRC Pads have the below caps :

SRC template: 'src'
Availability: Always
Capabilities:
video/x-h264
parsed: true
stream-format: { (string)avc, (string)avc3, (string)byte-stream }
alignment: { (string)au, (string)nal }

When you try to link the sink pad of Qtdemux to the src pad of h264parse, you may have to collect the video caps to connect with h264parse.

I have used the below code for linking the qtdemux with h264parse inside "pad-added" signal:

```<code>static void pad_added_handler(GstElement *src, GstPad *new_pad, gpointer *data) {
   GstPadLinkReturn ret;
   GstCaps *new_pad_caps = NULL;
   GstStructure *new_pad_struct = NULL;
   const gchar *new_pad_type = NULL;
   GstElement *h264parse = (GstElement *) data;

   /* Check the new pad's type */
   new_pad_caps = gst_pad_get_current_caps(new_pad);
   new_pad_struct = gst_caps_get_structure(new_pad_caps, 0);
   new_pad_type = gst_structure_get_name(new_pad_struct);

    if (g_str_has_prefix(new_pad_type, "video/x-h264")) {
          GstPad *sink_pad_video = gst_element_get_static_pad (h264parse, "sink");
          ret = gst_pad_link(new_pad, sink_pad_video);
     }
   }
</code>```

Note:
You may need to link caps filters to filter a desired video capability of your video source or just try the condition as:
if (g_str_has_prefix(new_pad_type, "video")) {}

But I am not sure how adding a queue solved your problem.

Hope this helps.

Body:
I am learning Gstreamer and whatever I have achieved through Gstreamer tools, I am trying to implement the same with gstreamer application using C language.

Below command streamed a mp4 video file successfully:
gst-launch-1.0.exe -v filesrc location=file.mp4 ! qtdemux ! h264parse ! avdec_h264 ! videoconvert ! autovideosink

I tried the same with C code and also used the "pad-added" Elements Signals to create pads and linked to the next element i.e. parser (h264parser).

So, it got failed with streaming stopped, reason not-negotiated.

Complete Output:
Now playing: file.mp4
Running...
A new pad video_0 was created for demux
element demux will be linked to parser
Error: Internal data stream error.
Debug Information: ../gst/isomp4/qtdemux.c(6607): gst_qtdemux_loop (): /GstPipeline:video-play/GstQTDemux:demux:
streaming stopped, reason not-negotiated (-4)
Returned, stopping playback...
Freeing pipeline...
Completed. Goodbye!

#include <gst/gst.h>
#include <stdlib.h>
#include <string.h>

#define INPUT_FILE "file.mp4"

static gboolean bus_call(GstBus *bus, GstMessage *msg, gpointer data)
{
    GMainLoop *loop = (GMainLoop *)data;

    switch (GST_MESSAGE_TYPE(msg)) {
        gchar  *debug;
        GError *error;

    case GST_MESSAGE_EOS:
        g_print("End of stream\n");
        g_main_loop_quit(loop);
        break;

    case GST_MESSAGE_ERROR:

        gst_message_parse_error(msg, &error, &debug);
        g_free(debug);

        g_printerr("Error: %s\n", error->message);
        g_printerr("Debug Information: %s\n", debug);
        g_error_free(error);

        g_main_loop_quit(loop);
        break;
    default:
        break;
    }

    return TRUE;
}

static void on_pad_added(GstElement *element, GstPad *pad, gpointer data)
{
    gchar *name;
    GstElement *parse = (GstElement *)data;

    name = gst_pad_get_name(pad);
    g_print("A new pad %s was created for %s\n", name, gst_element_get_name(element));
    g_free(name);

    g_print("element %s will be linked to %s\n",
        gst_element_get_name(element),
        gst_element_get_name(parse));

    gst_element_link(element, parse);
}

int main(int argc, char *argv[])
{
    GMainLoop *loop;
    GstElement *pipeline, *source, *demux, *parser, *decoder, *sink, *fpssink;
    GstBus *bus;
    guint bus_watch_id;

    const gchar *input_file = INPUT_FILE;

    /* Initialization */
    gst_init(&argc, &argv);
    loop = g_main_loop_new(NULL, FALSE);

    /* Create gstreamer elements */
    pipeline = gst_pipeline_new("video-play");
    source = gst_element_factory_make("filesrc", "file-source");
    demux = gst_element_factory_make("qtdemux", "demux");
    parser = gst_element_factory_make("h264parse", "h264-parser");
    decoder = gst_element_factory_make("avdec_h264", "decoder");
    sink = gst_element_factory_make("d3dvideosink", "video-output");

    if (!pipeline || !source || !demux || !parser || !decoder || !sink) {
        g_printerr("One element could not be created. Exiting.\n");
        return -1;
    }

    /* Set input video file for source element */
    g_object_set(G_OBJECT(source), "location", input_file, NULL);

    /* we add a message handler */
    bus = gst_pipeline_get_bus(GST_PIPELINE(pipeline));
    bus_watch_id = gst_bus_add_watch(bus, bus_call, loop);
    gst_object_unref(bus);

    /* Add all elements into the pipeline */
    /* pipeline---[ filesrc + qtdemux + h264parse + avdec_h264 + d3dvideosink ] */
    gst_bin_add_many(GST_BIN(pipeline), source, demux, parser, decoder, sink, NULL);

    /* Link the elements filesrc->demux together */

    if (gst_element_link(source, demux) != TRUE) {
        g_printerr("Element source->demux could not be linked.\n");
        gst_object_unref(pipeline);
        return -1;
    }
    /* h264parse -> avdec_h264 -> d3dvideosink */

    if (gst_element_link_many(parser, decoder, sink, NULL) != TRUE) {
            g_printerr("Many Elements could not be linked.\n");
            gst_object_unref(pipeline);
            return -1;
    }

    g_signal_connect(demux, "pad-added", G_CALLBACK(on_pad_added), parser);

    /* Set the pipeline to "playing" state */
    g_print("Now playing: %s\n", input_file);
    if (gst_element_set_state(pipeline,
        GST_STATE_PLAYING) == GST_STATE_CHANGE_FAILURE) {
        g_printerr("Unable to set the pipeline to the playing state.\n");
        gst_object_unref(pipeline);
        return -1;
    }

    g_print("Running...\n");
    g_main_loop_run(loop);

    /* Free resources and change state to NULL */
    gst_object_unref(bus);
    g_print("Returned, stopping playback...\n");
    gst_element_set_state(pipeline, GST_STATE_NULL);
    g_print("Freeing pipeline...\n");
    gst_object_unref(GST_OBJECT(pipeline));
    g_print("Completed. Goodbye!\n");
    return 0;
}

Can you guys please let me know how to link these pads to the h264parser element to stream the video file. If possible, please explain how does these pads work in Gstreamer tools and applications

Body:
Below command streamed a mp4 video file successfully:
gst-launch-1.0.exe -v filesrc location=file.mp4 ! qtdemux ! h264parse
! avdec_h264 ! videoconvert ! autovideosink

Ideally your pipeline should be :

gst-launch-1.0.exe -v filesrc location=file.mp4 ! qtdemux name=d
d.video_0 ! queue ! h264parse ! avdec_h264 ! videoconvert !
autovideosink

If you inspect qtdemux (gst-inspect-1.0 qtdemux), you will notice that the SINK pads have the below caps:

Capabilities:
video/quicktime
video/mj2
audio/x-m4a
application/x-3gp

And if you inspect h264parse (gst-inspect-1.0 h264parse) , you will notice that the SRC Pads have the below caps :

SRC template: 'src'
Availability: Always
Capabilities:
video/x-h264
parsed: true
stream-format: { (string)avc, (string)avc3, (string)byte-stream }
alignment: { (string)au, (string)nal }

When you try to link the sink pad of Qtdemux to the src pad of h264parse, you may have to collect the video caps to connect with h264parse.

I have used the below code for linking the qtdemux with h264parse inside "pad-added" signal:

static void pad_added_handler(GstElement *src, GstPad *new_pad, gpointer *data) {
   GstPadLinkReturn ret;
   GstCaps *new_pad_caps = NULL;
   GstStructure *new_pad_struct = NULL;
   const gchar *new_pad_type = NULL;
   GstElement *h264parse = (GstElement *) data;

   /* Check the new pad's type */
   new_pad_caps = gst_pad_get_current_caps(new_pad);
   new_pad_struct = gst_caps_get_structure(new_pad_caps, 0);
   new_pad_type = gst_structure_get_name(new_pad_struct);

    if (g_str_has_prefix(new_pad_type, "video/x-h264")) {
          GstPad *sink_pad_video = gst_element_get_static_pad (h264parse, "sink");
          ret = gst_pad_link(new_pad, sink_pad_video);
     }
   }

Note:
You may need to link caps filters to filter a desired video capability of your video source or just try the condition as:
if (g_str_has_prefix(new_pad_type, "video")) {}

But I am not sure how adding a queue solved your problem.

Hope this helps.


问:
How to access google chrome extension from any page's javascript
I am trying to figure out how can I call into my extension from a normal web page.
All documentation that I find seems to be either for communication between extensions, or between content scripts and extensions.

Any pointers are much appreciated!

答:
While extensions can't access page variables and vice versa, you can communicate between page and extension through events. Here is a quick example of creating custom events:

```<code>function fireEvent(name, target) {
    //Ready: create a generic event
    var evt = document.createEvent("Events")
    //Aim: initialize it to be the event we want
    evt.initEvent(name, true, true); //true for can bubble, true for cancelable
    //FIRE!
    target.dispatchEvent(evt);
}

function foobar() {
    alert("foobar");
}

function testEvents() {
    window.addEventListener("foobar", foobar, false); //false to get it in bubble not capture.
    fireEvent("foobar", document);
}
</code>```

(taken from here)

So if you need to pass information from a page to an extension, you would need to fire a custom event on a page which you will be listening to in your content script.

ContentLicense: CC BY-SA 3.0

Body:
While extensions can't access page variables and vice versa, you can communicate between page and extension through events. Here is a quick example of creating custom events:

function fireEvent(name, target) {
    //Ready: create a generic event
    var evt = document.createEvent("Events")
    //Aim: initialize it to be the event we want
    evt.initEvent(name, true, true); //true for can bubble, true for cancelable
    //FIRE!
    target.dispatchEvent(evt);
}

function foobar() {
    alert("foobar");
}

function testEvents() {
    window.addEventListener("foobar", foobar, false); //false to get it in bubble not capture.
    fireEvent("foobar", document);
}

(taken from here)

So if you need to pass information from a page to an extension, you would need to fire a custom event on a page which you will be listening to in your content script.


问:
How to notify View from ViewModel without breaking MVVM?
I recently started trying out MVVM pattern in school and was wondering what the best way (if any) is to notify View from the ViewModel, letting the view know to run a method without breaking MVVM? Basically letting the view know if something was successful, like a login attempt or trying to connect to a database?

An example could be a login page, where the mainwindow should change content to a new page only if the login was successful, if not, a messagebox should show up

Edit:

I'm using .NET

What I have tried so far:

View:

<Page
      xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
      xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
      xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
      xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
      xmlns:local="clr-namespace:View.Pages" xmlns:ViewModels="clr-namespace:ViewModel.ViewModels;assembly=ViewModel" x:Class="View.Pages.Start_Page"
      mc:Ignorable="d"
      d:DesignHeight="720" d:DesignWidth="1280"
      Title="Start_Page">

    <Page.DataContext>
        <ViewModels:Start_Page_ViewModel/>
    </Page.DataContext>
```

<p>Code behind it:</p>

<pre class="lang-cs prettyprint-override"><code>public Start_Page()
        {
            InitializeComponent();

            Start_Page_ViewModel currentDataContext = DataContext as Start_Page_ViewModel;

            currentDataContext.CurrentUserIDGotten += GoToMenu;
        }

        private void GoToMenu(int result)
        {
            if (result == -1)
            {
                MessageBox.Show("User credentials incorrect");
            }
            else if (result == -2)
            {
                MessageBox.Show("Connection failed");
            }
            else
            {
                Application.Current.MainWindow.Content = new Menu_Page();
            }
        }
</code>```

ViewModel:

public class Start_Page_ViewModel
    {

        private string userName;
        private string userPassword;

        public string UserName { get => userName; set => userName = value; }

        public string UserPassword { get => userPassword; set => userPassword = value; }

        private RelayCommand logIn;

        public RelayCommand LogIn => logIn;

        public delegate void CurrentUserIDGottenEventHandler(int result);
        public event CurrentUserIDGottenEventHandler CurrentUserIDGotten;

        public Start_Page_ViewModel()
        {
            logIn = new RelayCommand(LogInToProgram, CanLogIn);
        }

        public void LogInToProgram(object o)
        {
            PasswordBox passwordBox = o as PasswordBox;

            ViewModelController.Instance.CurrentUserID = Database_Controller.Instance.SignIn(userName, passwordBox.Password);

            OnUserIDGotten(ViewModelController.Instance.CurrentUserID);
        }

        public bool CanLogIn(object o)
        {
            if (userName != null)
            {
                return true;
            }
            return false;
        }

        protected virtual void OnUserIDGotten(int result)
        {
            if (CurrentUserIDGotten != null)
            {
                CurrentUserIDGotten(result);
            }
        }
    }
```

答:
Generally, the ViewModel communicates with the View via databindings. The ViewModel might expose a property, like LoginSuccessful, that the the View would bind to. Then, when the property updates, the View would receive a PropertyChanged notification and change some aspect of its appearance. How it would do this varies; for example, a text property in XAML could be bound directly to an underlying ViewModel property:

<TextBox Text="{Binding Source={StaticResource UserViewModel}, Path=Username}"/>
```

<p>The ViewModel might look like:</p>

<pre class="lang-cs prettyprint-override"><code>public class UserViewModel : INotifyPropertyChanged {
    public event PropertyChangedEventHandler PropertyChanged;

    public string Username {
        get { return _username; }
        set {
            _username = value;
            PropertyChanged.Invoke(this, new PropertyChangedEventArgs("Username"));
        }
    }
    private string _username;

    public UserViewModel() { }
}
</code>```

Whenever the Username property is changed on the UserViewModel class, the text box will update to display the new value.

However, this approach doesn't work for all situations. When working with boolean values, it's often useful to implement data triggers:

<TextBox Text="{Binding Source={StaticResource UserViewModel}, Path=Username}">
    <TextBlock.Style>

        </Style>
    </TextBlock.Style>
</TextBox>
```

This code extends the previous example to color the background of the text box red if the IsTaken property is set to true on the ViewModel. A nice thing about data triggers is that they reset themselves; for example, if the value is set to false the background will revert to its original color.

If you want to go the other way, and notify the ViewModel of user input or a similarly important event, you can use commands. Commands can be bound to properties in XAML, and are implemented by the ViewModel. They are called when the user performs a certain action, such a clicking a button. Commands can be created by implementing the ICommand interface.

Body:
I recently started trying out MVVM pattern in school and was wondering what the best way (if any) is to notify View from the ViewModel, letting the view know to run a method without breaking MVVM? Basically letting the view know if something was successful, like a login attempt or trying to connect to a database?

An example could be a login page, where the mainwindow should change content to a new page only if the login was successful, if not, a messagebox should show up

Edit:

I'm using .NET

What I have tried so far:

View:

<Page
      xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
      xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
      xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
      xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
      xmlns:local="clr-namespace:View.Pages" xmlns:ViewModels="clr-namespace:ViewModel.ViewModels;assembly=ViewModel" x:Class="View.Pages.Start_Page"
      mc:Ignorable="d"
      d:DesignHeight="720" d:DesignWidth="1280"
      Title="Start_Page">

    <Page.DataContext>
        <ViewModels:Start_Page_ViewModel/>
    </Page.DataContext>

Code behind it:

public Start_Page()
        {
            InitializeComponent();

            Start_Page_ViewModel currentDataContext = DataContext as Start_Page_ViewModel;

            currentDataContext.CurrentUserIDGotten += GoToMenu;
        }

        private void GoToMenu(int result)
        {
            if (result == -1)
            {
                MessageBox.Show("User credentials incorrect");
            }
            else if (result == -2)
            {
                MessageBox.Show("Connection failed");
            }
            else
            {
                Application.Current.MainWindow.Content = new Menu_Page();
            }
        }

ViewModel:

public class Start_Page_ViewModel
    {

        private string userName;
        private string userPassword;

        public string UserName { get => userName; set => userName = value; }

        public string UserPassword { get => userPassword; set => userPassword = value; }

        private RelayCommand logIn;

        public RelayCommand LogIn => logIn;

        public delegate void CurrentUserIDGottenEventHandler(int result);
        public event CurrentUserIDGottenEventHandler CurrentUserIDGotten;

        public Start_Page_ViewModel()
        {
            logIn = new RelayCommand(LogInToProgram, CanLogIn);
        }

        public void LogInToProgram(object o)
        {
            PasswordBox passwordBox = o as PasswordBox;

            ViewModelController.Instance.CurrentUserID = Database_Controller.Instance.SignIn(userName, passwordBox.Password);

            OnUserIDGotten(ViewModelController.Instance.CurrentUserID);
        }

        public bool CanLogIn(object o)
        {
            if (userName != null)
            {
                return true;
            }
            return false;
        }

        protected virtual void OnUserIDGotten(int result)
        {
            if (CurrentUserIDGotten != null)
            {
                CurrentUserIDGotten(result);
            }
        }
    }

Body:
Generally, the ViewModel communicates with the View via databindings. The ViewModel might expose a property, like LoginSuccessful, that the the View would bind to. Then, when the property updates, the View would receive a PropertyChanged notification and change some aspect of its appearance. How it would do this varies; for example, a text property in XAML could be bound directly to an underlying ViewModel property:

<TextBox Text="{Binding Source={StaticResource UserViewModel}, Path=Username}"/>

The ViewModel might look like:

public class UserViewModel : INotifyPropertyChanged {
    public event PropertyChangedEventHandler PropertyChanged;

    public string Username {
        get { return _username; }
        set {
            _username = value;
            PropertyChanged.Invoke(this, new PropertyChangedEventArgs("Username"));
        }
    }
    private string _username;

    public UserViewModel() { }
}

Whenever the Username property is changed on the UserViewModel class, the text box will update to display the new value.

However, this approach doesn't work for all situations. When working with boolean values, it's often useful to implement data triggers:

<TextBox Text="{Binding Source={StaticResource UserViewModel}, Path=Username}">
    <TextBlock.Style>
        <Style TargetType="{x:Type TextBox}">
            <Style.Triggers>
                <DataTrigger Binding="{Binding Source={StaticResource UserViewModel}, Path=IsTaken}" Value="True">
                            <Setter Property="Background" Value="Red"></Setter>
                </DataTrigger>
            </Style.Triggers>
        </Style>
    </TextBlock.Style>
</TextBox>

This code extends the previous example to color the background of the text box red if the IsTaken property is set to true on the ViewModel. A nice thing about data triggers is that they reset themselves; for example, if the value is set to false the background will revert to its original color.

If you want to go the other way, and notify the ViewModel of user input or a similarly important event, you can use commands. Commands can be bound to properties in XAML, and are implemented by the ViewModel. They are called when the user performs a certain action, such a clicking a button. Commands can be created by implementing the ICommand interface.


问:
Angular 7 Type 'void' is not assignable to type 'ObservableInput<{}>'
I can not figure it out why i got this error

```<code>  getByURL(url: string): any {
    return this.apiService.get(url).pipe(map(data => data));
  }

  getByNextPage(): Observable<any> {
    const url = 'url';
    this.getByURL(url).pipe(
      expand(data => {
        console.log(data);
      })
    );
  }
</code>```

I got this error at line that has expand(data => ... . I want to use expand() so i can recursive the call for the next api.

```<code>Type 'void' is not assignable to type 'ObservableInput<{}>'
</code>```

Any hint would be really appreciate. Thanks

答:
That is because you are using expand() operator badly. If you check documentation, the expand() operator has to return an Observable and you are not returning nothing.

Even though you return "data" variable the error will still persist because that rule.

Check this documentation

Body:
I can not figure it out why i got this error

  getByURL(url: string): any {
    return this.apiService.get(url).pipe(map(data => data));
  }

  getByNextPage(): Observable<any> {
    const url = 'url';
    this.getByURL(url).pipe(
      expand(data => {
        console.log(data);
      })
    );
  }

I got this error at line that has expand(data => ... . I want to use expand() so i can recursive the call for the next api.

Type 'void' is not assignable to type 'ObservableInput<{}>'

Any hint would be really appreciate. Thanks


问:
My input is not working in React, onChange looks good too
My input element doesn't let me type into it, it will show up, with the value i want, but I cannot delete or edit anything in the input. Everything is spelled correctly from what I have seen.

I've been googling and have searched multiple SO forms, none have been able to help me. Which is why I am asking now

```<code>const GuestName =(props)=>{
    if(props.isEditing){
        return(
        <form>
        <input type='text' className='edit-guest-input'
         value={props.guestName} onChange={e => props.editGuest(e.target.value)}/>
         </form>
        )
    }

    return (
    <span>{props.guestName}</span>
    )
}
</code>```

the above is the input that will not work

```<code>  editGuest=(id, name)=>{
    this.setState({
      guest: this.state.guest.map((guest) =>{
        if(id===guest.id){
          return{
            ...guest,
            name
          }}
          return guest
      })
    })
  }
</code>```

this is the code for the onChange event.

```<code>const GuestList =(props)=>

    <div>

        <ul>
            {props.guest.filter( guest => !props.filterUnconfirmedGuest || guest.isConfirmed)
            .map((guest, index) =>   <Guest
                            key={index}
                            guestName={guest.guestName}
                            toggleGuestConfirmed={props.toggleGuestConfirmed}
                            isConfirmed={guest.isConfirmed}
                            toggleEditGuest={()=> props.toggleEditGuest(guest.id)}
                            isEditing={guest.isEditing}
                            editGuest={editedName=> props.editGuest(editedName, guest.id)}
                            removeGuest={()=> props.removeGuest(guest.id)}
                                />)}
       </ul>
    </div>
</code>```

The first argument is passed in here

Probably a minor issue that I am too tired to notice lol. Any help is appreciated, thank you for your time!

答:
You are calling the editGuests function with one argument

```<code>onChange={e => props.editGuest(e.target.value)}
</code>```

But it has two arguments in the definition

```<code>editGuest=(id, name)=>{

}
</code>```

Body:
My input element doesn't let me type into it, it will show up, with the value i want, but I cannot delete or edit anything in the input. Everything is spelled correctly from what I have seen.

I've been googling and have searched multiple SO forms, none have been able to help me. Which is why I am asking now

const GuestName =(props)=>{
    if(props.isEditing){
        return(
        <form>
        <input type='text' className='edit-guest-input'
         value={props.guestName} onChange={e => props.editGuest(e.target.value)}/>
         </form>
        )
    }

    return (
    {props.guestName}
    )
}

the above is the input that will not work

  editGuest=(id, name)=>{
    this.setState({
      guest: this.state.guest.map((guest) =>{
        if(id===guest.id){
          return{
            ...guest,
            name
          }}
          return guest
      })
    })
  }

this is the code for the onChange event.

const GuestList =(props)=>

            {props.guest.filter( guest => !props.filterUnconfirmedGuest || guest.isConfirmed)
            .map((guest, index) =>   <Guest
                            key={index}
                            guestName={guest.guestName}
                            toggleGuestConfirmed={props.toggleGuestConfirmed}
                            isConfirmed={guest.isConfirmed}
                            toggleEditGuest={()=> props.toggleEditGuest(guest.id)}
                            isEditing={guest.isEditing}
                            editGuest={editedName=> props.editGuest(editedName, guest.id)}
                            removeGuest={()=> props.removeGuest(guest.id)}
                                />)}

The first argument is passed in here

Probably a minor issue that I am too tired to notice lol. Any help is appreciated, thank you for your time!

Body:
You are calling the editGuests function with one argument

onChange={e => props.editGuest(e.target.value)}

But it has two arguments in the definition

editGuest=(id, name)=>{

}


问:
NSAttributedString and emoji: the range I never set seems to be set
This is the most weird problem (XCode 10.2.1 playground):

let a = "String with emoji "
var b = "00:00 0000"

var nsa = NSMutableAttributedString(string: a)
var nsb = NSMutableAttributedString(string: b)
nsb.addAttributes([.foregroundColor: UIColor.red],
                  range: NSRange(location: 0, length: nsb.length))
nsa.append(nsb)
```

and the nsa looks like this:

The 00 after the emoji has the same width and height as the emoji character. But it gets weirder. The effect is extended only over digits 0-9, space, and hash (#) characters. If I replace the 00:00 0000 with a different string then everything is perfectly normal:

It seems like internally NSMutableAttributedString applies an attribute to the emoji character and then incorrectly extends it to the attached string's prefix composed of certain characters.

Is this a known problem? I found a workaround by appending a thin non-breaking space character to the first string a + "\u{2009}". Is there a better way of dealing with emoji weirdness in Swift?

答:
Here is Apple's official answer:

We have determined that this is an issue for you to resolve.

Since the app is not explicitly specifying the font to the attributed
  string, it’s relying on the font fallback system.

It is recommended to specify the font attribute all the time since the
  contextual nature of the text system might produce unexpected result
  like this.

Please let us know whether the issue is resolved for you by updating
  your bug report.

This is just appalling.

Body:
This is the most weird problem (XCode 10.2.1 playground):

let a = "String with emoji "
var b = "00:00 0000"

var nsa = NSMutableAttributedString(string: a)
var nsb = NSMutableAttributedString(string: b)
nsb.addAttributes([.foregroundColor: UIColor.red],
                  range: NSRange(location: 0, length: nsb.length))
nsa.append(nsb)

and the nsa looks like this:

The 00 after the emoji has the same width and height as the emoji character. But it gets weirder. The effect is extended only over digits 0-9, space, and hash (#) characters. If I replace the 00:00 0000 with a different string then everything is perfectly normal:

It seems like internally NSMutableAttributedString applies an attribute to the emoji character and then incorrectly extends it to the attached string's prefix composed of certain characters.

Is this a known problem? I found a workaround by appending a thin non-breaking space character to the first string a + "\u{2009}". Is there a better way of dealing with emoji weirdness in Swift?


问:
Ranking different combinations in SQL
I'm working with pharmacy data and I'm trying to rank the use of three specific medications (A, B, C) amongst a large group of patients. In short, I want to figure out the top 12 combinations of these meds that people are using. So for instance, patient 1 might take meds A + B,

patient 2 takes A + C, patient 3 takes B + C, patient 4 takes A + B, and so forth. I did some digging and there are 25 possible combinations to rank. I want my output to look something like this:

The tables I'm working with look like this:

Currently I'm breaking the drugs up into different combination groups by doing something like this:

```<code>select distinct concat(substance_name, dosage, unit) as Drug_Dose_Combo,
count(distinct user_id) as Patients
from pharmacy_data a join drug_reference_table b
on a.drug_code=b.drug_code
group by 1
order by 2 desc
</code>```

However, this seems very inefficient so I'm looking for a better way of building this out. I don't necessarily need to use a rank() here, I just want the output to look similar to what I've outlined above.

答:
Maybe something like (Untested):</p>

```<code>WITH meds_taken AS
  (SELECT sum(CASE WHEN d.drug_name = :namea THEN 1 ELSE 0 END) AS drug_a
        , sum(CASE WHEN d.drug_name = :nameb THEN 1 ELSE 0 END) AS drug_b
        , sum(CASE WHEN d.drug_name = :namec THEN 1 ELSE 0 END) AS drug_c
   FROM pharmacy_data AS p
   JOIN drug_reference AS d ON p.drug_code = d.drug_code
   GROUP BY p.user_id)
, med_counts AS
  (SELECT drug_a, drug_b, drug_c, count(*) AS "user total"
   FROM meds_taken
   GROUP BY drug_a, drug_b, drug_c)
SELECT rank() OVER (ORDER BY "user total" DESC) AS rank
     , drug_a, drug_b, drug_c, "user total"
FROM med_counts
ORDER BY "user total" DESC;
</code>```

Title: Ranking different combinations in SQL

Body:
I'm working with pharmacy data and I'm trying to rank the use of three specific medications (A, B, C) amongst a large group of patients. In short, I want to figure out the top 12 combinations of these meds that people are using. So for instance, patient 1 might take meds A + B,

patient 2 takes A + C, patient 3 takes B + C, patient 4 takes A + B, and so forth. I did some digging and there are 25 possible combinations to rank. I want my output to look something like this:

The tables I'm working with look like this:

Currently I'm breaking the drugs up into different combination groups by doing something like this:

select distinct concat(substance_name, dosage, unit) as Drug_Dose_Combo,
count(distinct user_id) as Patients
from pharmacy_data a join drug_reference_table b
on a.drug_code=b.drug_code
group by 1
order by 2 desc

However, this seems very inefficient so I'm looking for a better way of building this out. I don't necessarily need to use a rank() here, I just want the output to look similar to what I've outlined above.

Body:
Maybe something like (Untested):

WITH meds_taken AS
  (SELECT sum(CASE WHEN d.drug_name = :namea THEN 1 ELSE 0 END) AS drug_a
        , sum(CASE WHEN d.drug_name = :nameb THEN 1 ELSE 0 END) AS drug_b
        , sum(CASE WHEN d.drug_name = :namec THEN 1 ELSE 0 END) AS drug_c
   FROM pharmacy_data AS p
   JOIN drug_reference AS d ON p.drug_code = d.drug_code
   GROUP BY p.user_id)
, med_counts AS
  (SELECT drug_a, drug_b, drug_c, count(*) AS "user total"
   FROM meds_taken
   GROUP BY drug_a, drug_b, drug_c)
SELECT rank() OVER (ORDER BY "user total" DESC) AS rank
     , drug_a, drug_b, drug_c, "user total"
FROM med_counts
ORDER BY "user total" DESC;


问:
PostgreSQL and locking
Hopefully some smarter DBAs than I can help me find a good solution for what I need to do.

For the sake of discussion, lets assume I have a table called 'work' with some number of columns, one of which is a column that represents ownership of that row of work from a given client.  The scenario is that I'll have 2 clients connected and polling a table for work to be done, when a row (or some number of rows) shows up, the first client that selects the rows will also update them to imply ownership, that update will remove those rows from being returned to any other client's selects.  My question is, in this scenario, what sort of locking can I use to prevent 2 clients from hitting the table at the same time and both of them being returned the same rows via the select?

答:
The UPDATE statement with RETURNING clause is the way to do this.

```<code>UPDATE table
SET ownership = owner
RETURNING ( column list );
</code>```

REFERENCES:

Similar Question

Documentation

Title: PostgreSQL and locking

Body:
The UPDATE statement with RETURNING clause is the way to do this.

UPDATE table
SET ownership = owner
RETURNING ( column list );

REFERENCES:

Similar Question

Documentation


问:
Pyinstaller Creates Empty Dist Folder
I have a small python script where I have only one dependency

```<code>from pandas import DataFrame as pdf
</code>```

I want to create a .exe that would only require users to have python installed in their PATH. This guide helped me run the creation but the yielding dist folder is empty. Does anyone know why this is the case or

what I am doing wrong?

Specs: written in and for Windows OS, Python 3.6.5 - Anaconda

Edit: Here's the sample I am working with.

```<code>from pandas import DataFrame as pdf
if "__main__":
    df = pdf([['This', 'is'], ['a', 'Test']],
                     index=['Row 1', 'Row 2'],
                     columns=['col 1', 'col 2'])
    df.to_excel("output\output.xlsx")
</code>```

The resulting spec file is

```<code># -*- mode: python -*-

block_cipher = None

a = Analysis(['src\\sample.py'],
             pathex=['C:\\Users\\kpiq\\Documents\\Data Science\\Executable Creation'],
             binaries=[],
             datas=[],
             hiddenimports=[],
             hookspath=[],
             runtime_hooks=[],
             excludes=[],
             win_no_prefer_redirects=False,
             win_private_assemblies=False,
             cipher=block_cipher,
             noarchive=False)
pyz = PYZ(a.pure, a.zipped_data,
             cipher=block_cipher)
exe = EXE(pyz,
          a.scripts,
          [],
          exclude_binaries=True,
          name='sample',
          debug=False,
          bootloader_ignore_signals=False,
          strip=False,
          upx=True,
          console=True )
coll = COLLECT(exe,
               a.binaries,
               a.zipfiles,
               a.datas,
               strip=False,
               upx=True,
               name='sample')
</code>```

The command used was pyinstaller src\sample.py

答:
I found an answer posted by NAP_time in another question 1.  The solution was to download the trial version using:

pip install https://github.com/pyinstaller/pyinstaller/archive/develop.zip

I did this and it worked for me.  Best of luck.

Title: Pyinstaller Creates Empty Dist Folder

Body:
I have a small python script where I have only one dependency

from pandas import DataFrame as pdf

I want to create a .exe that would only require users to have python installed in their PATH. This guide helped me run the creation but the yielding dist folder is empty. Does anyone know why this is the case or

what I am doing wrong?

Specs: written in and for Windows OS, Python 3.6.5 - Anaconda

Edit: Here's the sample I am working with.

from pandas import DataFrame as pdf
if "__main__":
    df = pdf([['This', 'is'], ['a', 'Test']],
                     index=['Row 1', 'Row 2'],
                     columns=['col 1', 'col 2'])
    df.to_excel("output\output.xlsx")

The resulting spec file is

# -*- mode: python -*-

block_cipher = None

a = Analysis(['src\\sample.py'],
             pathex=['C:\\Users\\kpiq\\Documents\\Data Science\\Executable Creation'],
             binaries=[],
             datas=[],
             hiddenimports=[],
             hookspath=[],
             runtime_hooks=[],
             excludes=[],
             win_no_prefer_redirects=False,
             win_private_assemblies=False,
             cipher=block_cipher,
             noarchive=False)
pyz = PYZ(a.pure, a.zipped_data,
             cipher=block_cipher)
exe = EXE(pyz,
          a.scripts,
          [],
          exclude_binaries=True,
          name='sample',
          debug=False,
          bootloader_ignore_signals=False,
          strip=False,
          upx=True,
          console=True )
coll = COLLECT(exe,
               a.binaries,
               a.zipfiles,
               a.datas,
               strip=False,
               upx=True,
               name='sample')

The command used was pyinstaller src\sample.py


问:
lines+=line/ TypeError: can't concat str to bytes
I need to pass the arduino data that is saved on a microSD to the sqlite database of my GUI. Anyone besides being able to fix this error, could you help me pass the data to the database?</p>

```<code>lines=b''

with serial.Serial('COM5',9600,timeout=2) as ser:
    line = ser.readline()
    line = line.decode("utf-8")
    lines+=line
</code>```

答:
I'm assuming you are using Python 3 (it's good practice to specify this information in your question).

Also, I assume that lines+=lines is a typo introduced when writing the question and your program uses lines+=line.

The pySerial docs for read() say it returns bytes, so it's likely that readline() also returns bytes.  When you do line.decode("utf-8"), you are using the byte string you got from the device to create text string.  Then you are trying to append line (type str) to lines (type bytes, because you created it with the bytestring literal b''), and that causes the error.

You should be able to solve this either by:

creating lines as a text string (lines = '')

not decoding line before appending it to lines

Which one you choose probably depends on whether the information provided by the device is actually textual and guaranteed not to fail at the decoding step, or whether it's actually binary and will need to be parsed later in the program.

Body:
I need to pass the arduino data that is saved on a microSD to the sqlite database of my GUI. Anyone besides being able to fix this error, could you help me pass the data to the database?

lines=b''

with serial.Serial('COM5',9600,timeout=2) as ser:
    line = ser.readline()
    line = line.decode("utf-8")
    lines+=line


问:
Get bool if a Nvidia or a AMD GPU card is installed
I need to somehow to get a list of the GPUs installed and available to use and for each GPU detected i need to get the brand name of it using Java.

Only on Windows

答:
It is impossible with pure Java.

You will need platform specific solution.


问:
MemoizedSelector is not assignable to parameter of type 'string'
I am using Angular 6 and NgRX 6.

I have a reducer that looks something like this -

```<code>export interface IFlexBenefitTemplateState {
  original: IFlexBenefitTemplate;
  changes: IFlexBenefitTemplate;
  count: number;
  loading: boolean;
}

export const INITIAL_STATE: IFlexBenefitTemplateState = {
  original: null,
  changes: null,
  count: 0,
  loading: true,
};

export default (state = INITIAL_STATE, { type, payload }) => {
  switch (type) {

    case STAGE_TEMPLATE_CHANGE:
      const pendingChanges = Object.assign({}, state.changes.sections);
      const newSection = Object.assign({}, pendingChanges[payload.key], payload, {
        changeType: 'updated',
      });

      return {
        ...state,
        changes: {
          sections: Object.assign({}, pendingChanges, { [payload.key]: { ...newSection } }),
        },
        count: !pendingChanges[payload.key].hasOwnProperty('changeType') ? state.count + 1 : state.count,
      };

    default:
      return state;
  }
};
</code>```

I have a selector this grabbing state.count for me, which looks like this -

```<code>export const changesCount = createSelector(getStore, (state: IFlexBenefitTemplateState) => state.count);
</code>```

And I am attempting to surface this is my template as follows -

```<code>@Component({
  selector: 'app-page-header-component',
  templateUrl: './page-header.component.html',
})
export class PageHeaderComponent implements OnInit {
  public count$: Observable<number>;

  public language: string;

  constructor(private store: Store<ICommonAppState>) {}

  ngOnInit(): void {
    this.count$ = this.store.select(changesCount);
    this.language = 'English';
  }
}
</code>```

this.count$ is however returning the error

```<code>[ts] Argument of type 'MemoizedSelector<IBenefitsState, number>' is not assignable to parameter of type 'string'.
</code>```

I cannot for the life of me understand what this is happening?

答:
I had the same error.  The problem wasn't having the wrong interface in my store.  Instead I was using the wrong selector.

Thanks to @nodediggity for getting me looking in the right direction.

Body:
I am using Angular 6 and NgRX 6.

I have a reducer that looks something like this -

export interface IFlexBenefitTemplateState {
  original: IFlexBenefitTemplate;
  changes: IFlexBenefitTemplate;
  count: number;
  loading: boolean;
}

export const INITIAL_STATE: IFlexBenefitTemplateState = {
  original: null,
  changes: null,
  count: 0,
  loading: true,
};

export default (state = INITIAL_STATE, { type, payload }) => {
  switch (type) {

    case STAGE_TEMPLATE_CHANGE:
      const pendingChanges = Object.assign({}, state.changes.sections);
      const newSection = Object.assign({}, pendingChanges[payload.key], payload, {
        changeType: 'updated',
      });

      return {
        ...state,
        changes: {
          sections: Object.assign({}, pendingChanges, { [payload.key]: { ...newSection } }),
        },
        count: !pendingChanges[payload.key].hasOwnProperty('changeType') ? state.count + 1 : state.count,
      };

    default:
      return state;
  }
};

I have a selector this grabbing state.count for me, which looks like this -

export const changesCount = createSelector(getStore, (state: IFlexBenefitTemplateState) => state.count);

And I am attempting to surface this is my template as follows -

@Component({
  selector: 'app-page-header-component',
  templateUrl: './page-header.component.html',
})
export class PageHeaderComponent implements OnInit {
  public count$: Observable<number>;

  public language: string;

  constructor(private store: Store<ICommonAppState>) {}

  ngOnInit(): void {
    this.count$ = this.store.select(changesCount);
    this.language = 'English';
  }
}

this.count$ is however returning the error

[ts] Argument of type 'MemoizedSelector<IBenefitsState, number>' is not assignable to parameter of type 'string'.

I cannot for the life of me understand what this is happening?


问:
How to remove a TextField from ListView when onPressed button?
How to remove the TextField when user click on "clear icon" button ? (not just clear the Text of TextField)

User Story

The user click on a button to add player. (Technically this button add TextField)

The user can write the name of player on TextField.

The user click on a "clear icon" button to remove current TextField (opposite of add function).

```<code>new ListView.builder(
                     padding: EdgeInsets.all(0),
                      shrinkWrap: true,
                      physics: NeverScrollableScrollPhysics(),
                      itemCount: 5,
                      itemBuilder: (context, index) {
                        print(index);
                        return TextField(
                          maxLength: 20,
                          decoration: InputDecoration(
                            labelText: "Player ${index+1}",
                            counterText: "",
                            prefixIcon: const Icon(Icons.person),
                            suffixIcon: new IconButton(
                                icon: Icon(Icons.clear),
                                onPressed: () =>
                                  setState(() {
                                    this.dispose(); // -----Doesn't work----
                                  })
                                ),
                          ),
                        );
                      }
                    ),
</code>```

For example, user set "John" on Player 4 if user click on "clear button" then Player 4 TextField is deleted. It will remain only 4 TextField

答:
You can have a property to check wheter the user clicked that button and depending on the value you show/hide the TextField. Below I just use a boolean property if user click on X button then I set hideField to true and the TextField will be replaced with a zero sized widget.

```<code> new ListView.builder(
                    padding: EdgeInsets.all(0),
                    shrinkWrap: true,
                    physics: NeverScrollableScrollPhysics(),
                    itemCount: 5,
                    itemBuilder: (context, index) {
                      print(index);
                      bool hideField = false; // I added it here

                      return hideField ? SizedBox.shrink() : TextField(
                        maxLength: 20,
                        decoration: InputDecoration(
                          labelText: "Player ${index + 1}",
                          counterText: "",
                          prefixIcon: const Icon(Icons.person),
                          suffixIcon: new IconButton(
                              icon: Icon(Icons.clear),
                              onPressed: () =>
                                  setState(() {
                                    hideField = true; // Now it works
                                  })
                          ),
                        ),
                      );
                    }
                )
</code>```

Body:
How to remove the TextField when user click on "clear icon" button ? (not just clear the Text of TextField)

User Story

The user click on a button to add player. (Technically this button add TextField)

The user can write the name of player on TextField.

The user click on a "clear icon" button to remove current TextField (opposite of add function).

new ListView.builder(
                     padding: EdgeInsets.all(0),
                      shrinkWrap: true,
                      physics: NeverScrollableScrollPhysics(),
                      itemCount: 5,
                      itemBuilder: (context, index) {
                        print(index);
                        return TextField(
                          maxLength: 20,
                          decoration: InputDecoration(
                            labelText: "Player ${index+1}",
                            counterText: "",
                            prefixIcon: const Icon(Icons.person),
                            suffixIcon: new IconButton(
                                icon: Icon(Icons.clear),
                                onPressed: () =>
                                  setState(() {
                                    this.dispose(); // -----Doesn't work----
                                  })
                                ),
                          ),
                        );
                      }
                    ),

For example, user set "John" on Player 4 if user click on "clear button" then Player 4 TextField is deleted. It will remain only 4 TextField

Body:
You can have a property to check wheter the user clicked that button and depending on the value you show/hide the TextField. Below I just use a boolean property if user click on X button then I set hideField to true and the TextField will be replaced with a zero sized widget.

 new ListView.builder(
                    padding: EdgeInsets.all(0),
                    shrinkWrap: true,
                    physics: NeverScrollableScrollPhysics(),
                    itemCount: 5,
                    itemBuilder: (context, index) {
                      print(index);
                      bool hideField = false; // I added it here

                      return hideField ? SizedBox.shrink() : TextField(
                        maxLength: 20,
                        decoration: InputDecoration(
                          labelText: "Player ${index + 1}",
                          counterText: "",
                          prefixIcon: const Icon(Icons.person),
                          suffixIcon: new IconButton(
                              icon: Icon(Icons.clear),
                              onPressed: () =>
                                  setState(() {
                                    hideField = true; // Now it works
                                  })
                          ),
                        ),
                      );
                    }
                )


问:
How to remove duplicates in MySQL using Rails?
I have to following table:

Relations

```<code>[id,user_id,status]
1,2,sent_reply
1,2,sent_mention
1,3,sent_mention
1,4,sent_reply
1,4,sent_mention
</code>```

I am looking for a way to remove duplicates, so that only the following rows will remain:

```<code>1,2,sent_reply
1,3,sent_mention
1,4,sent_reply
</code>```

(Preferably using Rails)

答:
It is better to do it through SQL. But if you prefer to use Rails:

```<code>(Relation.all - Relation.all.uniq_by{|r| [r.user_id, r.status]}).each{ |d| d.destroy }
</code>```

or

```<code> ids = Relation.all.uniq_by{|r| [r.user_id, r.status]}.map(&:id)
 Relation.where("id IS NOT IN (?)", ids).destroy_all # or delete_all, which is faster
</code>```

But I don't like this solution :D

Body:
I have to following table:

Relations

[id,user_id,status]
1,2,sent_reply
1,2,sent_mention
1,3,sent_mention
1,4,sent_reply
1,4,sent_mention

I am looking for a way to remove duplicates, so that only the following rows will remain:

1,2,sent_reply
1,3,sent_mention
1,4,sent_reply

(Preferably using Rails)

Body:
It is better to do it through SQL. But if you prefer to use Rails:

(Relation.all - Relation.all.uniq_by{|r| [r.user_id, r.status]}).each{ |d| d.destroy }

or

 ids = Relation.all.uniq_by{|r| [r.user_id, r.status]}.map(&:id)
 Relation.where("id IS NOT IN (?)", ids).destroy_all # or delete_all, which is faster

But I don't like this solution :D


问:
Parameterize Azure Blob Storage Linked Service in ADF
I would like to create an Azure Data Factory pipeline that copies a file to multiple storage accounts. My plan was to define the storage account connection info in a pipeline parameter as an array and use the ForEach activity to loop over each of the objects in the array passing the connection info to another pipeline.

```<code>    [
  {
    "destinationBlob": {
      "connectionString": "Conn1"
    }
  },
  {
    "destinationBlob": {
      "connectionString": "Conn2"
    }
  },
  {
    "destinationBlob": {
      "connectionString": "Conn3"
    }
  }
]
</code>```

My question is, is it possible to parameterize the connection to an Azure Blob Storage Linked Service?

答:
This can actually be done. Sample JSON:</p>
```<code>{
    "name": "DataLakeBlob",
    "type": "Microsoft.DataFactory/factories/linkedservices",
    "properties": {
        "parameters": {
            "StorageAccountEndpoint": {
                "type": "String",
                "defaultValue": "https://testblobstorage.blob.core.windows.net"
            }
        },
        "type": "AzureBlobStorage",
        "typeProperties": {
            "serviceEndpoint": "@{linkedService().StorageAccountEndpoint}"
        },
        "description": "Test Description"
    }
}
</code>```

Body:
I would like to create an Azure Data Factory pipeline that copies a file to multiple storage accounts. My plan was to define the storage account connection info in a pipeline parameter as an array and use the ForEach activity to loop over each of the objects in the array passing the connection info to another pipeline.

    [
  {
    "destinationBlob": {
      "connectionString": "Conn1"
    }
  },
  {
    "destinationBlob": {
      "connectionString": "Conn2"
    }
  },
  {
    "destinationBlob": {
      "connectionString": "Conn3"
    }
  }
]

My question is, is it possible to parameterize the connection to an Azure Blob Storage Linked Service?

Body:
This can actually be done. Sample JSON:

{
    "name": "DataLakeBlob",
    "type": "Microsoft.DataFactory/factories/linkedservices",
    "properties": {
        "parameters": {
            "StorageAccountEndpoint": {
                "type": "String",
                "defaultValue": "https://testblobstorage.blob.core.windows.net"
            }
        },
        "type": "AzureBlobStorage",
        "typeProperties": {
            "serviceEndpoint": "@{linkedService().StorageAccountEndpoint}"
        },
        "description": "Test Description"
    }
}


问:
What is the R equivalent to Stata's fillin?
Stata's fillin command makes a dataset rectangular.
How can I do the same in R?

As a reproducible example, say that I have the data below:

```<code>data <- data.frame(season = c("2016-17","2017-18","2018-19", "2018-19"), group=c("A","A","A","B"), value=c(1,2,3,6))
</code>```

I would like to get the following:

```<code>data_wanted <- data.frame(season = c("2016-17","2017-18","2018-19", "2018-19", "2016-17", "2017-18"), group=c("A","A","A","B","B","B"),value=c(1,2,3,6,NA,NA))
</code>```

答:
Using tidyr::complete, just specify that you want every combination of season and group:

```<code>tidyr::complete(data, season, group)
</code>```

Body:
Stata's fillin command makes a dataset rectangular.
How can I do the same in R?

As a reproducible example, say that I have the data below:

data <- data.frame(season = c("2016-17","2017-18","2018-19", "2018-19"), group=c("A","A","A","B"), value=c(1,2,3,6))

I would like to get the following:

data_wanted <- data.frame(season = c("2016-17","2017-18","2018-19", "2018-19", "2016-17", "2017-18"), group=c("A","A","A","B","B","B"),value=c(1,2,3,6,NA,NA))

Body:
Using tidyr::complete, just specify that you want every combination of season and group:

tidyr::complete(data, season, group)


问:
'this' argument to member function 'select' has type 'const SelectParam', but function is not marked const
I'm trying to call a function on a polymorphic item. But I get the following error message at compile time:

'this' argument to member function 'select' has type 'const SelectParam', but function is not marked const

the error is shown at the p->selection(*it)

```<code>std::set<Tuple>::iterator it;
for (it = tuples.begin(); it != tuples.end();) {
    for (const SelectParam* p: selectionParams) {
        bool successful = p->select(*it);
        if( !successful ) {
            it = tuples.erase(it);
        } else {
            it++;
        }
    }
}
</code>```

and here's how those classes are defined. (I use to not have all the const and & is there but I put them everywhere I could in hopes that I would make whatever it wanted const but clearly I'm not approaching the problem right since it's not changing anything.

In one of the child classes that is being stored at parent pointer.

```<code>bool const select(Tuple const & tup) {
    bool matched = false;
    if (tup[idx] == val) {
        matched = true;
    }
    return matched;
}
</code>```

In the other child class that is being used with polymorphism

```<code>bool const select(Tuple const & tup) {
    bool matched = false;
    if (tup[idx1] == tup[idx2]) {
        matched = true;
    }
    return matched;
}
</code>```

And finally here's the parent class that's super simple.

```<code>class SelectParam {
    public:
    virtual const bool select( Tuple const & t) = 0;
};
</code>```

Thanks in advance for being willing to help my feeble brain.

答:
You need to explicitly tell the compiler that your function will not modify any members:</p>

```<code>bool const select(Tuple const & tup) const {
</code>```

Body:
I'm trying to call a function on a polymorphic item. But I get the following error message at compile time:

'this' argument to member function 'select' has type 'const SelectParam', but function is not marked const

the error is shown at the p->selection(*it)

std::set<Tuple>::iterator it;
for (it = tuples.begin(); it != tuples.end();) {
    for (const SelectParam* p: selectionParams) {
        bool successful = p->select(*it);
        if( !successful ) {
            it = tuples.erase(it);
        } else {
            it++;
        }
    }
}

and here's how those classes are defined. (I use to not have all the const and & is there but I put them everywhere I could in hopes that I would make whatever it wanted const but clearly I'm not approaching the problem right since it's not changing anything.

In one of the child classes that is being stored at parent pointer.

bool const select(Tuple const & tup) {
    bool matched = false;
    if (tup[idx] == val) {
        matched = true;
    }
    return matched;
}

In the other child class that is being used with polymorphism

bool const select(Tuple const & tup) {
    bool matched = false;
    if (tup[idx1] == tup[idx2]) {
        matched = true;
    }
    return matched;
}

And finally here's the parent class that's super simple.

class SelectParam {
    public:
    virtual const bool select( Tuple const & t) = 0;
};

Thanks in advance for being willing to help my feeble brain.

Body:
You need to explicitly tell the compiler that your function will not modify any members:

bool const select(Tuple const & tup) const {


答:
Indeed, you cannot call a non-const method a const object. But you also cannot call a non-const method through a pointer or reference to a const object (regardless of whether the referred-to object is const or not).

This means that this:

```<code>const SelectParam* ptr = whatever();
ptr->select(someTuple);
</code>```

is ill-formed.

In your case, you've declared a pointer to a const SelectParam here on this line:

```<code>for (const SelectParam* p: selectionParams) {
</code>```

Simply remove the const and it should work :-)

On the other hand, if select is never meant to modify the object, simply mark it as const:

```<code>virtual const bool select( Tuple const & t) const = 0;
</code>```

And your code should also work.

Title: 'this' argument to member function 'select' has type 'const SelectParam', but function is not marked const

Body:
Indeed, you cannot call a non-const method a const object. But you also cannot call a non-const method through a pointer or reference to a const object (regardless of whether the referred-to object is const or not).

This means that this:

const SelectParam* ptr = whatever();
ptr->select(someTuple);

is ill-formed.

In your case, you've declared a pointer to a const SelectParam here on this line:

for (const SelectParam* p: selectionParams) {

Simply remove the const and it should work :-)

On the other hand, if select is never meant to modify the object, simply mark it as const:

virtual const bool select( Tuple const & t) const = 0;

And your code should also work.