问:
<AWS VPC> Unable to ping private subnet instance from a public subnet instance
May I seek for assistance about a lab exercise on AWS VPC that I was going through? Thanks.

I created a new VPC, a public and private subnet respectively, and then launched 2 EC2 instances into each of the subnet respectively. I also setup the security groups required for pinging (ICMP) access on the private subnet security group. However, I could not ping the instance in the private subnet from the instance in the public subnet.

Below are the setup:

VPC: (CIDR block 10.0.0.0/16)

Public subnet: (CIDR block 10.0.1.0/24)

Private subnet: (CIDR block 10.0.2.0/24)

Route table for public subnet:

Route table for private subnet:

Security group for public facing instance:

Security group for private facing instance: (All ICMP - IPv4 allowed from private subnet CIDR block)

Public facing EC2 instance launched in public subnet:

Private facing EC2 instance launched in private subnet:

SSH-ed into public instance, but then cannot ping private instance from there:

Additionally, tried to SSH into the private instance from the public instance (private key already added to public instance), also failed:

Thank you very for your help in advance.

答:
Finally found the problem, the security group for the public facing instance is missing an outbound rule.
When this is added back, the ping is successful.


来源: stackexchange

问:
How to modify new records for INSERT ON DUPLICATE in Mysql

Situation

Imagine a table columns A,B,C with a unique key on B and C and an autoincrement primary key on A

When sending new values (B,C) (42,1) and this table already contains a row with B,C being 42 and 1 on lets say ID 10, then the Mysql Server will not allow this and return :

```<code>Duplicate Entry ... for key ... .
</code>```

Problem:

I would like to act on this and modify (increment) the value for C, to 2, so (42,2) could be inserted.

Failed tried solution

I found the INSERT .. ON DUPLICATE UPDATE ... but this updates the existing record. not the new values.

Existing record may not be edited

I have no way to query the table beforehand, everything should be done in 1 query

incremented new values may also already exist, and thus should continue increment (c = 3..4..5...)

Any idea how this can be done ?

答:
Hmmm. I don't seen it as common feature on a database.
I had expirence with MySQL e Informix. I know which theses databases have a TRIGGER for some actions:

https://dev.mysql.com/doc/refman/8.0/en/trigger-syntax.html

I create a example with MySQL:

Schema

```<code>CREATE TABLE tb (A INT NOT NULL AUTO_INCREMENT PRIMARY KEY, B INT, C INT);
</code>```

Trigger

```<code>CREATE TRIGGER upd_c_column
BEFORE INSERT ON tb
FOR EACH ROW
SET NEW.C = (
    SELECT DISTINCT IFNULL(
        (SELECT IF(COUNT(*) IS NULL, 1, COUNT(*) + 1) AS B_ocurrences
        FROM tb sub_tb
        WHERE sub_tb.B = NEW.B
        GROUP BY sub_tb.B), 1)
);
</code>```

Insert test

```<code>INSERT INTO tb (B) VALUES (10), (10), (10), (10), (20), (20), (30);

SELECT * FROM tb;
+----+----+---+
| A  | B  | C |
+----+----+---+
| 73 | 10 | 1 |
| 74 | 10 | 2 |
| 75 | 10 | 3 |
| 76 | 10 | 4 |
| 77 | 20 | 1 |
| 78 | 20 | 2 |
| 79 | 30 | 1 |
+----+----+---+
</code>```

It resolve to INSERT... If you need do UPDATE ou DELETE you will need create others trigger with other strategies.

ContentLicense: CC BY-SA 4.0

Body:
Situation

Imagine a table columns A,B,C with a unique key on B and C and an autoincrement primary key on A

When sending new values (B,C) (42,1) and this table already contains a row with B,C being 42 and 1 on lets say ID 10, then the Mysql Server will not allow this and return :

Duplicate Entry ... for key ... .

Problem:

I would like to act on this and modify (increment) the value for C, to 2, so (42,2) could be inserted.

Failed tried solution

I found the INSERT .. ON DUPLICATE UPDATE ... but this updates the existing record. not the new values.

Existing record may not be edited

I have no way to query the table beforehand, everything should be done in 1 query

incremented new values may also already exist, and thus should continue increment (c = 3..4..5...)

Any idea how this can be done ?

Body:
Hmmm. I don't seen it as common feature on a database.
I had expirence with MySQL e Informix. I know which theses databases have a TRIGGER for some actions:

https://dev.mysql.com/doc/refman/8.0/en/trigger-syntax.html

I create a example with MySQL:

Schema

CREATE TABLE tb (A INT NOT NULL AUTO_INCREMENT PRIMARY KEY, B INT, C INT);

Trigger

CREATE TRIGGER upd_c_column
BEFORE INSERT ON tb
FOR EACH ROW
SET NEW.C = (
    SELECT DISTINCT IFNULL(
        (SELECT IF(COUNT(*) IS NULL, 1, COUNT(*) + 1) AS B_ocurrences
        FROM tb sub_tb
        WHERE sub_tb.B = NEW.B
        GROUP BY sub_tb.B), 1)
);

Insert test

INSERT INTO tb (B) VALUES (10), (10), (10), (10), (20), (20), (30);

SELECT * FROM tb;
+----+----+---+
| A  | B  | C |
+----+----+---+
| 73 | 10 | 1 |
| 74 | 10 | 2 |
| 75 | 10 | 3 |
| 76 | 10 | 4 |
| 77 | 20 | 1 |
| 78 | 20 | 2 |
| 79 | 30 | 1 |
+----+----+---+

It resolve to INSERT... If you need do UPDATE ou DELETE you will need create others trigger with other strategies.


问:
Understanding pointers in C using example code
I am learning pointers in C, so I am looking at one example. I tried to add comments to understand what is going on. Is the following code correct? In other words, do my comments describe the operation correctly?

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <math.h>

int main(){

    int x, y;
    int *p1, *p2;

    x=-42;
    y=163;

    p1=&x; //pointer 1 points to the address of x
    p2=&y; //pointer 2 points to the address of y

    *p1=17; //this just made x=17 because it says that the value at the address where p1 points should be 17
    p1=p2; //this just made pointer 1 point at the same place as pointer 2, which means that p1 now points at y

    p2=&x; //this just made pointer 2 point at the address of x

    //NOW WE HAVE: p1 points at y, p2 points at x, y=17 because of p1

    *p1=*p2; //now x=17 as well as y (because the value at the place p2 points, which is x, just became 17)

    printf("x=%d, \ny=%d\n", x, y);

    return 0;
}
```

答:
"Check the debugger", for sure.  You can also just copy your printf statement after each time you set a value to check, since you're just learning, but this isn't good long-term practice.

I'm not sure if you've quite got the concept and just made a typo mixing up x and y, or if you're making an incorrect assumption, but yes, in your comments:

//NOW WE HAVE: p1 points at y, p2 points at x, y=17 because of p1

you have the location of p1 and p2 correct at this point, but y has not received an assignment since you gave it the value of 163 initially.  Assignments to *p1 will affect y, but only after the p1=p2 line.
At the point of this comment, x=17, because of the *p1=17 line a few line up.  y is unchanged from the initial assignment.

*p1=*p2; //now x=17 as well as y (because the value at the place p2 points, which is x, just became 17)

y becomes 17 here, as *p1 (which is now y) is assigned the value in *p2, which, as you state, is x.


问:
Creating another Thread
I'm doing too much work on the main thread, and so I want to learn how to run some things on other threads. But I'm having difficulties understanding how threads work.

From what I've gathered, you can no longer stop or cancel a thread, and the way that I need it to work is that, if Button A is clicked, do the function, if Button B is clicked, stop as to not use resources.

Here's where I stand:

```<code>> //Inside OnCreate

Thread newthread = new Thread(new Runnable(){

            @Override

            public void run(){

                while(bool) {
                    ...
                }
                    ...
            }
        });
        newthread.start();

Button A Listener(){
bool = true;
}

Button A Listener(){
bool = false;
}
</code>```

when I first start the thread it runs, but after changing bool to false, and back to true it doesn't.

putting return at the end destroys the thread, but calling start again isn't allowed.

I've tried putting 2 while loops, but it still doesn't switch between the loops.

Is there even a reason to use interrupt? and how would it be implemented?

What I need is to create another thread, have it keep doing something until I click button A, then resume when I click on Button B, that's all.

答:
but calling start again isn't allowed.

Not sure why don't you can not call start again, but I think it's good solution. Base on your requirement tries this code put inside run

```<code>      while (!Thread.currentThread().isInterrupted()) {
          try {
              if (loop) {
                  ...
              }
          } catch (InterruptedException e) {
              return;
          }
      }
</code>```

Why we need to check Thread.currentThread().isInterrupted() because when your Activity destroy you should call newthread.interrupt() to release your Thread because it can be leak memory.

Title: Creating another Thread

Body:
I'm doing too much work on the main thread, and so I want to learn how to run some things on other threads. But I'm having difficulties understanding how threads work.

From what I've gathered, you can no longer stop or cancel a thread, and the way that I need it to work is that, if Button A is clicked, do the function, if Button B is clicked, stop as to not use resources.

Here's where I stand:

> //Inside OnCreate

Thread newthread = new Thread(new Runnable(){

            @Override

            public void run(){

                while(bool) {
                    ...
                }
                    ...
            }
        });
        newthread.start();

Button A Listener(){
bool = true;
}

Button A Listener(){
bool = false;
}

when I first start the thread it runs, but after changing bool to false, and back to true it doesn't.

putting return at the end destroys the thread, but calling start again isn't allowed.

I've tried putting 2 while loops, but it still doesn't switch between the loops.

Is there even a reason to use interrupt? and how would it be implemented?

What I need is to create another thread, have it keep doing something until I click button A, then resume when I click on Button B, that's all.

Body:
but calling start again isn't allowed.

Not sure why don't you can not call start again, but I think it's good solution. Base on your requirement tries this code put inside run

      while (!Thread.currentThread().isInterrupted()) {
          try {
              if (loop) {
                  ...
              }
          } catch (InterruptedException e) {
              return;
          }
      }

Why we need to check Thread.currentThread().isInterrupted() because when your Activity destroy you should call newthread.interrupt() to release your Thread because it can be leak memory.


问:
Converting a function's parameter - signature from using an `std::function<T>` to a template parameter type
In my existing codebase, I have a non-template class and its constructor has the following declaration signature...

```<code>struct SomeStruct {
    double a_;
    double b_;
    SomeStruct(double a, double b) : a_{a}, b_{b} {}
}

class SomeClass {
private:
    SomeStruct fields_;
    size_t n_;
    std::function<double(double)> func_;
public:
    SomeClass(SomeStruct fields, size_t n, std::function<double(double)> func) :
      fields_{fields}, n_{n}, func_{func}
    {}
};
</code>```

I was using it like this:

```<code>constexpr double funcA(double x) {
    return x;
}

constexpr double funcB(double x) {
    return x*x;
}

int main() {
    SomeClass a(SomeStruct{1.0, 5.0}, 1000, &funcA);
    SomeClass b(SomeStruct{3.5, 7.7}, 2000, &funcB);

    return 0;
}
</code>```

And the above representation works just fine...

I'm in the process of refactoring my code and I want to template my class and I'm trying to allow the class and its member functions to be defined fully as constexpr...

The new signature of my classes ought to look like this:

```<code>template<typename Field>
struct SomeStruct {
    Field a_;
    Field b_;
    constexpr SomeStruct(Field a, Field b) : a_{a}, b_{b} {}
};

template<typename FieldType, typename ValueType, typename Func>
class SomeClass {
    SomeStruct<FieldType> fields_;
    size_t n_;
    // std::function<double(double)> func_; // No longer using `std::function` since I want this to be constexpr
    Func* func_; // would like to save a pointer to a function, functor, function object, or lambda instead...
   public:
    SomeClass(SomeStruct<FieldType> fields, size_t n, Func* func) :
      fields_{fields}, n_{n}, func_{func}
    {}
};
</code>```

There are two issues or problems that I'm having here or struggling with...

The ValueType template argument should be a part of the Func template argument... And as a side note, all of the function pointers, functors, lambdas, etc. currently have the form of accepting a single parameter of type T and they are returning a value of type T.

The other issue which is the "more important" issue involves when I try to instantiate an object...

```<code>SomeClass<double, double, ?> a{ SomeStruct{ 3.0, 5.0 }, 1000, &funcA };
</code>```

I'm getting confused about the syntax for the template arguments for the function pointers... along with being able to pass in a function as an object...

答:
I would suggest not specifying the template parameters for the constructor, but instead provide a deduction guide like this:

```<code>template<typename FieldType, typename ValueType, typename Func>
SomeClass(SomeStruct<FieldType>, ValueType, Func*)
 -> SomeClass<FieldType, ValueType, Func>;
</code>```

and then you can call the constructor like this:

```<code>SomeClass a{ SomeStruct{ 3.0, 5.0 }, 1000, &funcA };
</code>```

Here's a demo.

Additionally, there's no reason to store the function as a pointer, you could just store it as an object. As pointed out in the comments, this has the advantage that you can now store stateful lambdas as well.

Here's a demo of that.

Body:
In my existing codebase, I have a non-template class and its constructor has the following declaration signature...

struct SomeStruct {
    double a_;
    double b_;
    SomeStruct(double a, double b) : a_{a}, b_{b} {}
}

class SomeClass {
private:
    SomeStruct fields_;
    size_t n_;
    std::function<double(double)> func_;
public:
    SomeClass(SomeStruct fields, size_t n, std::function<double(double)> func) :
      fields_{fields}, n_{n}, func_{func}
    {}
};

I was using it like this:

constexpr double funcA(double x) {
    return x;
}

constexpr double funcB(double x) {
    return x*x;
}

int main() {
    SomeClass a(SomeStruct{1.0, 5.0}, 1000, &funcA);
    SomeClass b(SomeStruct{3.5, 7.7}, 2000, &funcB);

    return 0;
}

And the above representation works just fine...

I'm in the process of refactoring my code and I want to template my class and I'm trying to allow the class and its member functions to be defined fully as constexpr...

The new signature of my classes ought to look like this:

template<typename Field>
struct SomeStruct {
    Field a_;
    Field b_;
    constexpr SomeStruct(Field a, Field b) : a_{a}, b_{b} {}
};

template<typename FieldType, typename ValueType, typename Func>
class SomeClass {
    SomeStruct<FieldType> fields_;
    size_t n_;
    // std::function<double(double)> func_; // No longer using `std::function` since I want this to be constexpr
    Func* func_; // would like to save a pointer to a function, functor, function object, or lambda instead...
   public:
    SomeClass(SomeStruct<FieldType> fields, size_t n, Func* func) :
      fields_{fields}, n_{n}, func_{func}
    {}
};

There are two issues or problems that I'm having here or struggling with...

The ValueType template argument should be a part of the Func template argument... And as a side note, all of the function pointers, functors, lambdas, etc. currently have the form of accepting a single parameter of type T and they are returning a value of type T.

The other issue which is the "more important" issue involves when I try to instantiate an object...

SomeClass<double, double, ?> a{ SomeStruct{ 3.0, 5.0 }, 1000, &funcA };

I'm getting confused about the syntax for the template arguments for the function pointers... along with being able to pass in a function as an object...

Body:
I would suggest not specifying the template parameters for the constructor, but instead provide a deduction guide like this:

template<typename FieldType, typename ValueType, typename Func>
SomeClass(SomeStruct<FieldType>, ValueType, Func*)
 -> SomeClass<FieldType, ValueType, Func>;

and then you can call the constructor like this:

SomeClass a{ SomeStruct{ 3.0, 5.0 }, 1000, &funcA };

Here's a demo.

Additionally, there's no reason to store the function as a pointer, you could just store it as an object. As pointed out in the comments, this has the advantage that you can now store stateful lambdas as well.

Here's a demo of that.


问:
WTForm used in two different views validate only using one view
I'm having a problem using a WTForm in two different views. One view creates a new item, using the form data. The other view display information for items already in the database and the user should be able to update the form data from there.

I can create and view the items in the database. The problem is updating the information when in in the display view. The steps I take are something like:

Create a item in /create. Before saving to database check that the same ID is not already in database. If exists show a flash and do not permit saving the item. Reloading /create

To display information about a existing item the route /display/<item> call the database, populate the form and show the information using the same form.

Desired behavior

To update information when in /display/<item>. After updating any field data and pressing the submit button, the form should save to the database and reload /display/<item>.

Actual behavior

After pressing the submit button the form takes me back to the /create route, and performs the ID validation.

I don't understand why, being in a different view /display/<item>, the form's submit button takes me to the /create view.

The code goes something like this:

This is a simple form

```<code>    class ItemForm(FlaskForm):
        id = IntegerField("id", validators=[DataRequired()])
        name = StringField("Email", validators=[DataRequired()])
        submit = SubmitField("Submit")
</code>```

With this I create a new item in the database, checking that the same Id is not already in the database:

```<code>    @app.route("/create", methods=["GET", "POST"])
    def create():
        form = ItemForm()

        if form.validate_on_submit():
            item = item = Item.query.filter(Item.id == form.id).first()
            # Check the same id is not already created
            if item is not None:
                flash('item already in database')
                return redirect(url_for("create"))

            item = Item()
            form.populate_obj(item)
            db.session.add(item)
            db.session.commit()
            return redirect(url_for("display", item = form.id))
        else:
            return render_template("create.html", form=form)
</code>```

And then after there is created items in the database i can call a display route. In this route I should be able to update the fields in the form and save it to the database. Whit out validating as the the same ID is already present in the database (I'm updating, no creating a new one).

```<code>@app.route("/display/<item>", methods=["GET", "POST"])
def display(item):
    item = Item.query.filter(Item.id == item).first()
    form = ItemForm(obj=item)

    if form.validate_on_submit():
        form.populate_obj(item)
        db.session.add(item)
        db.session.commit()
        return redirect(url_for("display", item=form.id))
    else:
        return render_template("display.html", form=form)
</code>```

The problem is that when in the /display/<item> route, the submit button takes me back to the /create route. Performing the validations in there. Of course the item is already created in the database so I get the flash and I'm redirected to /create, when it should reload /display/<item>.

Could someone point me in the right direction, please. Thank you all!

答:
My mistake, but @the_gañañufla asked the right question. The problems of coding alone.

I had added an action to the HTML  and i forgot to remove it.

I had

<form id="form_item" action="{{ url_for('create') }}" class="form" method=post>
```

<p>After correct it I have:</p>

<pre class="lang-html prettyprint-override"><code><form id="form_product" action="" class="form" method=post>
</code>```

Body:
I'm having a problem using a WTForm in two different views. One view creates a new item, using the form data. The other view display information for items already in the database and the user should be able to update the form data from there.

I can create and view the items in the database. The problem is updating the information when in in the display view. The steps I take are something like:

Create a item in /create. Before saving to database check that the same ID is not already in database. If exists show a flash and do not permit saving the item. Reloading /create

To display information about a existing item the route /display/<item> call the database, populate the form and show the information using the same form.

Desired behavior

To update information when in /display/<item>. After updating any field data and pressing the submit button, the form should save to the database and reload /display/<item>.

Actual behavior

After pressing the submit button the form takes me back to the /create route, and performs the ID validation.

I don't understand why, being in a different view /display/<item>, the form's submit button takes me to the /create view.

The code goes something like this:

This is a simple form

    class ItemForm(FlaskForm):
        id = IntegerField("id", validators=[DataRequired()])
        name = StringField("Email", validators=[DataRequired()])
        submit = SubmitField("Submit")

With this I create a new item in the database, checking that the same Id is not already in the database:

    @app.route("/create", methods=["GET", "POST"])
    def create():
        form = ItemForm()

        if form.validate_on_submit():
            item = item = Item.query.filter(Item.id == form.id).first()
            # Check the same id is not already created
            if item is not None:
                flash('item already in database')
                return redirect(url_for("create"))

            item = Item()
            form.populate_obj(item)
            db.session.add(item)
            db.session.commit()
            return redirect(url_for("display", item = form.id))
        else:
            return render_template("create.html", form=form)

And then after there is created items in the database i can call a display route. In this route I should be able to update the fields in the form and save it to the database. Whit out validating as the the same ID is already present in the database (I'm updating, no creating a new one).

@app.route("/display/<item>", methods=["GET", "POST"])
def display(item):
    item = Item.query.filter(Item.id == item).first()
    form = ItemForm(obj=item)

    if form.validate_on_submit():
        form.populate_obj(item)
        db.session.add(item)
        db.session.commit()
        return redirect(url_for("display", item=form.id))
    else:
        return render_template("display.html", form=form)

The problem is that when in the /display/<item> route, the submit button takes me back to the /create route. Performing the validations in there. Of course the item is already created in the database so I get the flash and I'm redirected to /create, when it should reload /display/<item>.

Could someone point me in the right direction, please. Thank you all!

Body:
My mistake, but @the_gañañufla asked the right question. The problems of coding alone.

I had added an action to the HTML  and i forgot to remove it.

I had

<form id="form_item" action="{{ url_for('create') }}" class="form" method=post>

After correct it I have:

<form id="form_product" action="" class="form" method=post>


问:
Huawei HIAI Engine "General text recognition" is not detecting any text from an image
When using "General text recognition" from HIAI Engine I can't make it detect and return any text. For instance for the sample image it returns empty text but with code 200. I used an example program from the HIAI documentation, so I don't know where the problem is. So i created another app from scratch and results are the same.

答: The basic capabilities of Huawei HIAI include face recognition, image recognition, natural language processing, language recognition, code detection and so on. If the text in the  picture is not recognized, it is recommended to use the picture with high contrast.</p>


问:
Why can't I directly return reference to a pointer from a function returning a pointer?
In C++, this code does not compile:

```<code>double* value() {
    return nullptr;
}

double*& function() {
    return value();
}
</code>```

Error: Non-const lvalue reference to type 'double *' cannot bind to a temporary of type 'double *'

However, this code does compile without errors:

```<code>double* value() {
    return nullptr;
}

double*& function() {
    double* valueVar = value();
    return valueVar;
}
</code>```

Can someone explain to me why? I would've thought they did exactly the same thing, to me the second code just looks redundant.

答:
value() returns pointer by value, what it returns is an rvalue and can't be bound to lvalue-reference to non-const like double* &, so your 1st code snippet doesn't compile.

In the 2nd code snippet you're binding a local object to the reference. valueVar is an lvalue and could be bound to the lvalue-reference to non-const, but note that the local object will be destroyed when the function returns, then the returned reference will always be dangled, any dereference on it leads to UB.

Body:
In C++, this code does not compile:

double* value() {
    return nullptr;
}

double*& function() {
    return value();
}

Error: Non-const lvalue reference to type 'double *' cannot bind to a temporary of type 'double *'

However, this code does compile without errors:

double* value() {
    return nullptr;
}

double*& function() {
    double* valueVar = value();
    return valueVar;
}

Can someone explain to me why? I would've thought they did exactly the same thing, to me the second code just looks redundant.


问:
How do I run compile and run a c file on an AWS EC2 Linux Instance?
I am trying to run an executable compiled from a c file on an AWS EC2 Linux Instance and when i try to run the executable I get a bash: command not found error and cant figure out why, below is my terminal commands.

```<code>`[ec2-user@ip-172-31-7-57 ~]$ gcc server.c -o server
[ec2-user@ip-172-31-7-57 ~]$ ls
server  server.c  test
[ec2-user@ip-172-31-7-57 ~]$ server 51717
-bash: server: command not found
[ec2-user@ip-172-31-7-57 ~]$ `
</code>```

The only install I have run is

```<code>sudo yum groupinstall "Development Tools"
</code>```

inorder to install gcc for compilation. Am I missing an install here?

答:
Unlike windows systems, Linux systems don't look in the current directory by default when looking for a program to run.  You need to give the path to the executable.</p>

```<code>./server 51717
</code>```

Body:
I am trying to run an executable compiled from a c file on an AWS EC2 Linux Instance and when i try to run the executable I get a bash: command not found error and cant figure out why, below is my terminal commands.

`[ec2-user@ip-172-31-7-57 ~]$ gcc server.c -o server
[ec2-user@ip-172-31-7-57 ~]$ ls
server  server.c  test
[ec2-user@ip-172-31-7-57 ~]$ server 51717
-bash: server: command not found
[ec2-user@ip-172-31-7-57 ~]$ `

The only install I have run is

sudo yum groupinstall "Development Tools"

inorder to install gcc for compilation. Am I missing an install here?

Body:
Unlike windows systems, Linux systems don't look in the current directory by default when looking for a program to run.  You need to give the path to the executable.

./server 51717


问:
How to create new instances of objects with custom SpecimenBuilder with AutoFixture
Currently I have such code:

```<code>private ConnectedClient WithConnection(IConnection connection)
{
    var builder = new ClientWithConnectionSpecimenBuilder(connection);

    Fixture.Customizations.Add(builder);
    var client = Fixture.Create<ConnectedClient>();
    Fixture.Customizations.Remove(builder);

    return client;
}
</code>```

Basically I need to create new instances of ConnectedClient class in my tests code with specified connection. And I've built custom specimen builder to do it.

But there is no method like

```<code>Fixture.Create<T>(specimenBuilder)
</code>```

so I need to customize the fixture.

"Fixture" there is the inherited protected property of my base tests class that is already set up with some custom AutoMoqData customization so I need to reuse it for creating objects.

答:
It should be possible to use the one-off Build method to customize using a particular specimen builder:

var client = fixture.Build<ConnectedClient>().FromFactory(builder).Create();
```

<p>Note that doing this will disable any other customizations from the fixture.</p>

<p>The DSL supports a bit more customization using <code>With</code> and <code>Without</code>, so if there's some additional customization you want to do on properties, you can do that:</p>

<pre class="lang-cs prettyprint-override"><code>var client = fixture.Build<ConnectedClient>()
    .FromFactory(builder)
    .With(cc => cc.SomeProperty, () => fixture.Build<T>().FromFactory(otherFactory).Create())
    .Create();
</code>```

But that will get pretty tedious for significant customization. Autofixture is opinionated in this way.

The Build method is really intended as a one-off solution. If you want to rely more on the machinery of Autofixture to do everything except for creating the client connection, I would suggest relying on the existing Freeze method and Frozen attribute to keep the injected  IConnection the same for a given ConnectedClient, which would obviate the need for a specific ISpecimenBuilder.

Body:
Currently I have such code:

private ConnectedClient WithConnection(IConnection connection)
{
    var builder = new ClientWithConnectionSpecimenBuilder(connection);

    Fixture.Customizations.Add(builder);
    var client = Fixture.Create<ConnectedClient>();
    Fixture.Customizations.Remove(builder);

    return client;
}

Basically I need to create new instances of ConnectedClient class in my tests code with specified connection. And I've built custom specimen builder to do it.

But there is no method like

Fixture.Create<T>(specimenBuilder)

so I need to customize the fixture.

"Fixture" there is the inherited protected property of my base tests class that is already set up with some custom AutoMoqData customization so I need to reuse it for creating objects.

Body:
It should be possible to use the one-off Build method to customize using a particular specimen builder:

var client = fixture.Build<ConnectedClient>().FromFactory(builder).Create();

Note that doing this will disable any other customizations from the fixture.

The DSL supports a bit more customization using With and Without, so if there's some additional customization you want to do on properties, you can do that:

var client = fixture.Build<ConnectedClient>()
    .FromFactory(builder)
    .With(cc => cc.SomeProperty, () => fixture.Build<T>().FromFactory(otherFactory).Create())
    .Create();

But that will get pretty tedious for significant customization. Autofixture is opinionated in this way.

The Build method is really intended as a one-off solution. If you want to rely more on the machinery of Autofixture to do everything except for creating the client connection, I would suggest relying on the existing Freeze method and Frozen attribute to keep the injected  IConnection the same for a given ConnectedClient, which would obviate the need for a specific ISpecimenBuilder.


问:
How do I get the next line from a file
I am implemting a program using c++, and i have a problem of geting the next line from an input file. I used:

```<code>   const MAX 300;
   char oneline[MAX];
   ifstream in;
   in.open("input.txt);
   in.getline(oneline,MAX);
</code>```

The function getline always gets me the first line in the file. The thing is, how can I get the next line in the file?

答:
```<code>while (getline(in,line,'\n')){
    //do something with line
}
</code>```

ContentLicense: CC BY-SA 3.0

Title: How do I get the next line from a file

Body:
I am implemting a program using c++, and i have a problem of geting the next line from an input file. I used:

   const MAX 300;
   char oneline[MAX];
   ifstream in;
   in.open("input.txt);
   in.getline(oneline,MAX);

The function getline always gets me the first line in the file. The thing is, how can I get the next line in the file?


问:
PowerShell - Why does Get-ChildItem does not return any output
I'm trying to get the filenames that are created within a datetime range.

```<code>[datetime]$start = '2020-06-01 10:00:00'
[datetime]$end = '2020-06-01 11:00:00'
Get-ChildItem -Path C:\Test -Name | Where-Object { $_.LastWriteTime -gt $start -and $_.LastWriteTime -lt $end }
</code>```

Why does this piece of code doesnt return me anything?

答:
Using the -Name parameter returns only the name of the file as a String type instead of an object. Therefore it has no LastWriteTime attribute to search against.

https://learn.microsoft.com/en-us/powershell/module/microsoft.powershell.management/get-childitem?view=powershell-7

PS C:\> (gci)[0].GetType()

IsPublic IsSerial Name                                     BaseType
-------- -------- ----                                     --------
True     True     DirectoryInfo                            System.IO.FileSystemInfo

PS C:\> (gci -Name)[0].GetType()

IsPublic IsSerial Name                                     BaseType
-------- -------- ----                                     --------
True     True     String                                   System.Object
```

<pre class="lang-bsh prettyprint-override"><code>PS C:\> gci

    Directory: C:\

Mode                LastWriteTime         Length Name
----                -------------         ------ ----
d-----        2/11/2019  12:08 AM                %homeshare%
d-----        5/12/2019   2:54 PM                Code
d-----       21/03/2019   5:11 PM                Intel
d-----       28/10/2019   9:54 AM                Microsoft
d-----       13/12/2019   5:15 PM                NVIDIA
d-r---       28/05/2020   7:27 PM                Program Files
d-r---        4/05/2020  11:00 AM                Program Files (x86)
d-r---       17/02/2020   1:43 PM                Users
d-----       31/05/2020  10:50 PM                Windows
</code>```

VS -Name

PS C:\> gci -Name
%homeshare%
Code
Intel
Microsoft
NVIDIA
Program Files
Program Files (x86)
Users
Windows
```

<p>You can filter the object, then select the names if that is required:</p>

<pre class="lang-bsh prettyprint-override"><code>PS C:\> gci | Where-Object { $_.LastWriteTime -gt (Get-Date -Year 2020 -Month 1 -Day 10) } | Select-Object Name

Name
----
Program Files
Program Files (x86)
Users
Windows
SUService.log
</code>```

If you need the file path instead of the file name, you can use FullName:

FullName
--------
C:\Program Files
C:\Program Files (x86)
```

Body:
I'm trying to get the filenames that are created within a datetime range.

[datetime]$start = '2020-06-01 10:00:00'
[datetime]$end = '2020-06-01 11:00:00'
Get-ChildItem -Path C:\Test -Name | Where-Object { $_.LastWriteTime -gt $start -and $_.LastWriteTime -lt $end }

Why does this piece of code doesnt return me anything?

Body:
Using the -Name parameter returns only the name of the file as a String type instead of an object. Therefore it has no LastWriteTime attribute to search against.

https://learn.microsoft.com/en-us/powershell/module/microsoft.powershell.management/get-childitem?view=powershell-7

PS C:\> (gci)[0].GetType()

IsPublic IsSerial Name                                     BaseType
-------- -------- ----                                     --------
True     True     DirectoryInfo                            System.IO.FileSystemInfo

PS C:\> (gci -Name)[0].GetType()

IsPublic IsSerial Name                                     BaseType
-------- -------- ----                                     --------
True     True     String                                   System.Object

PS C:\> gci

    Directory: C:\

Mode                LastWriteTime         Length Name
----                -------------         ------ ----
d-----        2/11/2019  12:08 AM                %homeshare%
d-----        5/12/2019   2:54 PM                Code
d-----       21/03/2019   5:11 PM                Intel
d-----       28/10/2019   9:54 AM                Microsoft
d-----       13/12/2019   5:15 PM                NVIDIA
d-r---       28/05/2020   7:27 PM                Program Files
d-r---        4/05/2020  11:00 AM                Program Files (x86)
d-r---       17/02/2020   1:43 PM                Users
d-----       31/05/2020  10:50 PM                Windows

VS -Name

PS C:\> gci -Name
%homeshare%
Code
Intel
Microsoft
NVIDIA
Program Files
Program Files (x86)
Users
Windows

You can filter the object, then select the names if that is required:

PS C:\> gci | Where-Object { $_.LastWriteTime -gt (Get-Date -Year 2020 -Month 1 -Day 10) } | Select-Object Name

Name
----
Program Files
Program Files (x86)
Users
Windows
SUService.log

If you need the file path instead of the file name, you can use FullName:

FullName
--------
C:\Program Files
C:\Program Files (x86)


问:
Getting all messages from Microsoft Teams
I'm trying to get all the messages from Microsoft Teams in my tenant, I have registered the application to Azure, set the correct permissions and grated admin privileges.

What I am getting confused about is creating a GraphServiceClient.
My app is more of an Daemon Application.
I would really appreciate if someone could give me an example of how to create the client correctly.

this is my code so far:

```<code>            string[] graphScopes = { "https://graph.microsoft.com/.default" };
            IConfidentialClientApplication app = ConfidentialClientApplicationBuilder
            .Create("x")
            .WithTenantId("x")
            .WithClientSecret("x")
            .Build();

            ClientCredentialProvider authProvider = new ClientCredentialProvider(app);
            GraphServiceClient graphClient = new GraphServiceClient(authProvider);
            try
            {
                var messages = await graphClient.Teams["x"].Channels["x@thread.skype"].Messages.Request().GetAsync();
                Console.ReadLine();
                foreach(var item in messages)
                {
                    Console.WriteLine(item.Body);
                }
            }
            catch(Exception e)

            {
                Console.WriteLine(e.Message);
                Console.Read();
            }
</code>```

I'm getting the following error no matter what I'm trying to get
Code: UnknownError                                                                                Inner error:                                                                                AdditionalData:                                                                                request-id: x                                                                        date: 2020-05-27T14:22:37                                                                                ClientRequestId:x

update: I was able to get something from the API, I had wrong permissions.
still can't get the messages though,
I have all these permission:
ChannelMessage.Read.All, Group.Read.All, Group.ReadWrite.All
I'm probably missing the "ChannelMessage.Read.Group (RSC)" permission but I can't find it in the permissions page.

答:
Your problem is you are accessing a "beta" api but using the production base url path.

The permission you need is ANY of the following (i.e. or not and):

ChannelMessage.Read.Group (RSC) OR

ChannelMessage.Read.All OR

Group.Read.All OR

Group.ReadWrite.All

Since you have Group.Read.All, that is ALL you need for permissions.

What you need to do is change the base URL to the beta api:

```<code>graphClient.BaseUrl = "https://graph.microsoft.com/beta";
</code>```

UPDATED:

Since now you are saying that you are getting a "Forbidden" error, I think you also have a consent problem.

My guess is that you created & consented you app on one tenant but you are trying to access the data in another tenant.  This will give you a forbidden errors. i.e. you created and consented on a dev azure account tenant and are trying to access your work tenant.

If this is the situation you need to:
* Make sure that the setup you azure app to be multi-tenanted
* You have to get your app consented by the target tenant

If you do that and use the beta endpoint I would expect that your example code will start working.

Update2:

Finally got around to trying to do the message list with a application context like you above and I get the same Forbidden error as well from the beta api.  From a user context it works fine.  So your answer will be to use a user context and not an application context to access this API.

It looks like what you are hitting is a Protected API.  So if you want to use this API from an application context, you will have to submit a request to be allowed access to it.

Body:
I'm trying to get all the messages from Microsoft Teams in my tenant, I have registered the application to Azure, set the correct permissions and grated admin privileges.

What I am getting confused about is creating a GraphServiceClient.
My app is more of an Daemon Application.
I would really appreciate if someone could give me an example of how to create the client correctly.

this is my code so far:

            string[] graphScopes = { "https://graph.microsoft.com/.default" };
            IConfidentialClientApplication app = ConfidentialClientApplicationBuilder
            .Create("x")
            .WithTenantId("x")
            .WithClientSecret("x")
            .Build();

            ClientCredentialProvider authProvider = new ClientCredentialProvider(app);
            GraphServiceClient graphClient = new GraphServiceClient(authProvider);
            try
            {
                var messages = await graphClient.Teams["x"].Channels["x@thread.skype"].Messages.Request().GetAsync();
                Console.ReadLine();
                foreach(var item in messages)
                {
                    Console.WriteLine(item.Body);
                }
            }
            catch(Exception e)

            {
                Console.WriteLine(e.Message);
                Console.Read();
            }

I'm getting the following error no matter what I'm trying to get
Code: UnknownError                                                                                Inner error:                                                                                AdditionalData:                                                                                request-id: x                                                                        date: 2020-05-27T14:22:37                                                                                ClientRequestId:x

update: I was able to get something from the API, I had wrong permissions.
still can't get the messages though,
I have all these permission:
ChannelMessage.Read.All, Group.Read.All, Group.ReadWrite.All
I'm probably missing the "ChannelMessage.Read.Group (RSC)" permission but I can't find it in the permissions page.

Body:
Your problem is you are accessing a "beta" api but using the production base url path.

The permission you need is ANY of the following (i.e. or not and):

ChannelMessage.Read.Group (RSC) OR

ChannelMessage.Read.All OR

Group.Read.All OR

Group.ReadWrite.All

Since you have Group.Read.All, that is ALL you need for permissions.

What you need to do is change the base URL to the beta api:

graphClient.BaseUrl = "https://graph.microsoft.com/beta";

UPDATED:

Since now you are saying that you are getting a "Forbidden" error, I think you also have a consent problem.

My guess is that you created & consented you app on one tenant but you are trying to access the data in another tenant.  This will give you a forbidden errors. i.e. you created and consented on a dev azure account tenant and are trying to access your work tenant.

If this is the situation you need to:
* Make sure that the setup you azure app to be multi-tenanted
* You have to get your app consented by the target tenant

If you do that and use the beta endpoint I would expect that your example code will start working.

Update2:

Finally got around to trying to do the message list with a application context like you above and I get the same Forbidden error as well from the beta api.  From a user context it works fine.  So your answer will be to use a user context and not an application context to access this API.

It looks like what you are hitting is a Protected API.  So if you want to use this API from an application context, you will have to submit a request to be allowed access to it.


问:
understand file processing with While vs For Loop
I am trying to read a large file using several methods. So my code is supposed to look for and count how many times the text "time_data" shows up in a file. The total count is actually 24. However using the code I havee, it only finds 4 counts of it using a while loop:

```<code>with open(filename) as f:
    time_data_count = 0
    while True:
        memcap = f.read(102400)
        if 'TIME_DATA' in memcap:
            time_data_count += 1
        if not memcap:
            break
    if time_data_count > 20:
        print("time_data complete")
    else:
        print("incomplete time_data data")
</code>```

Why is time_data_count only returning a count of 4? It's supposed to search through all of memcap and look increment each time it finds "time_data". I don't have this issue when I use a for loop like so:

```<code>with open(filename, 'r', buffering=102400) as f:
    time_data_count = 0
    for line in f:
        if 'TIME_DATA' in line:
            time_data_count += 1
    if time_data_count > 20:
        print("time_data complete")
    else:
        print("incomplete time_data data")
</code>```

What am I missing? Yes the file does indeed have newlines

答:
Use time_data_count += memcap.count('TIME_DATA') to count the occurrences of 'TIME_DATA_ in the memcap string. This will not count items if they get sliced in half between chunks of the file.

with open(filename) as f:
    time_data_count = 0
    while True:
        memcap = f.read(102400)
        if 'TIME_DATA' in memcap:
            # add the number of occurrences
            time_data_count += memcap.count('TIME_DATA')
        if not memcap:
            break
    if time_data_count > 20:
        print("time_data complete")
    else:
        print("incomplete time_data data")
```

The issue with your original code is the counter would only increment if the  item was found in the string regardless of how many occurrences, not for each occurrence.

Body:
I am trying to read a large file using several methods. So my code is supposed to look for and count how many times the text "time_data" shows up in a file. The total count is actually 24. However using the code I havee, it only finds 4 counts of it using a while loop:

with open(filename) as f:
    time_data_count = 0
    while True:
        memcap = f.read(102400)
        if 'TIME_DATA' in memcap:
            time_data_count += 1
        if not memcap:
            break
    if time_data_count > 20:
        print("time_data complete")
    else:
        print("incomplete time_data data")

Why is time_data_count only returning a count of 4? It's supposed to search through all of memcap and look increment each time it finds "time_data". I don't have this issue when I use a for loop like so:

with open(filename, 'r', buffering=102400) as f:
    time_data_count = 0
    for line in f:
        if 'TIME_DATA' in line:
            time_data_count += 1
    if time_data_count > 20:
        print("time_data complete")
    else:
        print("incomplete time_data data")

What am I missing? Yes the file does indeed have newlines

Body:
Use time_data_count += memcap.count('TIME_DATA') to count the occurrences of 'TIME_DATA_ in the memcap string. This will not count items if they get sliced in half between chunks of the file.

with open(filename) as f:
    time_data_count = 0
    while True:
        memcap = f.read(102400)
        if 'TIME_DATA' in memcap:
            # add the number of occurrences
            time_data_count += memcap.count('TIME_DATA')
        if not memcap:
            break
    if time_data_count > 20:
        print("time_data complete")
    else:
        print("incomplete time_data data")

The issue with your original code is the counter would only increment if the  item was found in the string regardless of how many occurrences, not for each occurrence.


问:
How to get current position of where you are typing in Javascript
I want to be able to see where I am typing in the box in proportion to the page. Ie. if I type an "L" in the text box, what is the current position on the page in pixels top/left.

I retrieved the current input positon of the field with:

```<code>  var field = document.getElementById("field");
  var boxX = field.offsetLeft;
  var boxY = field.offsetTop;
</code>```

I just can't figure out current position in pixels of the location of the last letter typed in the field.

Can anyone help me?

Thanks!

答:
HTML

```<code>  <input id="field" type="text"/>
</code>```

JavaScript

```<code>var boxX =field.offsetHeight;
var boxY= field.offsetLeft;

document.getElementById("field").addEventListener('keyup', e => {
    console.log('Caret at: ', e.target.offsetLeft + e.target.selectionEnd);
    console.log('Caret at: ', e.target.offsetTop + e.target.selectionEnd);
  });
</code>```

Body:
I want to be able to see where I am typing in the box in proportion to the page. Ie. if I type an "L" in the text box, what is the current position on the page in pixels top/left.

I retrieved the current input positon of the field with:

  var field = document.getElementById("field");
  var boxX = field.offsetLeft;
  var boxY = field.offsetTop;

I just can't figure out current position in pixels of the location of the last letter typed in the field.

Can anyone help me?

Thanks!

Body:
HTML

  <input id="field" type="text"/>

JavaScript

var boxX =field.offsetHeight;
var boxY= field.offsetLeft;

document.getElementById("field").addEventListener('keyup', e => {
    console.log('Caret at: ', e.target.offsetLeft + e.target.selectionEnd);
    console.log('Caret at: ', e.target.offsetTop + e.target.selectionEnd);
  });


问:
Xamarin Forms to Xamarin.Android
I have some pages in Xamarin.Forms,since I need to build a custom camera,so I used Xamarin.Android.
now I need to go to Xamarin.Android/iOS from page of  Xamarin.Forms and  and back to Xamarin.Forms again. how can I do it?
pls help</p>

答:
Welcome to SO !

Baesd on a Xamarin Forms project , you can use Custom Renderer to achieve that .

Such as Creating the Custom Control :

```<code>public class CameraPreview : View
{
  public static readonly BindableProperty CameraProperty = BindableProperty.Create (
    propertyName: "Camera",
    returnType: typeof(CameraOptions),
    declaringType: typeof(CameraPreview),
    defaultValue: CameraOptions.Rear);

  public CameraOptions Camera {
    get { return (CameraOptions)GetValue (CameraProperty); }
    set { SetValue (CameraProperty, value); }
  }
}
</code>```

In Xaml :

```<code><ContentPage ...
             xmlns:local="clr-namespace:CustomRenderer;assembly=CustomRenderer"
             ...>
    <ContentPage.Content>
        <StackLayout>
            <Label Text="Camera Preview:" />
            <local:CameraPreview Camera="Rear"
              HorizontalOptions="FillAndExpand" VerticalOptions="FillAndExpand" />
        </StackLayout>
    </ContentPage.Content>
</ContentPage>
</code>```

Now you can create the Custom Renderer on each Platform.

Android :

```<code>[assembly: ExportRenderer(typeof(CustomRenderer.CameraPreview), typeof(CameraPreviewRenderer))]
namespace CustomRenderer.Droid
{
    public class CameraPreviewRenderer : ViewRenderer<CustomRenderer.CameraPreview, CustomRenderer.Droid.CameraPreview>
    {
        CameraPreview cameraPreview;

        public CameraPreviewRenderer(Context context) : base(context)
        {
        }

        protected override void OnElementChanged(ElementChangedEventArgs<CustomRenderer.CameraPreview> e)
        {
            base.OnElementChanged(e);

            if (e.OldElement != null)
            {
                // Unsubscribe
                cameraPreview.Click -= OnCameraPreviewClicked;
            }
            if (e.NewElement != null)
            {
                if (Control == null)
                {
                  cameraPreview = new CameraPreview(Context);
                  SetNativeControl(cameraPreview);
                }
                Control.Preview = Camera.Open((int)e.NewElement.Camera);

                // Subscribe
                cameraPreview.Click += OnCameraPreviewClicked;
            }
        }

        void OnCameraPreviewClicked(object sender, EventArgs e)
        {
            if (cameraPreview.IsPreviewing)
            {
                cameraPreview.Preview.StopPreview();
                cameraPreview.IsPreviewing = false;
            }
            else
            {
                cameraPreview.Preview.StartPreview();
                cameraPreview.IsPreviewing = true;
            }
        }
        ...
    }
}
</code>```

iOS :

```<code>[assembly: ExportRenderer (typeof(CameraPreview), typeof(CameraPreviewRenderer))]
namespace CustomRenderer.iOS
{
    public class CameraPreviewRenderer : ViewRenderer<CameraPreview, UICameraPreview>
    {
        UICameraPreview uiCameraPreview;

        protected override void OnElementChanged (ElementChangedEventArgs<CameraPreview> e)
        {
            base.OnElementChanged (e);

            if (e.OldElement != null) {
                // Unsubscribe
                uiCameraPreview.Tapped -= OnCameraPreviewTapped;
            }
            if (e.NewElement != null) {
                if (Control == null) {
                  uiCameraPreview = new UICameraPreview (e.NewElement.Camera);
                  SetNativeControl (uiCameraPreview);
                }
                // Subscribe
                uiCameraPreview.Tapped += OnCameraPreviewTapped;
            }
        }

        void OnCameraPreviewTapped (object sender, EventArgs e)
        {
            if (uiCameraPreview.IsPreviewing) {
                uiCameraPreview.CaptureSession.StopRunning ();
                uiCameraPreview.IsPreviewing = false;
            } else {
                uiCameraPreview.CaptureSession.StartRunning ();
                uiCameraPreview.IsPreviewing = true;
            }
        }
        ...
    }
}
</code>```

More info can refer to this official sample .

Title: Xamarin Forms to Xamarin.Android

Body:
Welcome to SO !

Baesd on a Xamarin Forms project , you can use Custom Renderer to achieve that .

Such as Creating the Custom Control :

public class CameraPreview : View
{
  public static readonly BindableProperty CameraProperty = BindableProperty.Create (
    propertyName: "Camera",
    returnType: typeof(CameraOptions),
    declaringType: typeof(CameraPreview),
    defaultValue: CameraOptions.Rear);

  public CameraOptions Camera {
    get { return (CameraOptions)GetValue (CameraProperty); }
    set { SetValue (CameraProperty, value); }
  }
}

In Xaml :

<ContentPage ...
             xmlns:local="clr-namespace:CustomRenderer;assembly=CustomRenderer"
             ...>
    <ContentPage.Content>
        <StackLayout>
            <Label Text="Camera Preview:" />
            <local:CameraPreview Camera="Rear"
              HorizontalOptions="FillAndExpand" VerticalOptions="FillAndExpand" />
        </StackLayout>
    </ContentPage.Content>
</ContentPage>

Now you can create the Custom Renderer on each Platform.

Android :

[assembly: ExportRenderer(typeof(CustomRenderer.CameraPreview), typeof(CameraPreviewRenderer))]
namespace CustomRenderer.Droid
{
    public class CameraPreviewRenderer : ViewRenderer<CustomRenderer.CameraPreview, CustomRenderer.Droid.CameraPreview>
    {
        CameraPreview cameraPreview;

        public CameraPreviewRenderer(Context context) : base(context)
        {
        }

        protected override void OnElementChanged(ElementChangedEventArgs<CustomRenderer.CameraPreview> e)
        {
            base.OnElementChanged(e);

            if (e.OldElement != null)
            {
                // Unsubscribe
                cameraPreview.Click -= OnCameraPreviewClicked;
            }
            if (e.NewElement != null)
            {
                if (Control == null)
                {
                  cameraPreview = new CameraPreview(Context);
                  SetNativeControl(cameraPreview);
                }
                Control.Preview = Camera.Open((int)e.NewElement.Camera);

                // Subscribe
                cameraPreview.Click += OnCameraPreviewClicked;
            }
        }

        void OnCameraPreviewClicked(object sender, EventArgs e)
        {
            if (cameraPreview.IsPreviewing)
            {
                cameraPreview.Preview.StopPreview();
                cameraPreview.IsPreviewing = false;
            }
            else
            {
                cameraPreview.Preview.StartPreview();
                cameraPreview.IsPreviewing = true;
            }
        }
        ...
    }
}

iOS :

[assembly: ExportRenderer (typeof(CameraPreview), typeof(CameraPreviewRenderer))]
namespace CustomRenderer.iOS
{
    public class CameraPreviewRenderer : ViewRenderer<CameraPreview, UICameraPreview>
    {
        UICameraPreview uiCameraPreview;

        protected override void OnElementChanged (ElementChangedEventArgs<CameraPreview> e)
        {
            base.OnElementChanged (e);

            if (e.OldElement != null) {
                // Unsubscribe
                uiCameraPreview.Tapped -= OnCameraPreviewTapped;
            }
            if (e.NewElement != null) {
                if (Control == null) {
                  uiCameraPreview = new UICameraPreview (e.NewElement.Camera);
                  SetNativeControl (uiCameraPreview);
                }
                // Subscribe
                uiCameraPreview.Tapped += OnCameraPreviewTapped;
            }
        }

        void OnCameraPreviewTapped (object sender, EventArgs e)
        {
            if (uiCameraPreview.IsPreviewing) {
                uiCameraPreview.CaptureSession.StopRunning ();
                uiCameraPreview.IsPreviewing = false;
            } else {
                uiCameraPreview.CaptureSession.StartRunning ();
                uiCameraPreview.IsPreviewing = true;
            }
        }
        ...
    }
}

More info can refer to this official sample .


问:
PostgreSQL - Insert records into a table and return the result
This following code snippet

```<code>SELECT data.generate_file_data(
   p.file_name,
   p.reference,
   p.extension,
   p.platform,
   p.library,
   p.path,
   p.is_temporary
) x
FROM files.main p;
</code>```

returns a column of records named generate_file_data which looks like this

```<code>generate_file_data record
(reference, directory, platform, library)
(reference, directory, platform, library)
(reference, directory, platform, library)
(reference, directory, platform, library)
...
</code>```

The results (return type of the generate_file_data() function) are records of the type

```<code>id integer          directory text        platform text         library text
id                  directory             platform              library
</code>```

Which always returns a single result. I wonder if there is a way to instead split the records to four pieces and put them inside of

```<code>TABLE(id text, directory text, platform text, library text)
</code>```

so the results will be a table instead of a column of records, kinda like this

```<code>id integer          directory text        platform text         library text
id                  directory             platform              library
id                  directory             platform              library
id                  directory             platform              library
id                  directory             platform              library
...
</code>```

答:
Kudos to @GMB who almost got the answer correct, it seems that CROSS JOIN LATERAL allows us to call the result of the generate_file_data() function for every row and glue it together

```<code>SELECT x.id, x.directory, x.library, x.platform
FROM files.main p
CROSS JOIN LATERAL data.generate_file_data(
   p.file_name,
   p.reference,
   p.extension,
   p.platform,
   p.library,
   p.path,
   p.is_temporary
) x;
</code>```

Which we do afterwards specify in SELECT which of the columns we do want to return!

Body:
This following code snippet

SELECT data.generate_file_data(
   p.file_name,
   p.reference,
   p.extension,
   p.platform,
   p.library,
   p.path,
   p.is_temporary
) x
FROM files.main p;

returns a column of records named generate_file_data which looks like this

generate_file_data record
(reference, directory, platform, library)
(reference, directory, platform, library)
(reference, directory, platform, library)
(reference, directory, platform, library)
...

The results (return type of the generate_file_data() function) are records of the type

id integer          directory text        platform text         library text
id                  directory             platform              library

Which always returns a single result. I wonder if there is a way to instead split the records to four pieces and put them inside of

TABLE(id text, directory text, platform text, library text)

so the results will be a table instead of a column of records, kinda like this

id integer          directory text        platform text         library text
id                  directory             platform              library
id                  directory             platform              library
id                  directory             platform              library
id                  directory             platform              library
...

Body:
Kudos to @GMB who almost got the answer correct, it seems that CROSS JOIN LATERAL allows us to call the result of the generate_file_data() function for every row and glue it together

SELECT x.id, x.directory, x.library, x.platform
FROM files.main p
CROSS JOIN LATERAL data.generate_file_data(
   p.file_name,
   p.reference,
   p.extension,
   p.platform,
   p.library,
   p.path,
   p.is_temporary
) x;

Which we do afterwards specify in SELECT which of the columns we do want to return!


问:
regex for matching programming language like block
I'm trying to make a small scripting language using c#
currently doing a block parser
im stuck at making regex for block.
Blocks can have ∞ times of sub blocks

This is what i need to catch

```<code>{
    naber();
}
{
    int x = 5;
    x = 2;
    if (x == 5) {
        x = 5;
    }
}

</code>```

I tried this but not working

```<code>\{[^{}]*|(\{[^\{\}]\})*\}
</code>```

This is my first post please have mercy on me

答:
I agree with those saying that regex isn't what you should use parsing code.
With that said, it is possible on some reg engines to match characters and get code in a block.

This might work for you {((?>[^{}]+|(?R))*)}. If the regex engine supports recursive pattern then it is possible to do some work parsing code.

More here about it Match balanced curly braces

Body:
I'm trying to make a small scripting language using c#
currently doing a block parser
im stuck at making regex for block.
Blocks can have ∞ times of sub blocks

This is what i need to catch

{
    naber();
}
{
    int x = 5;
    x = 2;
    if (x == 5) {
        x = 5;
    }
}

I tried this but not working

\{[^{}]*|(\{[^\{\}]\})*\}

This is my first post please have mercy on me


问:
Empirical probability with boost histogram
I have a boost::histogram with 100 bins over the range [-3.5,3.5]. I fill it with a data vector qp. Since I work with periodic BC all the values of q in qp are in [-3.5,3.5].

```<code>auto h = boost::histogram::make_histogram(boost::histogram::axis::regular<>(100, -3.5, 3.5));
for (auto&& value : qp)
    h(value.first);
</code>```

For security I count all points in the bin with

```<code>int samplesize = 0;
for (auto&& it : indexed(h))
    samplesize += *it;
</code>```

I prepare the data for the plot

```<code>for (auto&& it : indexed(h)) {
    const auto bin = it.bin(0_c);
    double xaxis = bin.lower();
    double density = *it / samplesize;
    const std::pair<double, double> paar = std::make_pair(xaxis,density);
    printToStream(file, paar);
}
</code>```

The result confuses me. It should be a normalized probability distribution, but it is definitely not (the values on the y-axis are way to low)

Is there a boost method with which I automatically get a (normalized) relative frequency?

答:
You need to divide by the width of the bin. So you need to modify the density:

double density = *it / bin.width() / samplesize;
```

<p>Here's the complete code in boost-histogram's Python bindings, since it was quicker to mock up:</p>

<pre class="lang-py prettyprint-override"><code>import boost_histogram as bh
import numpy as np
import matplotlib.pyplot as plt

h = bh.Histogram(bh.axis.Regular(100, -3.5, 3.5))

data = np.concatenate([
    np.random.normal(-.75,.3, 1_000_000),
    np.random.normal(.75,.3, 750_000),
    np.random.normal(-1.5,.2, 200_000),
])

h.fill(data)

# Compute the areas of each bin (any number of axes)
areas = np.prod(h.axes.widths, axis=0)

# Compute the density (any number of axes)
density = h.view() / h.sum() / areas

plt.plot(h.axes.centers[0], density)
</code>```

PS: You can use a circular axes if your data is circular

Body:
I have a boost::histogram with 100 bins over the range [-3.5,3.5]. I fill it with a data vector qp. Since I work with periodic BC all the values of q in qp are in [-3.5,3.5].

auto h = boost::histogram::make_histogram(boost::histogram::axis::regular<>(100, -3.5, 3.5));
for (auto&& value : qp)
    h(value.first);

For security I count all points in the bin with

int samplesize = 0;
for (auto&& it : indexed(h))
    samplesize += *it;

I prepare the data for the plot

for (auto&& it : indexed(h)) {
    const auto bin = it.bin(0_c);
    double xaxis = bin.lower();
    double density = *it / samplesize;
    const std::pair<double, double> paar = std::make_pair(xaxis,density);
    printToStream(file, paar);
}

The result confuses me. It should be a normalized probability distribution, but it is definitely not (the values on the y-axis are way to low)

Is there a boost method with which I automatically get a (normalized) relative frequency?

Body:
You need to divide by the width of the bin. So you need to modify the density:

double density = *it / bin.width() / samplesize;

Here's the complete code in boost-histogram's Python bindings, since it was quicker to mock up:

import boost_histogram as bh
import numpy as np
import matplotlib.pyplot as plt

h = bh.Histogram(bh.axis.Regular(100, -3.5, 3.5))

data = np.concatenate([
    np.random.normal(-.75,.3, 1_000_000),
    np.random.normal(.75,.3, 750_000),
    np.random.normal(-1.5,.2, 200_000),
])

h.fill(data)

# Compute the areas of each bin (any number of axes)
areas = np.prod(h.axes.widths, axis=0)

# Compute the density (any number of axes)
density = h.view() / h.sum() / areas

plt.plot(h.axes.centers[0], density)

PS: You can use a circular axes if your data is circular


问:
Making recursive function more elegant
I've been working to hone my understanding of recursion [and become a better programmer in general]. Today a wrote some code to flatten a tuple of tuples. The code is as follows:

```<code>def recursive_tuple_flatten(tuple_list):
    if type(tuple_list) is tuple:
        if type(tuple_list[0]) is tuple:
            list_of_lists = [list(tuple_list[0]), tuple_list[1:]]
            return recursive_tuple_flatten([i for j in list_of_lists for i in j])
        else:
            return recursive_tuple_flatten(list(tuple_list))
    else:
        if type(tuple_list[-1]) is tuple:
            list_of_lists = [tuple_list[:-1], list(tuple_list[-1])]
            return recursive_tuple_flatten([i for j in list_of_lists for i in j])
        else:
            return tuple_list

k = ((1,(2)),(3,(4,5)))
recursive_tuple_flatten(k)
</code>```

The code works, but I'd really appreciate any advise and coaching to help me improve this code and make it more elegant. Have a great day!

答:
While this probably belongs on Code Review, here is what I came up with, for the sake of it:

def recursive_tuple_flatten(tuples):
    res = []
    for elem in tuples:
        if isinstance(elem, tuple):
            res.extend(recursive_tuple_flatten(elem))
        else:
            res.append(elem)
    return res
```

Title: Making recursive function more elegant

Body:
I've been working to hone my understanding of recursion [and become a better programmer in general]. Today a wrote some code to flatten a tuple of tuples. The code is as follows:

def recursive_tuple_flatten(tuple_list):
    if type(tuple_list) is tuple:
        if type(tuple_list[0]) is tuple:
            list_of_lists = [list(tuple_list[0]), tuple_list[1:]]
            return recursive_tuple_flatten([i for j in list_of_lists for i in j])
        else:
            return recursive_tuple_flatten(list(tuple_list))
    else:
        if type(tuple_list[-1]) is tuple:
            list_of_lists = [tuple_list[:-1], list(tuple_list[-1])]
            return recursive_tuple_flatten([i for j in list_of_lists for i in j])
        else:
            return tuple_list

k = ((1,(2)),(3,(4,5)))
recursive_tuple_flatten(k)

The code works, but I'd really appreciate any advise and coaching to help me improve this code and make it more elegant. Have a great day!


问:
Return only key value on AWS IOT rule to send date to DynamoDB?
I'm working on a project where I'm publishing some sensor data to a MQTT topic in AWS IOT. I have rule to insert that data to a DynamoDB table.

My published data looks like:

```<code>{
  "id": 1,
  "timestamp": 1591132839,
  "data": 71
}
</code>```

Since I only need the value of the "data" key in my data column, my SQL query is:

SELECT data FROM 'soil-moisture/#'

I was expecting my values in my table to just be the value, e.g. 71, but instead I get:

{ "data" : { "N" : "71" } }

I've tried changing my query but I get these results:

data.N returns {}
SELECT VALUE data... returns some random String in data_raw column.

How do I just insert just the value of the "data" key into my table?

Thank you.

答:
This metadata is how DynamoDB stores items. You can't remove the data type as it is applied automatically.

The possible data types are documented at https://docs.aws.amazon.com/amazondynamodb/latest/developerguide/Programming.LowLevelAPI.html#Programming.LowLevelAPI.DataTypeDescriptors and https://docs.aws.amazon.com/amazondynamodb/latest/APIReference/API_AttributeValue.html.

From the first link:

The low-level DynamoDB API protocol requires each attribute to be accompanied by a data type descriptor. Data type descriptors are tokens that tell DynamoDB how to interpret each attribute.

Some of the DynamoDB SDKs abstract these types away so you don't need to deal with them. e.g. the Javascript DocumentClient

Body:
I'm working on a project where I'm publishing some sensor data to a MQTT topic in AWS IOT. I have rule to insert that data to a DynamoDB table.

My published data looks like:

{
  "id": 1,
  "timestamp": 1591132839,
  "data": 71
}

Since I only need the value of the "data" key in my data column, my SQL query is:

SELECT data FROM 'soil-moisture/#'

I was expecting my values in my table to just be the value, e.g. 71, but instead I get:

{ "data" : { "N" : "71" } }

I've tried changing my query but I get these results:

data.N returns {}
SELECT VALUE data... returns some random String in data_raw column.

How do I just insert just the value of the "data" key into my table?

Thank you.


问:
Can't display index.html from React in Spring
I built the frontend with React and the REST API with Spring. NOw i was trying to connect the two , and created a controller that returns the index.html generated in the vuild folder of the frontend.
But when i run the app, I'm getting this errors:

No mapping for GET /static/js/2.24af4acc.chunk.js
No mapping for GET /static/js/main.5b0f5e80.chunk.js
...

MY POM:

```<code>  <plugin>
    <groupId>com.github.eirslett</groupId>
    <artifactId>frontend-maven-plugin</artifactId>
    <version>1.6</version>
    <configuration>
        <workingDirectory>src/main/frontend</workingDirectory>
        <installDirectory>target</installDirectory>
    </configuration>
    <executions>
        <execution>
            <id>install node and npm</id>
            <goals>
                <goal>install-node-and-npm</goal>
            </goals>
            <configuration>
                <nodeVersion>v12.16.1</nodeVersion>
                <npmVersion>6.13.4</npmVersion>
            </configuration>
        </execution>
        <execution>
            <id>npm install</id>
            <goals>
                <goal>npm</goal>
            </goals>
            <configuration>
                <arguments>install</arguments>
            </configuration>
        </execution>
        <execution>
            <id>npm run build --nomaps</id>
            <goals>
                <goal>npm</goal>
            </goals>
            <configuration>
                <arguments>run build</arguments>
            </configuration>
        </execution>

    </executions>
</plugin>

<plugin>
    <groupId>org.apache.maven.plugins</groupId>
    <artifactId>maven-antrun-plugin</artifactId>
    <executions>
        <execution>
            <phase>generate-resources</phase>
            <configuration>
                <target>
                    <copy todir="src/main/resources/static">
                        <fileset dir="src/main/frontend/build" />
                    </copy>
                </target>
            </configuration>
            <goals>
                <goal>run</goal>
            </goals>
        </execution>
    </executions>
</plugin>

</code>```

index.html:

```<code><!doctype html><html lang="en"><head><meta charset="utf-8"/>
<link rel="icon" href="/favicon.ico"/>
<meta name="viewport" content="width=device-width,initial-scale=1"/><meta name="theme-color" content="#000000"/><meta name="description" content="Web site created using create-react-app"/>
<link rel="apple-touch-icon" href="/logo192.png"/>
<link rel="manifest" href="/manifest.json"/><title>My App</title>
<link href="/static/css/2.ecffae5e.chunk.css" rel="stylesheet"><link href="/static/css/main.fcc6280a.chunk.css" rel="stylesheet"></head><body><noscript>You need to enable JavaScript to run this app.</noscript><div id="root"></div><script>!function(e){function r(r){for(var n,f,l=r[0],i=r[1],a=r[2],c=0,s=[];c<l.length;c++)f=l[c],Object.prototype.hasOwnProperty.call(o,f)&&o[f]&&s.push(o[f][0]),o[f]=0;for(n in i)Object.prototype.hasOwnProperty.call(i,n)&&(e[n]=i[n]);for(p&&p(r);s.length;)s.shift()();return u.push.apply(u,a||[]),t()}function t(){for(var e,r=0;r<u.length;r++){for(var t=u[r],n=!0,l=1;l<t.length;l++){var i=t[l];0!==o[i]&&(n=!1)}n&&(u.splice(r--,1),e=f(f.s=t[0]))}return e}var n={},o={1:0},u=[];function f(r){if(n[r])return n[r].exports;var t=n[r]={i:r,l:!1,exports:{}};return e[r].call(t.exports,t,t.exports,f),t.l=!0,t.exports}f.m=e,f.c=n,f.d=function(e,r,t){f.o(e,r)||Object.defineProperty(e,r,{enumerable:!0,get:t})},f.r=function(e){"undefined"!=typeof Symbol&&Symbol.toStringTag&&Object.defineProperty(e,Symbol.toStringTag,{value:"Module"}),Object.defineProperty(e,"__esModule",{value:!0})},f.t=function(e,r){if(1&r&&(e=f(e)),8&r)return e;if(4&r&&"object"==typeof e&&e&&e.__esModule)return e;var t=Object.create(null);if(f.r(t),Object.defineProperty(t,"default",{enumerable:!0,value:e}),2&r&&"string"!=typeof e)for(var n in e)f.d(t,n,function(r){return e[r]}.bind(null,n));return t},f.n=function(e){var r=e&&e.__esModule?function(){return e.default}:function(){return e};return f.d(r,"a",r),r},f.o=function(e,r){return Object.prototype.hasOwnProperty.call(e,r)},f.p="/";var l=this.webpackJsonpweb_frontend=this.webpackJsonpweb_frontend||[],i=l.push.bind(l);l.push=r,l=l.slice();for(var a=0;a<l.length;a++)r(l[a]);var p=i;t()}([])</script><script src="/static/js/2.24af4acc.chunk.js"></script><script src="/static/js/main.5b0f5e80.chunk.js"></script></body></html>

</code>```

Project structure:

here

答:
These warnings occur because no interceptor is configured,Use the default settings.
 or you can add the resource file mapping in the MVC configuration file.</p>

```<code>enter code here
<resources mapping="/resources/**" location="/resources/" />
<resources mapping="/images/**" location="/images/" />
<resources mapping="/js/**" location="/js/" />
</code>```

Body:
I built the frontend with React and the REST API with Spring. NOw i was trying to connect the two , and created a controller that returns the index.html generated in the vuild folder of the frontend.
But when i run the app, I'm getting this errors:

No mapping for GET /static/js/2.24af4acc.chunk.js
No mapping for GET /static/js/main.5b0f5e80.chunk.js
...

MY POM:

  <plugin>
    <groupId>com.github.eirslett</groupId>
    <artifactId>frontend-maven-plugin</artifactId>
    <version>1.6</version>
    <configuration>
        <workingDirectory>src/main/frontend</workingDirectory>
        <installDirectory>target</installDirectory>
    </configuration>
    <executions>
        <execution>
            <id>install node and npm</id>
            <goals>
                <goal>install-node-and-npm</goal>
            </goals>
            <configuration>
                <nodeVersion>v12.16.1</nodeVersion>
                <npmVersion>6.13.4</npmVersion>
            </configuration>
        </execution>
        <execution>
            <id>npm install</id>
            <goals>
                <goal>npm</goal>
            </goals>
            <configuration>
                <arguments>install</arguments>
            </configuration>
        </execution>
        <execution>
            <id>npm run build --nomaps</id>
            <goals>
                <goal>npm</goal>
            </goals>
            <configuration>
                <arguments>run build</arguments>
            </configuration>
        </execution>

    </executions>
</plugin>

<plugin>
    <groupId>org.apache.maven.plugins</groupId>
    <artifactId>maven-antrun-plugin</artifactId>
    <executions>
        <execution>
            <phase>generate-resources</phase>
            <configuration>
                <target>
                    <copy todir="src/main/resources/static">
                        <fileset dir="src/main/frontend/build" />
                    </copy>
                </target>
            </configuration>
            <goals>
                <goal>run</goal>
            </goals>
        </execution>
    </executions>
</plugin>

index.html:

<!doctype html><meta charset="utf-8"/>
<link rel="icon" href="/favicon.ico"/>
<meta name="viewport" content="width=device-width,initial-scale=1"/><meta name="theme-color" content="#000000"/><meta name="description" content="Web site created using create-react-app"/>
<link rel="apple-touch-icon" href="/logo192.png"/>
<link rel="manifest" href="/manifest.json"/><title>My App</title>
<link href="/static/css/2.ecffae5e.chunk.css" rel="stylesheet"><link href="/static/css/main.fcc6280a.chunk.css" rel="stylesheet">You need to enable JavaScript to run this app.

Project structure:

here

Body:
These warnings occur because no interceptor is configured,Use the default settings.
 or you can add the resource file mapping in the MVC configuration file.

enter code here
<resources mapping="/resources/**" location="/resources/" />
<resources mapping="/images/**" location="/images/" />
<resources mapping="/js/**" location="/js/" />


答:
Simply assign a SEASON column then aggregate:

```<code>df <- within(df, {
          SEASON <- ifelse(MONTH %in% c(12, 1, 2), 'Winter',
                           ifelse(MONTH %in% c(3, 4, 5), 'Spring',
                                  ifelse (MONTH %in% c(6, 7, 8), 'Summer',
                                          ifelse(MONTH %in% c(9, 10, 11), 'Fall', NA)
                                  )
                          )
                     )

          YEAR <- ifelse(MONTH == 12, YEAR + 1, YEAR)
      })

agg_df <- aggregate(PPT ~ CENTROID_ID + SEASON, df, FUN=mean)
agg_df
#   CENTROID_ID SEASON      PPT
# 1     c1763_1   Fall 43.79958
# 2     c1763_1 Spring 17.81050
# 3     c1763_1 Summer 36.92158
# 4     c1763_1 Winter 39.74171
</code>```

Should you need multiple aggregations of PPT:

```<code>agg_raw <- aggregate(PPT ~ CENTROID_ID + SEASON, df,
                     FUN=function(x) c(min=min(x), mean=mean(x), max=max(x)))

agg_df <- do.call(data.frame, agg_raw)
agg_df

#   CENTROID_ID SEASON PPT.min PPT.mean PPT.max
# 1     c1763_1   Fall  10.420 43.79958 119.725
# 2     c1763_1 Spring   0.739 17.81050  72.017
# 3     c1763_1 Summer   3.773 36.92158  74.731
# 4     c1763_1 Winter   8.777 39.74171 104.197
</code>```

Title: How to find the average, max, and min based on multiple sets of criteria

Body:
I have found a few options from other posts but I am having trouble reproducing the code for my specific needs.

I have climate data that I would like to find the average based on season from 1910-2015 for specific locations.

Here is an example of what I need: the average PPT for CENTROID_ID c1763_1 in 1911 for Winter (Month 12 of the preceding year [1910], month 1 and 2 of year in question [1911]), Spring (months 3,4,5 in 1911), Summer (months 6,7,8 in 1911) and Fall (months 9,10,11 in 1911). This would then need to be done for all individual centroid IDs for every year. I have over 400 unique CENTROID_IDs covering years 1910-2015.

I envision the new dataframe to have the columns CENTROID_ID, YEAR, WINT_PPT, SPR_PPT, SUM_PPT, FALL_PPT.

 CENTROID_ID    YEAR MONTH  PPT
1       c1763_1 1910     1  52.639
2       c1763_1 1910     2  20.870
3       c1763_1 1910     3  21.706
4       c1763_1 1910     4   9.347
5       c1763_1 1910     5   1.201
6       c1763_1 1910     6  11.267
7       c1763_1 1910     7  41.870
8       c1763_1 1910     8  61.260
9       c1763_1 1910     9  27.815
10      c1763_1 1910    10  67.377
11      c1763_1 1910    11  24.719
12      c1763_1 1910    12  30.212
13      c1763_1 1911     1  88.728
14      c1763_1 1911     2  50.035
15      c1763_1 1911     3  37.720
16      c1763_1 1911     4  12.831
17      c1763_1 1911     5   0.739
18      c1763_1 1911     6  18.198
19      c1763_1 1911     7  74.731
20      c1763_1 1911     8  40.873
21      c1763_1 1911     9  86.340
22      c1763_1 1911    10  36.423
23      c1763_1 1911    11  12.491
24      c1763_1 1911    12  19.428
25      c1763_1 1912     1  11.010
26      c1763_1 1912     2  16.339
27      c1763_1 1912     3  72.017
28      c1763_1 1912     4  25.887
29      c1763_1 1912     5   5.314
30      c1763_1 1912     6   8.595
31      c1763_1 1912     7  47.781
32      c1763_1 1912     8  51.188
33      c1763_1 1912     9  10.931
34      c1763_1 1912    10 119.725
35      c1763_1 1912    11  10.420
36      c1763_1 1912    12   8.777
37      c1763_1 1913     1  27.771
38      c1763_1 1913     2  62.622
39      c1763_1 1913     3  17.533
40      c1763_1 1913     4   8.008
41      c1763_1 1913     5   1.423
42      c1763_1 1913     6   3.773
43      c1763_1 1913     7  42.982
44      c1763_1 1913     8  40.541
45      c1763_1 1913     9  58.495
46      c1763_1 1913    10  22.729
47      c1763_1 1913    11  48.130
48      c1763_1 1913    12  32.049
49      c1763_1 1914     1 104.197
50      c1763_1 1914     2  31.707

Body:
Simply assign a SEASON column then aggregate:

df <- within(df, {
          SEASON <- ifelse(MONTH %in% c(12, 1, 2), 'Winter',
                           ifelse(MONTH %in% c(3, 4, 5), 'Spring',
                                  ifelse (MONTH %in% c(6, 7, 8), 'Summer',
                                          ifelse(MONTH %in% c(9, 10, 11), 'Fall', NA)
                                  )
                          )
                     )

          YEAR <- ifelse(MONTH == 12, YEAR + 1, YEAR)
      })

agg_df <- aggregate(PPT ~ CENTROID_ID + SEASON, df, FUN=mean)
agg_df
#   CENTROID_ID SEASON      PPT
# 1     c1763_1   Fall 43.79958
# 2     c1763_1 Spring 17.81050
# 3     c1763_1 Summer 36.92158
# 4     c1763_1 Winter 39.74171

Should you need multiple aggregations of PPT:

agg_raw <- aggregate(PPT ~ CENTROID_ID + SEASON, df,
                     FUN=function(x) c(min=min(x), mean=mean(x), max=max(x)))

agg_df <- do.call(data.frame, agg_raw)
agg_df

#   CENTROID_ID SEASON PPT.min PPT.mean PPT.max
# 1     c1763_1   Fall  10.420 43.79958 119.725
# 2     c1763_1 Spring   0.739 17.81050  72.017
# 3     c1763_1 Summer   3.773 36.92158  74.731
# 4     c1763_1 Winter   8.777 39.74171 104.197


问:
What is the difference between HMS Core ML Kit and HiAI?
What is the difference between HMS Core ML Kit and HiAI ? I see the document in HiAI , and the Facial Recognition, Image Recognition, text recognize... and I also see text recognize in  HMS Core ML kit, what should I use?</p>

答:
HUAWEI HiAI is completely on the device side, and does not depend on the processing of the cloud side. It integrates NPUs with software, and opens multiple APIs including facial recognition, image recognition, video processing, text recognition, and document processing. It depends on Huawei Kirin SoC.

HUAWEI ML Kit allows your apps to easily leverage Huawei's long-term proven expertise in machine learning to support diverse artificial intelligence (AI) applications throughout a wide range of industries, including text-related, language-related, image-related, and face/body-related services. It provides both on-device and on-cloud APIs. On-device APIs are blistering-fast, without requiring a network connection, and on-cloud APIs provide a high degree of accuracy with the benefit of powerful computing, and are best equipped for complex scenarios. ML Kit has the advantage of supporting all android devices with ARM architecture, and all features are provided globally.

If your application needs to use device-side and cloud-side capabilities, and supports all android devices, it is recommended that you use HUAWEI ML Kit.