问:
Using jQuery / javascript, how to properly parse an HTML table to send the contents of each row to be updated into the database
I am loading members into a database from a table (the table has been populated from an MS Excel spreadsheet so contains fixed columns and variable rows). The ajax call to write the second row has data from the first row. However, when I add the "alert" the data on each ajax call is correct. How do I ensure that all the data from parsing the row has been retrieved before the ajax call?

```<code>    var firstName = '';
    var surname = '';
    $("#wrapper tbody tr").each(function() {
        var row = $(this).index() + 1; // +1 since index is 0 based
        $('td', this).each(function() {
            if (row > 1) {
                var $col = $(this);
                var col = $col.index() + 1;
                var text = $.trim($col.text()); // GET TRIMMED TEXT

                if (col === 1){
                    firstName = text;
                }
                if (col === 2){
                    surname = text;
                }
            }
        });
        if (row > 1) {
            alert("firstName: " + firstName + " surname: " + surname);

            //ajax call to server to add to database

        row++;
    });
</code>```

This is what I have amended the above to:

```<code>function sendRequest() {
//Get the default image
    var img2 = '';
    toDataURL('images/YouthMember.jpg', function(dataUrl) {
        img2 = dataUrl.replace(/^data:image\/(png|jpg|jpeg|gif);base64,/, "");
    })

    var records = getRecords();
    console.log("Records: " + records);
    var jsonRecords = JSON.stringify(records);

    //ajax call to server to add to database
    $.ajax({
        url : 'BulkUploadMembersView', // Your Servlet mapping or JSP(not suggested)
        type : 'POST',
        dataType : 'json',
        data : {
            ssAccountLevel : sessionStorage.getItem('ssAccountLevel'),
            ssAccountID : sessionStorage.getItem('ssAccountID'),
            ssGroupNoAdd : sessionStorage.getItem('ssGroupNoAdd'),

            image : img2,
            memberList: jsonRecords,
        },

        })
        .fail (function(jqXHR, textStatus, errorThrown) {
            //alert(jqXHR.responseText);
            $('#ajaxGetUserServletResponse3').text('Error adding member.');
        })
        .done(function(responseJson){
            $('#ajaxGetUserServletResponse3').text('Member added.');
            showActionPlanDataTable();
    })
}

function getRecords() {
    var records  = [];
    var keyNames = ['firstName', 'surname', 'dob', 'scoutNumber', 'joiningDate'];

    $("#wrapper tbody tr").each(function(i) {

        if (i === 0) {
            i++
            return;
        }

        var record = {};
        $('td', this).each(function(j) {
            if (keyNames[j]){
                var text = $.trim($(this).text()); // GET TRIMMED TEXT

                record[keyNames[j]] = text;
            }
        });
        records.push(record);
    });

    return records;
}
</code>```

答:
Looking at you code, looks like you're sending the last record every request.

I do not recommend to send an ajax request for each row. But if you have to do it, try this:

```<code>function getRecords() {
  var records  = [];
  var keyNames = ['firstName', 'surname'];

  $("#wrapper tbody tr").each(function(i) {

    if (i === 0) {
       return;
    }

    var record = {};
    $('td', this).each(function(j) {
        if (keyNames[j]){
          var text = $.trim($(this).text()); // GET TRIMMED TEXT
          record[keyNames[j]] = text;
        }
    });

    records.push(record);
  });

  return records;
}

function sendRequest() {
  var records = getRecords();
  console.log(records);
  //ajax call to server to add to database
}

sendRequest();
</code>```

I highly recommend you to send more than one item per time.

Body:
I am loading members into a database from a table (the table has been populated from an MS Excel spreadsheet so contains fixed columns and variable rows). The ajax call to write the second row has data from the first row. However, when I add the "alert" the data on each ajax call is correct. How do I ensure that all the data from parsing the row has been retrieved before the ajax call?

    var firstName = '';
    var surname = '';
    $("#wrapper tbody tr").each(function() {
        var row = $(this).index() + 1; // +1 since index is 0 based
        $('td', this).each(function() {
            if (row > 1) {
                var $col = $(this);
                var col = $col.index() + 1;
                var text = $.trim($col.text()); // GET TRIMMED TEXT

                if (col === 1){
                    firstName = text;
                }
                if (col === 2){
                    surname = text;
                }
            }
        });
        if (row > 1) {
            alert("firstName: " + firstName + " surname: " + surname);

            //ajax call to server to add to database

        row++;
    });

This is what I have amended the above to:

function sendRequest() {
//Get the default image
    var img2 = '';
    toDataURL('images/YouthMember.jpg', function(dataUrl) {
        img2 = dataUrl.replace(/^data:image\/(png|jpg|jpeg|gif);base64,/, "");
    })

    var records = getRecords();
    console.log("Records: " + records);
    var jsonRecords = JSON.stringify(records);

    //ajax call to server to add to database
    $.ajax({
        url : 'BulkUploadMembersView', // Your Servlet mapping or JSP(not suggested)
        type : 'POST',
        dataType : 'json',
        data : {
            ssAccountLevel : sessionStorage.getItem('ssAccountLevel'),
            ssAccountID : sessionStorage.getItem('ssAccountID'),
            ssGroupNoAdd : sessionStorage.getItem('ssGroupNoAdd'),

            image : img2,
            memberList: jsonRecords,
        },

        })
        .fail (function(jqXHR, textStatus, errorThrown) {
            //alert(jqXHR.responseText);
            $('#ajaxGetUserServletResponse3').text('Error adding member.');
        })
        .done(function(responseJson){
            $('#ajaxGetUserServletResponse3').text('Member added.');
            showActionPlanDataTable();
    })
}

function getRecords() {
    var records  = [];
    var keyNames = ['firstName', 'surname', 'dob', 'scoutNumber', 'joiningDate'];

    $("#wrapper tbody tr").each(function(i) {

        if (i === 0) {
            i++
            return;
        }

        var record = {};
        $('td', this).each(function(j) {
            if (keyNames[j]){
                var text = $.trim($(this).text()); // GET TRIMMED TEXT

                record[keyNames[j]] = text;
            }
        });
        records.push(record);
    });

    return records;
}

Body:
Looking at you code, looks like you're sending the last record every request.

I do not recommend to send an ajax request for each row. But if you have to do it, try this:

function getRecords() {
  var records  = [];
  var keyNames = ['firstName', 'surname'];

  $("#wrapper tbody tr").each(function(i) {

    if (i === 0) {
       return;
    }

    var record = {};
    $('td', this).each(function(j) {
        if (keyNames[j]){
          var text = $.trim($(this).text()); // GET TRIMMED TEXT
          record[keyNames[j]] = text;
        }
    });

    records.push(record);
  });

  return records;
}

function sendRequest() {
  var records = getRecords();
  console.log(records);
  //ajax call to server to add to database
}

sendRequest();

I highly recommend you to send more than one item per time.


来源: stackexchange

问:
How long does it take for GitHub page to show changes after changing index.html
I am just wondering how long does it take for GitHub page to show the new items that I have added to the repository.

I changed index.html but after 10 minutes it still showed up the previous page...

答:
Github also has a deployment page: https://github.com/<user>/<repo>/deployments that lists the deployments and the time they were deployed.

Choose github-pages from the environments drop-down list.

This helps to know if your latest git push was deployed at all.

ContentLicense: CC BY-SA 4.0


问:
Gradient color text
What I actually try to achieve:
I'd like to draw text with a gradient vertical color. I found this solution, but it doesn't quite fit for me, as it has black square around the gradient font in my case - don't know how to get rid of it, so I started simple (the irrelevant part) question to understand better the physics of blending and frame buffer in opengl and libgdx

What I was trying to understand, irrelevant to my goal:
I have a texture with a white square on it, I draw it on top of red background. I am trying to draw a green square on top of the white one, the green square partially covers the white one, and partially on top of the red background (see picture below).

My intention is: the white area, that is behind of the green square should be painted in green color, but all red background should not be affected and stayed unchanged (red as it is).

How can I do this?

```<code>package com.mygdx.game;

import com.badlogic.gdx.ApplicationAdapter;
import com.badlogic.gdx.Gdx;
import com.badlogic.gdx.graphics.Color;
import com.badlogic.gdx.graphics.GL20;
import com.badlogic.gdx.graphics.Texture;
import com.badlogic.gdx.graphics.g2d.SpriteBatch;
import com.badlogic.gdx.graphics.glutils.ShapeRenderer;

public class Game extends ApplicationAdapter {
    SpriteBatch batch;
    Texture img;
    private int height;
    private int width;
    private ShapeRenderer shapeRenderer;

    @Override
    public void create() {
        batch = new SpriteBatch();
        img = new Texture("white.png");
        width = Gdx.graphics.getWidth();
        height = Gdx.graphics.getHeight();
        shapeRenderer = new ShapeRenderer();
        shapeRenderer.setAutoShapeType(true);
    }

    @Override
    public void render() {
        Gdx.gl.glClearColor(1, 0, 0, 1);
        Gdx.gl.glClear(GL20.GL_COLOR_BUFFER_BIT);

        batch.begin();
        batch.draw(img, width / 7, height / 4);
        batch.end();

        Gdx.gl.glEnable(GL20.GL_BLEND);
        Gdx.gl.glBlendFunc(GL20.GL_ONE, GL20.GL_SRC_COLOR);
        shapeRenderer.begin();
        shapeRenderer.set(ShapeRenderer.ShapeType.Filled);
        shapeRenderer.setColor(Color.GREEN);
        shapeRenderer.rect(width / 2 - 100, height / 4 - 50, 200, 200);
        shapeRenderer.end();
        Gdx.gl.glDisable(GL20.GL_BLEND);
    }

    @Override
    public void dispose() {
        batch.dispose();
        img.dispose();
    }
}
</code>```

Ideally, the green square should not be transparent anyhow, just should block white where it hides the white area.

The output I'm getting:

Update:
I mark @Xoppa 's answer as correct, as it solves my original question with the following result:

答:
You can fake blending by doing some math here's what I came up with:

import com.badlogic.gdx.Game;
import com.badlogic.gdx.Gdx;
import com.badlogic.gdx.graphics.Color;
import com.badlogic.gdx.graphics.GL20;
import com.badlogic.gdx.graphics.Texture;
import com.badlogic.gdx.graphics.g2d.SpriteBatch;
import com.badlogic.gdx.graphics.glutils.ShapeRenderer;
import com.badlogic.gdx.math.MathUtils;
import com.badlogic.gdx.math.Rectangle;

public class CalculatedMask extends Game {

    private SpriteBatch batch;          // The SpriteBatch to draw the white image
    private ShapeRenderer renderer;     // The ShapeRenderer to draw the green rectangle
    private Texture img;                // The texture of the image
    private Rectangle imgBounds;        // The bounds of the image
    private Rectangle squareBounds;     // The bounds of the square
    private float width;                // The width of the screen
    private float height;               // The height of the screen
    private float squareX;              // The x position of the green square
    private float squareY;              // The y position of the green square
    private float squareWidth;          // The width of the green square
    private float squareHeight;         // The height of the green square

    @Override
    public void create() {
        width = Gdx.graphics.getWidth();
        height = Gdx.graphics.getHeight();
        batch = new SpriteBatch();
        renderer = new ShapeRenderer();
        renderer.setAutoShapeType(true);

        img = new Texture("pixel.png");                 // A 1x1 white pixel png
        imgBounds = new Rectangle();                    // The white image bounds
        imgBounds.setPosition(width / 7f, height / 4f); // Position the white image bounds
        imgBounds.setSize(400f, 300f);                  // Scale the white image bounds
        calculateRectangle();
    }

    private void calculateRectangle() {
        // Here we define the green rectangle's original position and size
        squareBounds = new Rectangle();
        squareX = width / 2f - 300f;
        squareY = height / 4f - 50f;
        squareWidth = 200f;
        squareHeight = 200f;
        // Adjust green square x position
        squareBounds.x = MathUtils.clamp(squareX, imgBounds.x, imgBounds.x + imgBounds.width);
        // Adjust green square y position
        squareBounds.y = MathUtils.clamp(squareY, imgBounds.y, imgBounds.y + imgBounds.height);
        // Adjust green square width
        if (squareX < imgBounds.x) {
            squareBounds.width = Math.max(squareWidth + squareX - imgBounds.x, 0f);
        } else if (squareX + squareWidth > imgBounds.x + imgBounds.width) {
            squareBounds.width = Math.max(imgBounds.width - squareX + imgBounds.x, 0f);
        } else {
            squareBounds.width = squareWidth;
        }
        // Adjust green square height
        if (squareY < imgBounds.y) {
            squareBounds.height = Math.max(squareHeight + squareY - imgBounds.y, 0f);
        } else if (squareY + squareHeight > imgBounds.y + imgBounds.height) {
            squareBounds.height = Math.max(imgBounds.height - squareY + imgBounds.y, 0f);
        } else {
            squareBounds.height = squareHeight;
        }
    }

    @Override
    public void render() {
        // Clear previous frame
        Gdx.gl.glClearColor(1, 0, 0, 1);
        Gdx.gl.glClear(GL20.GL_COLOR_BUFFER_BIT);
        // Draw the white image
        batch.begin();
        batch.draw(img, imgBounds.x, imgBounds.y, imgBounds.width, imgBounds.height);
        batch.end();
        // Draw the green rectangle without affecting background
        renderer.begin();
        renderer.setColor(Color.GREEN);

        // Debug so we can see the real green rectangle
        renderer.set(ShapeRenderer.ShapeType.Line);
        renderer.rect(squareX, squareY, squareWidth, squareHeight);
        // Draw the modified green rectangle
        renderer.set(ShapeRenderer.ShapeType.Filled);
        renderer.rect(squareBounds.x, squareBounds.y, squareBounds.width, squareBounds.height);

        renderer.end();
    }
}
```

<p>And the results are:
<img src="https://i.stack.imgur.com/UL4Y2.png" alt="enter image description here"></p>

<p>And with:  </p>

<pre class="lang-java prettyprint-override"><code>squareX = width / 2f + 100f;
squareY = height / 4f + 150f;
</code>```

Title: Gradient color text

Body:
What I actually try to achieve:
I'd like to draw text with a gradient vertical color. I found this solution, but it doesn't quite fit for me, as it has black square around the gradient font in my case - don't know how to get rid of it, so I started simple (the irrelevant part) question to understand better the physics of blending and frame buffer in opengl and libgdx

What I was trying to understand, irrelevant to my goal:
I have a texture with a white square on it, I draw it on top of red background. I am trying to draw a green square on top of the white one, the green square partially covers the white one, and partially on top of the red background (see picture below).

My intention is: the white area, that is behind of the green square should be painted in green color, but all red background should not be affected and stayed unchanged (red as it is).

How can I do this?

package com.mygdx.game;

import com.badlogic.gdx.ApplicationAdapter;
import com.badlogic.gdx.Gdx;
import com.badlogic.gdx.graphics.Color;
import com.badlogic.gdx.graphics.GL20;
import com.badlogic.gdx.graphics.Texture;
import com.badlogic.gdx.graphics.g2d.SpriteBatch;
import com.badlogic.gdx.graphics.glutils.ShapeRenderer;

public class Game extends ApplicationAdapter {
    SpriteBatch batch;
    Texture img;
    private int height;
    private int width;
    private ShapeRenderer shapeRenderer;

    @Override
    public void create() {
        batch = new SpriteBatch();
        img = new Texture("white.png");
        width = Gdx.graphics.getWidth();
        height = Gdx.graphics.getHeight();
        shapeRenderer = new ShapeRenderer();
        shapeRenderer.setAutoShapeType(true);
    }

    @Override
    public void render() {
        Gdx.gl.glClearColor(1, 0, 0, 1);
        Gdx.gl.glClear(GL20.GL_COLOR_BUFFER_BIT);

        batch.begin();
        batch.draw(img, width / 7, height / 4);
        batch.end();

        Gdx.gl.glEnable(GL20.GL_BLEND);
        Gdx.gl.glBlendFunc(GL20.GL_ONE, GL20.GL_SRC_COLOR);
        shapeRenderer.begin();
        shapeRenderer.set(ShapeRenderer.ShapeType.Filled);
        shapeRenderer.setColor(Color.GREEN);
        shapeRenderer.rect(width / 2 - 100, height / 4 - 50, 200, 200);
        shapeRenderer.end();
        Gdx.gl.glDisable(GL20.GL_BLEND);
    }

    @Override
    public void dispose() {
        batch.dispose();
        img.dispose();
    }
}

Ideally, the green square should not be transparent anyhow, just should block white where it hides the white area.

The output I'm getting:

Update:
I mark @Xoppa 's answer as correct, as it solves my original question with the following result:

Body:
You can fake blending by doing some math here's what I came up with:

import com.badlogic.gdx.Game;
import com.badlogic.gdx.Gdx;
import com.badlogic.gdx.graphics.Color;
import com.badlogic.gdx.graphics.GL20;
import com.badlogic.gdx.graphics.Texture;
import com.badlogic.gdx.graphics.g2d.SpriteBatch;
import com.badlogic.gdx.graphics.glutils.ShapeRenderer;
import com.badlogic.gdx.math.MathUtils;
import com.badlogic.gdx.math.Rectangle;

public class CalculatedMask extends Game {

    private SpriteBatch batch;          // The SpriteBatch to draw the white image
    private ShapeRenderer renderer;     // The ShapeRenderer to draw the green rectangle
    private Texture img;                // The texture of the image
    private Rectangle imgBounds;        // The bounds of the image
    private Rectangle squareBounds;     // The bounds of the square
    private float width;                // The width of the screen
    private float height;               // The height of the screen
    private float squareX;              // The x position of the green square
    private float squareY;              // The y position of the green square
    private float squareWidth;          // The width of the green square
    private float squareHeight;         // The height of the green square

    @Override
    public void create() {
        width = Gdx.graphics.getWidth();
        height = Gdx.graphics.getHeight();
        batch = new SpriteBatch();
        renderer = new ShapeRenderer();
        renderer.setAutoShapeType(true);

        img = new Texture("pixel.png");                 // A 1x1 white pixel png
        imgBounds = new Rectangle();                    // The white image bounds
        imgBounds.setPosition(width / 7f, height / 4f); // Position the white image bounds
        imgBounds.setSize(400f, 300f);                  // Scale the white image bounds
        calculateRectangle();
    }

    private void calculateRectangle() {
        // Here we define the green rectangle's original position and size
        squareBounds = new Rectangle();
        squareX = width / 2f - 300f;
        squareY = height / 4f - 50f;
        squareWidth = 200f;
        squareHeight = 200f;
        // Adjust green square x position
        squareBounds.x = MathUtils.clamp(squareX, imgBounds.x, imgBounds.x + imgBounds.width);
        // Adjust green square y position
        squareBounds.y = MathUtils.clamp(squareY, imgBounds.y, imgBounds.y + imgBounds.height);
        // Adjust green square width
        if (squareX < imgBounds.x) {
            squareBounds.width = Math.max(squareWidth + squareX - imgBounds.x, 0f);
        } else if (squareX + squareWidth > imgBounds.x + imgBounds.width) {
            squareBounds.width = Math.max(imgBounds.width - squareX + imgBounds.x, 0f);
        } else {
            squareBounds.width = squareWidth;
        }
        // Adjust green square height
        if (squareY < imgBounds.y) {
            squareBounds.height = Math.max(squareHeight + squareY - imgBounds.y, 0f);
        } else if (squareY + squareHeight > imgBounds.y + imgBounds.height) {
            squareBounds.height = Math.max(imgBounds.height - squareY + imgBounds.y, 0f);
        } else {
            squareBounds.height = squareHeight;
        }
    }

    @Override
    public void render() {
        // Clear previous frame
        Gdx.gl.glClearColor(1, 0, 0, 1);
        Gdx.gl.glClear(GL20.GL_COLOR_BUFFER_BIT);
        // Draw the white image
        batch.begin();
        batch.draw(img, imgBounds.x, imgBounds.y, imgBounds.width, imgBounds.height);
        batch.end();
        // Draw the green rectangle without affecting background
        renderer.begin();
        renderer.setColor(Color.GREEN);

        // Debug so we can see the real green rectangle
        renderer.set(ShapeRenderer.ShapeType.Line);
        renderer.rect(squareX, squareY, squareWidth, squareHeight);
        // Draw the modified green rectangle
        renderer.set(ShapeRenderer.ShapeType.Filled);
        renderer.rect(squareBounds.x, squareBounds.y, squareBounds.width, squareBounds.height);

        renderer.end();
    }
}

And the results are:

And with:

squareX = width / 2f + 100f;
squareY = height / 4f + 150f;


问:
How can I format this date into Day - Month - Year
```<code>def UpdateDate(WorstDate):
    Day = WorstDate[5:]
    Month = WorstDate[2:6]
    Year = WorstDate[:2]
    return Day + "-" + Month + "-" + Year
print(UpdateDate("202011Jan"))
</code>```

I keep getting (1Jan-2011-20)
I'm no pro so any advice would be appreciated.

答:
This might be useful:</p>

```<code>import time

timestr = time.strftime("%d-%m-%Y")

print(timestr)
</code>```

Body:
def UpdateDate(WorstDate):
    Day = WorstDate[5:]
    Month = WorstDate[2:6]
    Year = WorstDate[:2]
    return Day + "-" + Month + "-" + Year
print(UpdateDate("202011Jan"))

I keep getting (1Jan-2011-20)
I'm no pro so any advice would be appreciated.

Body:
This might be useful:

import time

timestr = time.strftime("%d-%m-%Y")

print(timestr)


问:
Search items in external JSON
I have the URL of a JSON file and I want to get all the items with the same value.
Example:

http://sampleurl.com has this JSON

```<code>`{
   "posts":[
      {
         "authors":[
           {
             {"name":"John",
              "age": 30
             },
             {"name":"John",
              "age": 35
             }
            }
         ]
       }
    ]
}`
</code>```

What I want to do is to list all those authors with the same name together with their age.

I have tried this with no success:

```<code>`var allposts = "http://sampleurl.com";
    $.each(allposts.posts.authors, function(i, v) {
        if (v.name == "John") {
        alert("Ok");
        return;
        }
    });`
</code>```

Thanks

答:
You need to get the data via an Ajax call - $.getJSON:

```<code>const authors = {};
$.getJSON( "http://sampleurl.com", data =>
  data.posts.authors.forEach(author => {
    authors[author.name] = authors[author.name] || []
    authors[author.name].push(author)
  });
);
</code>```

At the end you have an object keyed on unique author names, with each key containing as its value an array of the authors with that name. You can do further processing to transform that to the data structure you need.

This example doesn't deal with data coming back that isn't in the shape you expect. For example, if some author records are missing a name, you will end up with a key undefined. And if there is no authors key or no posts key in the returned object you will get an exception.

So you have to decide how your program should behave in those cases. Should it explode? Or return an empty object? If you want it to continue with an empty object:

```<code>const authors = {};
$.getJSON( "http://sampleurl.com", data =>
  if (data.posts && data.posts.authors) {
    authors.forEach(author => {
      const name = author.name || 'unknown';
      authors[author.name] = authors[author.name] || []
      authors[author.name].push(author)
    });
  } else {
    console.log('Warning! Data from API did not contain posts.authors!')
  }
);
</code>```

Note that neither of these examples deal with the AJAX call itself failing. For that you need to chain a .fail() handler:

```<code>const authors = {};
const url = "http://sampleurl.com"
$.getJSON( url, data =>
  if (data.posts && data.posts.authors) {
    authors.forEach(author => {
      const name = author.name || 'unknown';
      authors[author.name] = authors[author.name] || []
      authors[author.name].push(author)
    });
  } else {
    console.log('Warning! Data from API did not contain posts.authors!')
  }
).fail(res => console.log(`Ajax call to ${url} failed with message ${res.responseText}!`);
</code>```

10% of programming is getting it to work. The other 90% is coding for what happens when it doesn't work.

Title: Search items in external JSON

Body:
I have the URL of a JSON file and I want to get all the items with the same value.
Example:

http://sampleurl.com has this JSON

`{
   "posts":[
      {
         "authors":[
           {
             {"name":"John",
              "age": 30
             },
             {"name":"John",
              "age": 35
             }
            }
         ]
       }
    ]
}`

What I want to do is to list all those authors with the same name together with their age.

I have tried this with no success:

`var allposts = "http://sampleurl.com";
    $.each(allposts.posts.authors, function(i, v) {
        if (v.name == "John") {
        alert("Ok");
        return;
        }
    });`

Thanks

Body:
You need to get the data via an Ajax call - $.getJSON:

const authors = {};
$.getJSON( "http://sampleurl.com", data =>
  data.posts.authors.forEach(author => {
    authors[author.name] = authors[author.name] || []
    authors[author.name].push(author)
  });
);

At the end you have an object keyed on unique author names, with each key containing as its value an array of the authors with that name. You can do further processing to transform that to the data structure you need.

This example doesn't deal with data coming back that isn't in the shape you expect. For example, if some author records are missing a name, you will end up with a key undefined. And if there is no authors key or no posts key in the returned object you will get an exception.

So you have to decide how your program should behave in those cases. Should it explode? Or return an empty object? If you want it to continue with an empty object:

const authors = {};
$.getJSON( "http://sampleurl.com", data =>
  if (data.posts && data.posts.authors) {
    authors.forEach(author => {
      const name = author.name || 'unknown';
      authors[author.name] = authors[author.name] || []
      authors[author.name].push(author)
    });
  } else {
    console.log('Warning! Data from API did not contain posts.authors!')
  }
);

Note that neither of these examples deal with the AJAX call itself failing. For that you need to chain a .fail() handler:

const authors = {};
const url = "http://sampleurl.com"
$.getJSON( url, data =>
  if (data.posts && data.posts.authors) {
    authors.forEach(author => {
      const name = author.name || 'unknown';
      authors[author.name] = authors[author.name] || []
      authors[author.name].push(author)
    });
  } else {
    console.log('Warning! Data from API did not contain posts.authors!')
  }
).fail(res => console.log(`Ajax call to ${url} failed with message ${res.responseText}!`);

10% of programming is getting it to work. The other 90% is coding for what happens when it doesn't work.


问:
React Native - Promise returns undefined
I have a js file that returns whether I have internet connection or not, and then in another js I have an if else statement that gets that value. The thing is im getting connection = undefined.</p>

```<code>import React from 'react';
import NetInfo from "@react-native-community/netinfo";

const isConnected = function() {
  NetInfo.fetch().then(state => {
    console.log("state.isConnected: ", state.isConnected)
    return state.isConnected
  });
}

export default isConnected;
</code>```

```<code>import isConnected from '../../src/utils/internetConnection';

async checking(){
   var connection = await isConnected()
   console.log("connection : ", connection)
   if (connection){
      return true
   }

   Alert.alert("There is no Internet connection")
   return
}
</code>```

答:
try this instead</p>

```<code>export const isConnected = async function () {
    var networkState = await NetInfo.fetch()
    return networkState.isConnected
}
</code>```

Body:
I have a js file that returns whether I have internet connection or not, and then in another js I have an if else statement that gets that value. The thing is im getting connection = undefined.

import React from 'react';
import NetInfo from "@react-native-community/netinfo";

const isConnected = function() {
  NetInfo.fetch().then(state => {
    console.log("state.isConnected: ", state.isConnected)
    return state.isConnected
  });
}

export default isConnected;

import isConnected from '../../src/utils/internetConnection';

async checking(){
   var connection = await isConnected()
   console.log("connection : ", connection)
   if (connection){
      return true
   }

   Alert.alert("There is no Internet connection")
   return
}

Body:
try this instead

export const isConnected = async function () {
    var networkState = await NetInfo.fetch()
    return networkState.isConnected
}


问:
rewrite prefix url in nginx location
My nginx config file like this:

```<code>server {
    listen 80;
    listen 443 ssl;
    server_name XXX.com;

    error_log  /log/nginx/xxx.com_error.log;
    access_log /log/nginx/xxx.com_access.log main;

    root /data/www/;
    index index.php index.html index.htm;

    location ~ \.php$ {
        add_header X-Frame-Options SAMEORIGIN;

        fastcgi_pass   127.0.0.1:9000;
        fastcgi_param  SCRIPT_FILENAME  $document_root$fastcgi_script_name;
        include        fastcgi_params;
    }
}
</code>```

We need to config the nginx to satisfy following:

1、If url does not has prefix "/api/mobile/index.php"，and the request's port is 80, redirect it to https
2、If url has prefix "/api/mobile/index.php"，just go on

So I add content in the config file:

```<code>    location ~ ^(?!/api/mobile/index\.php).*$ {
        if ($server_port = "80") {
               return 301 https://$server_name$request_uri;
        }

        rewrite /* $server_name$reqeust_uri last;
    }
</code>```

Now the config file content is :

```<code>server {
    listen 80;
    listen 443 ssl;
    server_name XXX.com;

    error_log  /log/nginx/xxx.com_error.log;
    access_log /log/nginx/xxx.com_access.log main;

    root /data/www/;
    index index.php index.html index.htm;

    location ~ ^(?!/api/mobile/index\.php).*$ {
        if ($server_port = "80") {
               return 301 https://$server_name$request_uri;
        }

        rewrite /* $server_name$reqeust_uri last;
    }

    location ~ \.php$ {
        add_header X-Frame-Options SAMEORIGIN;

        fastcgi_pass   127.0.0.1:9000;
        fastcgi_param  SCRIPT_FILENAME  $document_root$fastcgi_script_name;
        include        fastcgi_params;
    }
}
</code>```

Than the request match the first location, will not match the other location.

That means these request couldn't go through the php cgi.

Is there anyone who knows how to solve the problem?

答:
There's the option to use two separated server context, and didn't use if statement (read why here: https://www.nginx.com/resources/wiki/start/topics/depth/ifisevil/).

The configuration could be:

```<code>server {
    listen 80;
    server_name XXX.com;

    error_log  /log/nginx/xxx.com_error.log;
    access_log /log/nginx/xxx.com_access.log;

    root /data/www;
    index index.php index.html index.htm;

    location /api/mobile/index.php {
        rewrite ^(.*)$ https://$host$1 redirect;
    }

    location ~ \.php$ {
        add_header X-Frame-Options SAMEORIGIN;

        fastcgi_pass  127.0.0.1:9000;
        fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;
        include       fastcgi_param;
    }
}

server {
    listen 443 ssl http2;
    server_name XXX.com;

    error_log  /log/nginx/xxx.com_ssl_error.log;
    access_log /log/nginx/xxx.com_ssl_access.log;

    root /data/www;
    index index.php index.html index.htm;

    location ~ \.php$ {
        add_header X-Frame-Options SAMEORIGIN;

        fastcgi_pass  127.0.0.1:9000;
        fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;
        include       fastcgi_param;
    }
}
</code>```

Title: rewrite prefix url in nginx location

Body:
My nginx config file like this:

server {
    listen 80;
    listen 443 ssl;
    server_name XXX.com;

    error_log  /log/nginx/xxx.com_error.log;
    access_log /log/nginx/xxx.com_access.log main;

    root /data/www/;
    index index.php index.html index.htm;

    location ~ \.php$ {
        add_header X-Frame-Options SAMEORIGIN;

        fastcgi_pass   127.0.0.1:9000;
        fastcgi_param  SCRIPT_FILENAME  $document_root$fastcgi_script_name;
        include        fastcgi_params;
    }
}

We need to config the nginx to satisfy following:

1、If url does not has prefix "/api/mobile/index.php"，and the request's port is 80, redirect it to https
2、If url has prefix "/api/mobile/index.php"，just go on

So I add content in the config file:

    location ~ ^(?!/api/mobile/index\.php).*$ {
        if ($server_port = "80") {
               return 301 https://$server_name$request_uri;
        }

        rewrite /* $server_name$reqeust_uri last;
    }

Now the config file content is :

server {
    listen 80;
    listen 443 ssl;
    server_name XXX.com;

    error_log  /log/nginx/xxx.com_error.log;
    access_log /log/nginx/xxx.com_access.log main;

    root /data/www/;
    index index.php index.html index.htm;

    location ~ ^(?!/api/mobile/index\.php).*$ {
        if ($server_port = "80") {
               return 301 https://$server_name$request_uri;
        }

        rewrite /* $server_name$reqeust_uri last;
    }

    location ~ \.php$ {
        add_header X-Frame-Options SAMEORIGIN;

        fastcgi_pass   127.0.0.1:9000;
        fastcgi_param  SCRIPT_FILENAME  $document_root$fastcgi_script_name;
        include        fastcgi_params;
    }
}

Than the request match the first location, will not match the other location.

That means these request couldn't go through the php cgi.

Is there anyone who knows how to solve the problem?

Body:
There's the option to use two separated server context, and didn't use if statement (read why here: https://www.nginx.com/resources/wiki/start/topics/depth/ifisevil/).

The configuration could be:

server {
    listen 80;
    server_name XXX.com;

    error_log  /log/nginx/xxx.com_error.log;
    access_log /log/nginx/xxx.com_access.log;

    root /data/www;
    index index.php index.html index.htm;

    location /api/mobile/index.php {
        rewrite ^(.*)$ https://$host$1 redirect;
    }

    location ~ \.php$ {
        add_header X-Frame-Options SAMEORIGIN;

        fastcgi_pass  127.0.0.1:9000;
        fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;
        include       fastcgi_param;
    }
}

server {
    listen 443 ssl http2;
    server_name XXX.com;

    error_log  /log/nginx/xxx.com_ssl_error.log;
    access_log /log/nginx/xxx.com_ssl_access.log;

    root /data/www;
    index index.php index.html index.htm;

    location ~ \.php$ {
        add_header X-Frame-Options SAMEORIGIN;

        fastcgi_pass  127.0.0.1:9000;
        fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;
        include       fastcgi_param;
    }
}


问:
Syntax Error in FROM Clause in C#(MS Access)
I am getting Syntax error in from clause while accessing data from MS Access database but if i run the same query in access i get the desired results without any error.

Any help is appreciated.
This is my code

```<code>string strQuery = string.Empty  ;

            strQuery = "SELECT TUCLRII.LUSID,TUCLRII.UserID,TUCLRII.LastName,TUCLRII.FirstName,TUCLRII.MI,TUCLRII.Sex,TUCLRII.WhichEye,TUCLRII.Memo1,TUCLRII.Memo2,TUCLRII.CreationDT, TUCLRII.LastModifiedDT,TUCLRII.CardID,TUCLRI.UCID,TUCLRII.WiegandData,TUCLRII.LIrisCodeID,TUCLRII.LWhichEye,TUCLRII.LIrisCode,TUCLRII.RIrisCodeID,TUCLRII.RWhichEye,TUCLRII.RIrisCode,TUCLRII.LIrisImage,TUCLRII.LImageFormat,TUCLRII.LImageSize,TUCLRII.LWhichEye,TUCLRII.RIrisImage,TUCLRII.RImageFormat,TUCLRII.RImageSize,TUCLRII.RWhichEye,TIM.ImageFormat,TIM.ImageSize,TIM.FaceImage,TIM.PictureTakenDT";
            strQuery += " FROM (SELECT TUCLRI.LUSID,TUCLRI.UUID,TUCLRI.UserID,TUCLRI.LastName,TUCLRI.FirstName,TUCLRI.MI,TUCLRI.Sex,TUCLRI.WhichEye,TUCLRI.Memo1,TUCLRI.Memo2,TUCLRI.CreationDT,TUCLRI.LastModifiedDT, TUCLRI.CardID, TUCLRI.UCID, TUCLRI.WiegandData, TUCLRI.LIrisCodeID ,TUCLRI.LWhichEye,TUCLRI.LIrisCode,TUCLRI.RIrisCodeID,TUCLRI.RWhichEye,TUCLRI.RIrisCode,TUCLRI.LIrisImage,TUCLRI.LImageFormat,TUCLRI.LImageSize,TUCLRI.LWhichEye,TRIM.IrisImage as RIrisImage,TRIM.ImageFormat as RImageFormat, TRIM.ImageSize as RImageSize, TRIM.WhichEye as RWhichEye";
            strQuery += " FROM (SELECT TUCLR.LUSID,TUCLR.UUID,TUCLR.UserID,TUCLR.LastName,TUCLR.FirstName,TUCLR.MI,TUCLR.Sex,TUCLR.WhichEye,TUCLR.Memo1,TUCLR.Memo2,TUCLR.CreationDT,TUCLR.LastModifiedDT,TUCLR.CardID,TUCLR.UCID,TUCLR.WiegandData,TUCLR.LIrisCodeID,TUCLR.LWhichEye,TUCLR.LIrisCode,TUCLR.RIrisCodeID,TUCLR.RWhichEye,TUCLR.RIrisCode,TLIM.IrisImage as LIrisImage,TLIM.ImageFormat as LimageFormat,TLIM.ImageSize as LImageSize,TLIM.WhichEye as LWhichEye";
            strQuery += " FROM (SELECT TUCI.LUSID,TUCI.UUID,TUCI.UserID,TUCI.LastName,TUCI.FirstName,TUCI.MI,TUCI.Sex,TUCI.WhichEye,TUCI.Memo1,TUCI.Memo2,TUCI.CreationDT,TUCI.LastModifiedDT,TUCI.CardID,TUCI.UCID,TUCI.WiegandData, TUCI.LIrisCodeID,TUCI.LWhichEye,TUCI.LIrisCode,TRI.IrisCodeID as RIrisCodeID,TRI.WhichEye as RWhichEye,TRI.IrisCode as RIrisCode";
            strQuery += " FROM (SELECT TUC.LUSID,TUC.UUID,TUC.UserID,TUC.LastName,TUC.FirstName,TUC.MI,TUC.Sex,TUC.WhichEye,TUC.Memo1,TUC.Memo2,TUC.CreationDT,TUC.LastModifiedDT,TUC.CardID,TUC.UCID,TUC.WiegandData,TLI.IrisCodeID as LIrisCodeID,TLI.WhichEye as LWhichEye,TLI.IrisCode as LIrisCode";
            strQuery += " FROM (SELECT TU.LUSID,TU.UUID,TU.UserID,TU.LastName,TU.FirstName,TU.MI,TU.Sex,TU.WhichEye,TU.Memo1,TU.Memo2,TU.CreationDT,TU.LastModifiedDT,TC.CardID,TC.UCID,TC.WiegandData FROM UserInfo TU left join CardInfo TC on (TU.UUID=TC.UUID and TU.LUSID = 0)) TUC LEFT JOIN IrisCodeInfo TLI ON(TUC.UUID = TLI.UUID and TLI.WhichEye=1))TUCI LEFT JOIN IrisCodeInfo TRI ON(TUCI.UUID = TRI.UUID and TRI.WhichEye=2))TUCLR LEFT JOIN IrisImageInfo TLIM ON(TUCLR.UUID = TLIM.UUID and TLIM.WhichEye=1))TUCLRI LEFT JOIN IrisImageInfo TRIM ON(TUCLRI.UUID = TRIM.UUID and TRIM.WhichEye=2))TUCLRII LEFT JOIN FaceImageInfo TIM ON(TUCLRII.UUID = TIM.UUID)";
</code>```

答: You're missing some spaces around the parentheses in your JOIN clauses.  I'm not sure if this is the issue, though.</p>

ContentLicense: CC BY-SA 3.0

Body:
I am getting Syntax error in from clause while accessing data from MS Access database but if i run the same query in access i get the desired results without any error.

Any help is appreciated.
This is my code

string strQuery = string.Empty  ;

            strQuery = "SELECT TUCLRII.LUSID,TUCLRII.UserID,TUCLRII.LastName,TUCLRII.FirstName,TUCLRII.MI,TUCLRII.Sex,TUCLRII.WhichEye,TUCLRII.Memo1,TUCLRII.Memo2,TUCLRII.CreationDT, TUCLRII.LastModifiedDT,TUCLRII.CardID,TUCLRI.UCID,TUCLRII.WiegandData,TUCLRII.LIrisCodeID,TUCLRII.LWhichEye,TUCLRII.LIrisCode,TUCLRII.RIrisCodeID,TUCLRII.RWhichEye,TUCLRII.RIrisCode,TUCLRII.LIrisImage,TUCLRII.LImageFormat,TUCLRII.LImageSize,TUCLRII.LWhichEye,TUCLRII.RIrisImage,TUCLRII.RImageFormat,TUCLRII.RImageSize,TUCLRII.RWhichEye,TIM.ImageFormat,TIM.ImageSize,TIM.FaceImage,TIM.PictureTakenDT";
            strQuery += " FROM (SELECT TUCLRI.LUSID,TUCLRI.UUID,TUCLRI.UserID,TUCLRI.LastName,TUCLRI.FirstName,TUCLRI.MI,TUCLRI.Sex,TUCLRI.WhichEye,TUCLRI.Memo1,TUCLRI.Memo2,TUCLRI.CreationDT,TUCLRI.LastModifiedDT, TUCLRI.CardID, TUCLRI.UCID, TUCLRI.WiegandData, TUCLRI.LIrisCodeID ,TUCLRI.LWhichEye,TUCLRI.LIrisCode,TUCLRI.RIrisCodeID,TUCLRI.RWhichEye,TUCLRI.RIrisCode,TUCLRI.LIrisImage,TUCLRI.LImageFormat,TUCLRI.LImageSize,TUCLRI.LWhichEye,TRIM.IrisImage as RIrisImage,TRIM.ImageFormat as RImageFormat, TRIM.ImageSize as RImageSize, TRIM.WhichEye as RWhichEye";
            strQuery += " FROM (SELECT TUCLR.LUSID,TUCLR.UUID,TUCLR.UserID,TUCLR.LastName,TUCLR.FirstName,TUCLR.MI,TUCLR.Sex,TUCLR.WhichEye,TUCLR.Memo1,TUCLR.Memo2,TUCLR.CreationDT,TUCLR.LastModifiedDT,TUCLR.CardID,TUCLR.UCID,TUCLR.WiegandData,TUCLR.LIrisCodeID,TUCLR.LWhichEye,TUCLR.LIrisCode,TUCLR.RIrisCodeID,TUCLR.RWhichEye,TUCLR.RIrisCode,TLIM.IrisImage as LIrisImage,TLIM.ImageFormat as LimageFormat,TLIM.ImageSize as LImageSize,TLIM.WhichEye as LWhichEye";
            strQuery += " FROM (SELECT TUCI.LUSID,TUCI.UUID,TUCI.UserID,TUCI.LastName,TUCI.FirstName,TUCI.MI,TUCI.Sex,TUCI.WhichEye,TUCI.Memo1,TUCI.Memo2,TUCI.CreationDT,TUCI.LastModifiedDT,TUCI.CardID,TUCI.UCID,TUCI.WiegandData, TUCI.LIrisCodeID,TUCI.LWhichEye,TUCI.LIrisCode,TRI.IrisCodeID as RIrisCodeID,TRI.WhichEye as RWhichEye,TRI.IrisCode as RIrisCode";
            strQuery += " FROM (SELECT TUC.LUSID,TUC.UUID,TUC.UserID,TUC.LastName,TUC.FirstName,TUC.MI,TUC.Sex,TUC.WhichEye,TUC.Memo1,TUC.Memo2,TUC.CreationDT,TUC.LastModifiedDT,TUC.CardID,TUC.UCID,TUC.WiegandData,TLI.IrisCodeID as LIrisCodeID,TLI.WhichEye as LWhichEye,TLI.IrisCode as LIrisCode";
            strQuery += " FROM (SELECT TU.LUSID,TU.UUID,TU.UserID,TU.LastName,TU.FirstName,TU.MI,TU.Sex,TU.WhichEye,TU.Memo1,TU.Memo2,TU.CreationDT,TU.LastModifiedDT,TC.CardID,TC.UCID,TC.WiegandData FROM UserInfo TU left join CardInfo TC on (TU.UUID=TC.UUID and TU.LUSID = 0)) TUC LEFT JOIN IrisCodeInfo TLI ON(TUC.UUID = TLI.UUID and TLI.WhichEye=1))TUCI LEFT JOIN IrisCodeInfo TRI ON(TUCI.UUID = TRI.UUID and TRI.WhichEye=2))TUCLR LEFT JOIN IrisImageInfo TLIM ON(TUCLR.UUID = TLIM.UUID and TLIM.WhichEye=1))TUCLRI LEFT JOIN IrisImageInfo TRIM ON(TUCLRI.UUID = TRIM.UUID and TRIM.WhichEye=2))TUCLRII LEFT JOIN FaceImageInfo TIM ON(TUCLRII.UUID = TIM.UUID)";


问:
Play reverse routing without a Request instance
I'm using a template to generate an email in Play. That email includes an URL which is generated through reverse routing :

```<code><a href="@routes.MyController.downloadFile(user).absoluteURL()">
</code>```

The problem is, the downloadFile function takes an implicit request: Request parameter (as any Action) and I don't always have a Request when I'm sending an email (it can be triggered out of a request/response workflow).

Is there some way to obtain the reverse route anyway ? Or maybe should I pass it a dummy request object (and then, how to generate one ?)

答:
When implicit request is not available, you should use method described below defined in play.mvc.Call (play.api.mvc.Call returned by reverse router extends java play.mvc.Call class, so there is no additional work needed):

/**
 * Transform this call to an absolute URL.
 *
 * @param secure true if the absolute URL should use HTTPS protocol instead of HTTP
 * @param host the absolute URL's domain
 * @return the absolute URL string
 */
 public String absoluteURL(boolean secure, String host)
```

<p>Example view code:</p>

```@(secure: Boolean, host: String)

```

secure and host values could be obtained from request or defined somewhere in application configuration.

Body:
I'm using a template to generate an email in Play. That email includes an URL which is generated through reverse routing :

The problem is, the downloadFile function takes an implicit request: Request parameter (as any Action) and I don't always have a Request when I'm sending an email (it can be triggered out of a request/response workflow).

Is there some way to obtain the reverse route anyway ? Or maybe should I pass it a dummy request object (and then, how to generate one ?)

Body:
When implicit request is not available, you should use method described below defined in play.mvc.Call (play.api.mvc.Call returned by reverse router extends java play.mvc.Call class, so there is no additional work needed):

/**
 * Transform this call to an absolute URL.
 *
 * @param secure true if the absolute URL should use HTTPS protocol instead of HTTP
 * @param host the absolute URL's domain
 * @return the absolute URL string
 */
 public String absoluteURL(boolean secure, String host)

Example view code:

@(secure: Boolean, host: String)
<a href="@routes.MyController.downloadFile(user).absoluteURL(secure, host)">

secure and host values could be obtained from request or defined somewhere in application configuration.


问:
apollo graph manager 406: Not Acceptable
I am trying to use apollo graph manager, but keep getting this error, when i try to publish my graph to apollo graph manager from my local terminal.

```<code>apollo service:push --endpoint=http://localhost:3050/graphql --key="service:salading_test"
  ✔ Loading Apollo Project
  ✔ Loading Apollo Project
  ✖ Uploading service to Apollo Graph Manager
    → 406: Not Acceptable
Error: 406: Not Acceptable
</code>```

This is what I got from apollo graph manager

```<code>ENGINE_API_KEY=service:salading_test:<key>
</code>```

I copied it and added it to my .env file and restarted my server.
In my server.js, I also tried with the following settings:

```<code>const { ApolloServer } = require('apollo-server-express');
const express = require('express');

const app = express();
const apolloInstance = new ApolloServer({
    schema,
    playground: true,
    introspection: true,
    engine: { //added
      apiKey: process.env.ENGINE_API_KEY
    }
  });

apolloInstance.applyMiddleware({ app, cors: false });
app.listen(process.env.PORT, () => console.log(`Server running on port: ${process.env.PORT}`));
</code>```

Now the tutorial in apollo docs uses 'apollo-server' instead of 'apollo-server-express'. But that shouldnt be a problem, since 'apollo-server' is used inside 'apollo-server-express'?

答: this error would indicate that you do not have the correct ENGINE_API_KEY loaded: https://github.com/apollographql/apollo-tooling/issues/1166</p>

Body:
I am trying to use apollo graph manager, but keep getting this error, when i try to publish my graph to apollo graph manager from my local terminal.

apollo service:push --endpoint=http://localhost:3050/graphql --key="service:salading_test"
  ✔ Loading Apollo Project
  ✔ Loading Apollo Project
  ✖ Uploading service to Apollo Graph Manager
    → 406: Not Acceptable
Error: 406: Not Acceptable

This is what I got from apollo graph manager

ENGINE_API_KEY=service:salading_test:<key>

I copied it and added it to my .env file and restarted my server.
In my server.js, I also tried with the following settings:

const { ApolloServer } = require('apollo-server-express');
const express = require('express');

const app = express();
const apolloInstance = new ApolloServer({
    schema,
    playground: true,
    introspection: true,
    engine: { //added
      apiKey: process.env.ENGINE_API_KEY
    }
  });

apolloInstance.applyMiddleware({ app, cors: false });
app.listen(process.env.PORT, () => console.log(`Server running on port: ${process.env.PORT}`));

Now the tutorial in apollo docs uses 'apollo-server' instead of 'apollo-server-express'. But that shouldnt be a problem, since 'apollo-server' is used inside 'apollo-server-express'?


问:
Australian Bureau of Statistics SDMX timeout issue
I'm trying to download Australian Bureau of Statistics data using pandasdmx.
I can download the ERP_COB using SDMX no problem but for ERP by SA2, age and sex I am getting a timeout error.
I have limited the time period to 2018 only but am still timing out.The weird thing is that it works sometimes but mostly not.
I would like to try limiting the parameters such as age or sex but not sure how to do this.
Any help would be much appreciated.

Thanks in advance.

```<code>from pandasdmx import Request

Agency_Code = 'ABS'
Dataset_Id = 'ABS_ERP_ASGS2016'
ABS = Request(Agency_Code)
data_response = ABS.data(resource_id='ABS_ERP_ASGS2016', params={'startTime': '2018','endTime': '2018'})
def timeout(self, value):
    self.client.config['timeout'] = 10000
ERP2018=data_response.write().unstack().reset_index()

ERP2018 = ERP2018[(ERP2018.REGIONTYPE =='AUS') | (ERP2018.REGIONTYPE =='STE')]

ERP2018.to_csv('c:\\Temp\\erp2018.csv')
</code>```

答:
I've managed to figure this out largely thanks to Anthony Kong.

I've modified the resource_id to match the URL given at the ABS website to apply a filter to my request to allow for a smaller request and no timeouts.
I've also been told how to change the ABS timeout value thanks to the ABS staff.
See below.

```<code>from pandasdmx import Request

Agency_Code = 'ABS'
Dataset_Id = 'ABS_ERP_ASGS2016'
ABS = Request(Agency_Code)
ABS.client.config['timeout'] = 100000
data_response = ABS.data(resource_id='ABS_ERP_ASGS2016/ERP.3+1+2.TT+A04+A59+A10+A15+A20+A25+A30+A35+A40+A45+A50+A55+A60+A65+A70+A75+A80+8599.AUS+STE..A/all?', params={'startTime': '2009','endTime': '2018'})

ERP2018=data_response.write().unstack().reset_index()

ERP2018.to_csv('c:\\Temp\\erp2018.csv')
</code>```

Body:
I'm trying to download Australian Bureau of Statistics data using pandasdmx.
I can download the ERP_COB using SDMX no problem but for ERP by SA2, age and sex I am getting a timeout error.
I have limited the time period to 2018 only but am still timing out.The weird thing is that it works sometimes but mostly not.
I would like to try limiting the parameters such as age or sex but not sure how to do this.
Any help would be much appreciated.

Thanks in advance.

from pandasdmx import Request

Agency_Code = 'ABS'
Dataset_Id = 'ABS_ERP_ASGS2016'
ABS = Request(Agency_Code)
data_response = ABS.data(resource_id='ABS_ERP_ASGS2016', params={'startTime': '2018','endTime': '2018'})
def timeout(self, value):
    self.client.config['timeout'] = 10000
ERP2018=data_response.write().unstack().reset_index()

ERP2018 = ERP2018[(ERP2018.REGIONTYPE =='AUS') | (ERP2018.REGIONTYPE =='STE')]

ERP2018.to_csv('c:\\Temp\\erp2018.csv')

Body:
I've managed to figure this out largely thanks to Anthony Kong.

I've modified the resource_id to match the URL given at the ABS website to apply a filter to my request to allow for a smaller request and no timeouts.
I've also been told how to change the ABS timeout value thanks to the ABS staff.
See below.

from pandasdmx import Request

Agency_Code = 'ABS'
Dataset_Id = 'ABS_ERP_ASGS2016'
ABS = Request(Agency_Code)
ABS.client.config['timeout'] = 100000
data_response = ABS.data(resource_id='ABS_ERP_ASGS2016/ERP.3+1+2.TT+A04+A59+A10+A15+A20+A25+A30+A35+A40+A45+A50+A55+A60+A65+A70+A75+A80+8599.AUS+STE..A/all?', params={'startTime': '2009','endTime': '2018'})

ERP2018=data_response.write().unstack().reset_index()

ERP2018.to_csv('c:\\Temp\\erp2018.csv')


问:
Why does intializing array with structs requires specifying the struct name
Why does this code produce compile time error?

```<code>#include <array>
#include <cstdint>
#include <string_view>

using namespace std::string_view_literals;

enum class my_enum : std::size_t {
    first = 0,
    second,
    third,

    COUNT,
};

struct my_enum_str_pair {
    std::string_view str;
    my_enum command;
};

constexpr
std::array<my_enum_str_pair, static_cast<std::size_t>(my_enum::COUNT)>
my_enum_str_pairs = {
    { "first"sv, my_enum::first },
    { "second"sv, my_enum::second }, // error: excess elements in struct initializer
    { "third"sv, my_enum::third },
};
</code>```

But if we change it to

```<code>...

constexpr
std::array<my_enum_str_pair, static_cast<std::size_t>(my_enum::COUNT)>
my_enum_str_pairs = {
    my_enum_str_pair{ "first"sv, my_enum::first },
    { "second"sv, my_enum::second },
    { "third"sv, my_enum::third },
};
</code>```

Is compiles just fine?

https://godbolt.org/z/pi2j8a

答:
You are missing a pair of brackets.

constexpr
std::array<my_enum_str_pair, static_cast<std::size_t>(my_enum::COUNT)>
my_enum_str_pairs =
{{
    { "first"sv, my_enum::first },
    { "second"sv, my_enum::second }, // error: excess elements in struct initializer
    { "third"sv, my_enum::third }
}};
```

Body:
Why does this code produce compile time error?

#include <array>
#include <cstdint>
#include <string_view>

using namespace std::string_view_literals;

enum class my_enum : std::size_t {
    first = 0,
    second,
    third,

    COUNT,
};

struct my_enum_str_pair {
    std::string_view str;
    my_enum command;
};

constexpr
std::array<my_enum_str_pair, static_cast<std::size_t>(my_enum::COUNT)>
my_enum_str_pairs = {
    { "first"sv, my_enum::first },
    { "second"sv, my_enum::second }, // error: excess elements in struct initializer
    { "third"sv, my_enum::third },
};

But if we change it to

...

constexpr
std::array<my_enum_str_pair, static_cast<std::size_t>(my_enum::COUNT)>
my_enum_str_pairs = {
    my_enum_str_pair{ "first"sv, my_enum::first },
    { "second"sv, my_enum::second },
    { "third"sv, my_enum::third },
};

Is compiles just fine?

https://godbolt.org/z/pi2j8a


问:
proj4 convert world coordinates to custom local frame aka how to set proj.def()
here is a world coordinate for the center of river north, chicago 41.892571, -87.630712
and here is where i want my coordinate system to be based from 41.881984 -87.629437 (south of river north in the loop, madison and state st)
i need a proj.def(<help_here>) such that when i transform the river north coordinate to my new coordinate system, it is x meters north and x meters west from the origin (at madison and state)

proj4.defs('chicagoFrame', "+proj=merc +lat_0=41.881984 +lon_0=-87.629437 +units=m +no_defs") this is what i've tried so far but im getting [ -1323.1922680083949, 5117321.60498216 ] which is way off. meaning its 1.3km west and 5,000km west of the origin

the right answer should be ~1km north and ~.1km west

my goal is to have local coordinates so I can say "a user is x meters away from the nearest post office" and from the very little that i know i dont think you can just subtract the coordinates from one another and even if you do you need to convert the difference in degrees to meters

答:
so i reverse engineered a solution but I have no idea why it works, or what easting/northing is and why you need it. i set but the origin and target coordinates to the same location 41.881984 -87.629437 and ran

```<code>proj4.defs('chicagoFrame', "+proj=merc +lat_0=41.881984 +lon_0=-87.629437 +units=m +no_defs")
proj4('chicagoFrame', [-87.62699284257677, 41.88005153127081])
</code>```

the expected output is [0,0] but i got [0, 5114784.278651999]
so i adjusted the y_0 value

```<code>proj4.defs('chicagoFrame', "+proj=merc +lat_0=41.881984 +lon_0=-87.629437 +y_0=-5114784.278651999 +units=m +no_defs")
</code>```

which output [0,0]
and now i have a projection that works, but better understand of how proj4js works

Body:
so i reverse engineered a solution but I have no idea why it works, or what easting/northing is and why you need it. i set but the origin and target coordinates to the same location 41.881984 -87.629437 and ran

proj4.defs('chicagoFrame', "+proj=merc +lat_0=41.881984 +lon_0=-87.629437 +units=m +no_defs")
proj4('chicagoFrame', [-87.62699284257677, 41.88005153127081])

the expected output is [0,0] but i got [0, 5114784.278651999]
so i adjusted the y_0 value

proj4.defs('chicagoFrame', "+proj=merc +lat_0=41.881984 +lon_0=-87.629437 +y_0=-5114784.278651999 +units=m +no_defs")

which output [0,0]
and now i have a projection that works, but better understand of how proj4js works


问:
CentOS RPM Packages
When I do rpm -qa | grep nano I can see that Nano Text Editor is installed onto my CentOS box.

But when I do rpm -qpi nano-2.9.8-1.el8.x86_64.rpm in the below given directory it shows me Install Date: (not installed)

Directory: cd /run/media/root/CentOS-8-BaseOS-x86_64/BaseOS/Packages/

```<code>[root@karancentos ~]# cd /run/media/root/CentOS-8-BaseOS-x86_64/BaseOS/Packages/
[root@karancentos Packages]# rpm -qpi nano-2.9.8-1.el8.x86_64.rpm
Name        : nano
Version     : 2.9.8
Release     : 1.el8
Architecture: x86_64
Install Date: (not installed)
Group       : Unspecified
Size        : 2328511
License     : GPLv3+
Signature   : RSA/SHA256, Mon 01 Jul 2019 08:15:52 PM EDT, Key ID 05b555b38483c65d
Source RPM  : nano-2.9.8-1.el8.src.rpm
Build Date  : Sat 11 May 2019 11:03:56 AM EDT
Build Host  : x86-02.mbox.centos.org
Relocations : (not relocatable)
Packager    : CentOS Buildsys <bugs@centos.org>
Vendor      : CentOS
URL         : https://www.nano-editor.org
Summary     : A small text editor
Description :
GNU nano is a small and friendly text editor.
</code>```

I'm not sure why does it comes up when doing rpm -qa | grep nano and then when I do rpm -qpi nano-2.9.8-1.el8.x86_64.rpm it shows me Install Date: (not installed)

Can someone please help me understand this?

Thanks!!

答: Using rpm -qpi <file> you're only querying a specific RPM package on the filesystem, here nano-2.9.8-1.el8.x86_64.rpm. However, without querying the RPM database (which does not happen if you use -p parameter!), the package is shown as "not installed". Only the RPM database knows if a package is installed or not. You're looking for rpm -qi <package>, thus rpm -qi nano in the specific case – this queries the RPM database and you will get the install date.

Title: CentOS RPM Packages

Body:
When I do rpm -qa | grep nano I can see that Nano Text Editor is installed onto my CentOS box.

But when I do rpm -qpi nano-2.9.8-1.el8.x86_64.rpm in the below given directory it shows me Install Date: (not installed)

Directory: cd /run/media/root/CentOS-8-BaseOS-x86_64/BaseOS/Packages/

[root@karancentos ~]# cd /run/media/root/CentOS-8-BaseOS-x86_64/BaseOS/Packages/
[root@karancentos Packages]# rpm -qpi nano-2.9.8-1.el8.x86_64.rpm
Name        : nano
Version     : 2.9.8
Release     : 1.el8
Architecture: x86_64
Install Date: (not installed)
Group       : Unspecified
Size        : 2328511
License     : GPLv3+
Signature   : RSA/SHA256, Mon 01 Jul 2019 08:15:52 PM EDT, Key ID 05b555b38483c65d
Source RPM  : nano-2.9.8-1.el8.src.rpm
Build Date  : Sat 11 May 2019 11:03:56 AM EDT
Build Host  : x86-02.mbox.centos.org
Relocations : (not relocatable)
Packager    : CentOS Buildsys <bugs@centos.org>
Vendor      : CentOS
URL         : https://www.nano-editor.org
Summary     : A small text editor
Description :
GNU nano is a small and friendly text editor.

I'm not sure why does it comes up when doing rpm -qa | grep nano and then when I do rpm -qpi nano-2.9.8-1.el8.x86_64.rpm it shows me Install Date: (not installed)

Can someone please help me understand this?

Thanks!!


问:
Get Count for Each Column values
Input

```<code>Create Table #t1 (CaseId Int, NewValue  char(2),Attribute char(2),TimeStamp datetime)

insert into #t1 values
(1,      'A',         'X'   ,       '2020-01-01 13:01'),
(1,      'Au',        'WB' ,        '2020-01-01 13:02'),
(1 ,     'C'  ,       'P'   ,       '2020-01-01 13:03'),
(1 ,     'Ma',        'WB' ,        '2020-01-01 13:04'),
(1 ,     'C'   ,      'D',          '2020-01-01 13:05'),
(1,      'D'  ,       'E',          '2020-01-01 13:04'),
(2 ,     'M'  ,       'P' ,         '2020-05-01 15:20'),
(2 ,     'X'  ,       'WB' ,        '2020-05-01 15:26'),
(2  ,    'Y' ,        'WB',         '2020-05-01 15:29'),
(2  ,    'X'  ,       'P'  ,         '2020-05-01 15:31')
</code>```

I need output like the following.

```<code>CaseId  NewValue    Attribute   TimeStamp   NewColumn   NewColumn   Count
1        A            X         01:00.0         NULL    NULL         0
1        Au           WB        02:00.0         Au-WB   Au-WB        2
1        C            P         03:00.0         Au-WB   Au-WB        2
1        Ma           WB        04:00.0         Ma-WB   Ma-WB        3
1        C            D         05:00.0         Ma-WB   Ma-WB        3
1        D            E         04:00.0         Ma-WB   Ma-WB        3
2        M            P         20:00.0         NULL    NULL         0
2        X            WB        26:00.0         X -WB   X -WB        1
2        Y            WB        29:00.0         Y -WB   Y -WB        2
2        X            P         31:00.0         Y -WB   Y -WB        2
</code>```

Squirrel helped to get everything minus count.  The query is as follows. Does anyone know how to get that count?

```<code>select  *, wb.NewColumn
from    #t1 t
        outer apply
        (
            select top 1 x.NewValue + '-' + x.Attibute as NewColumn
            from    #t1 x
            where   x.CaseId    = t.CaseId
            and     x.TimeStamp <= t.TimeStamp
            and     x.Attibute  = 'WB'
            order by x.TimeStamp desc
        ) wb
</code>```

答:
This looks like a gaps-and-island problem, where a new island starts everytime a record with Attribute 'WB' is encountered.

If so, here is one way to solve it using window functions:

```<code>select
    caseId,
    newValue,
    attribute,
    timeStamp,
    case when grp > 0
        then first_value(newValue) over(partition by caseId, grp order by timeStamp)
            + '-'
            + first_value(attribute) over(partition by caseId, grp order by timeStamp)
    end newValue,
    case when grp > 0
        then count(*) over(partition by caseId, grp)
        else 0
    end cnt
from (
    select
        t.*,
        sum(case when attribute = 'WB' then 1 else 0 end)
            over(partition by caseId order by timeStamp) grp
    from #t1 t
) t
order by caseId, timeStamp
</code>```

The inner query does a window sum() to define the groups: everytime attribute 'WB' is met for a given caseId, a new group starts. Then, the outer query uses first_value() to recover the first value in the group, and performs a window count() to compute the number of records per group. This is wrapped in conditional logic so the additional columns are not filled before the first 'WB' atribute is met.

Demo on DB Fiddle:

```
caseId | newValue | attribute | timeStamp               | newValue | cnt
-----: | :------- | :-------- | :---------------------- | :------- | --:
     1 | A        | X         | 2020-01-01 13:01:00.000 | <em>null</em>     |   0
     1 | Au       | WB        | 2020-01-01 13:02:00.000 | Au-WB    |   2
     1 | C        | P         | 2020-01-01 13:03:00.000 | Au-WB    |   2
     1 | Ma       | WB        | 2020-01-01 13:04:00.000 | Ma-WB    |   3
     1 | D        | E         | 2020-01-01 13:04:00.000 | Ma-WB    |   3
     1 | C        | D         | 2020-01-01 13:05:00.000 | Ma-WB    |   3
     2 | M        | P         | 2020-05-01 15:20:00.000 | <em>null</em>     |   0
     2 | X        | WB        | 2020-05-01 15:26:00.000 | X -WB    |   1
     2 | Y        | WB        | 2020-05-01 15:29:00.000 | Y -WB    |   2
     2 | X        | P         | 2020-05-01 15:31:00.000 | Y -WB    |   2
```

Title: Get Count for Each Column values

Body:
Input

Create Table #t1 (CaseId Int, NewValue  char(2),Attribute char(2),TimeStamp datetime)

insert into #t1 values
(1,      'A',         'X'   ,       '2020-01-01 13:01'),
(1,      'Au',        'WB' ,        '2020-01-01 13:02'),
(1 ,     'C'  ,       'P'   ,       '2020-01-01 13:03'),
(1 ,     'Ma',        'WB' ,        '2020-01-01 13:04'),
(1 ,     'C'   ,      'D',          '2020-01-01 13:05'),
(1,      'D'  ,       'E',          '2020-01-01 13:04'),
(2 ,     'M'  ,       'P' ,         '2020-05-01 15:20'),
(2 ,     'X'  ,       'WB' ,        '2020-05-01 15:26'),
(2  ,    'Y' ,        'WB',         '2020-05-01 15:29'),
(2  ,    'X'  ,       'P'  ,         '2020-05-01 15:31')

I need output like the following.

CaseId  NewValue    Attribute   TimeStamp   NewColumn   NewColumn   Count
1        A            X         01:00.0         NULL    NULL         0
1        Au           WB        02:00.0         Au-WB   Au-WB        2
1        C            P         03:00.0         Au-WB   Au-WB        2
1        Ma           WB        04:00.0         Ma-WB   Ma-WB        3
1        C            D         05:00.0         Ma-WB   Ma-WB        3
1        D            E         04:00.0         Ma-WB   Ma-WB        3
2        M            P         20:00.0         NULL    NULL         0
2        X            WB        26:00.0         X -WB   X -WB        1
2        Y            WB        29:00.0         Y -WB   Y -WB        2
2        X            P         31:00.0         Y -WB   Y -WB        2

Squirrel helped to get everything minus count.  The query is as follows. Does anyone know how to get that count?

select  *, wb.NewColumn
from    #t1 t
        outer apply
        (
            select top 1 x.NewValue + '-' + x.Attibute as NewColumn
            from    #t1 x
            where   x.CaseId    = t.CaseId
            and     x.TimeStamp <= t.TimeStamp
            and     x.Attibute  = 'WB'
            order by x.TimeStamp desc
        ) wb

Body:
This looks like a gaps-and-island problem, where a new island starts everytime a record with Attribute 'WB' is encountered.

If so, here is one way to solve it using window functions:

select
    caseId,
    newValue,
    attribute,
    timeStamp,
    case when grp > 0
        then first_value(newValue) over(partition by caseId, grp order by timeStamp)
            + '-'
            + first_value(attribute) over(partition by caseId, grp order by timeStamp)
    end newValue,
    case when grp > 0
        then count(*) over(partition by caseId, grp)
        else 0
    end cnt
from (
    select
        t.*,
        sum(case when attribute = 'WB' then 1 else 0 end)
            over(partition by caseId order by timeStamp) grp
    from #t1 t
) t
order by caseId, timeStamp

The inner query does a window sum() to define the groups: everytime attribute 'WB' is met for a given caseId, a new group starts. Then, the outer query uses first_value() to recover the first value in the group, and performs a window count() to compute the number of records per group. This is wrapped in conditional logic so the additional columns are not filled before the first 'WB' atribute is met.

Demo on DB Fiddle:

caseId | newValue | attribute | timeStamp               | newValue | cnt
-----: | :------- | :-------- | :---------------------- | :------- | --:
     1 | A        | X         | 2020-01-01 13:01:00.000 | null     |   0
     1 | Au       | WB        | 2020-01-01 13:02:00.000 | Au-WB    |   2
     1 | C        | P         | 2020-01-01 13:03:00.000 | Au-WB    |   2
     1 | Ma       | WB        | 2020-01-01 13:04:00.000 | Ma-WB    |   3
     1 | D        | E         | 2020-01-01 13:04:00.000 | Ma-WB    |   3
     1 | C        | D         | 2020-01-01 13:05:00.000 | Ma-WB    |   3
     2 | M        | P         | 2020-05-01 15:20:00.000 | null     |   0
     2 | X        | WB        | 2020-05-01 15:26:00.000 | X -WB    |   1
     2 | Y        | WB        | 2020-05-01 15:29:00.000 | Y -WB    |   2
     2 | X        | P         | 2020-05-01 15:31:00.000 | Y -WB    |   2


问:
How to save a SQLite binding into an NSString
I have the following bind statement for binding an SQLite column. I want to save this value into an NSString named journeyName. For this I have written the following statement:

```<code>NSString * journeyName = sqlite3_bind_text( compiledStatement, 1,
                                           [Gjourney UTF8String], -1,
                                           SQLITE_TRANSIENT );
</code>```

This gives me a warning that

initialization makes pointer from integer without a cast

and my app crashes.

答:
sqlite3_bind_text binds a text value to a SQL parameter prior to executing the SQL statement. This means that you are already in possession of the NSString* value that you are passing. The return value of sqlite3_bind_text is an int not NSString*.

If you mean that you want to the value that is returned to the SQL statement following executing it, then you need to look at sqlite3_column_text.

For example...

```<code>if (sqlite3_step(stmt) == SQLITE_ROW)
{
    char *cstr = (char*)sqlite3_column_text(stmt, 0); // 0 = the param index
    NSString *str = [NSString stringWithUTF8String:cstr];
}
</code>```

Body:
I have the following bind statement for binding an SQLite column. I want to save this value into an NSString named journeyName. For this I have written the following statement:

NSString * journeyName = sqlite3_bind_text( compiledStatement, 1,
                                           [Gjourney UTF8String], -1,
                                           SQLITE_TRANSIENT );

This gives me a warning that

initialization makes pointer from integer without a cast

and my app crashes.

Body:
sqlite3_bind_text binds a text value to a SQL parameter prior to executing the SQL statement. This means that you are already in possession of the NSString* value that you are passing. The return value of sqlite3_bind_text is an int not NSString*.

If you mean that you want to the value that is returned to the SQL statement following executing it, then you need to look at sqlite3_column_text.

For example...

if (sqlite3_step(stmt) == SQLITE_ROW)
{
    char *cstr = (char*)sqlite3_column_text(stmt, 0); // 0 = the param index
    NSString *str = [NSString stringWithUTF8String:cstr];
}


问:
How to insert array into database? Laravel Php
this might be a different question from the questions that has been asked here already about inserting arrays into the database, but mine is quite different.

Here's the code:

```<code>public function something(Request $request)
{
  $id = $request ->id;
  $name = $request->name;
  $money = $request ->money;

  $data = array(
    'name' => $name,
    'money' => $money,
  );

  $z = User::where('id',$id)
    ->select('name','money')
    ->first();

  $data2 = array(
    'name' => $z->name,
    'money' => $z->money,
  );

  $diff = array_diff($data,$data2);
  $diff_name = array_keys($diff);
  $diff_values = array_values($diff);
  for ($i = 0; $i < count($diff_name); $i++) {
    $z->$diff_name[$i] = $diff_values[$i];
    $z->save();
  }
  return 'Success';
}
</code>```

Model:

```<code>class User extends Model
{
    protected $table = 'users';
    protected $fillable = ['name','money'];
    public $timestamps = false;
}

$data:
array(2) { ["name"]=> string(9) "Somewhere" ["money"]=> string(7) "5123.00"}

 $data2:
array(2) { ["name"]=> string(8) "Anywhere" ["money"]=> string(7) "5000.00"}
</code>```

So I'm using array_diff to determine if the values that has been entered by the user is equal from the original value from the database, if theres a difference in value then get the column name($diff_name) and then insert the new value($diff_value).
I did it this way since I will be needing the values of $diff_name for history log purposes.
However I'm getting this error Array to string conversion
Thanks in advance.

答:
There is are several built in Eloquent methods that you could implement.

    public function something(Request $request)
    {
      $z = User::where('id',$request->id)
        ->select('name','money')
        ->first(); // You could also use '->firstOrFail()' if you want to stop execution if a model was not retrieved.

      $z->fill([
        'name' => $request->name,
        'money' => $request->money,
      ]);

      $diff = array_keys($z->getDirty());

      $z->save()'

      return 'Success';
    }

```

$model->firstOrFail()

Can be used to stop execution to prevent an error from trying to
  manipulate a model which was not retrieved from the database.

$model->fill()

This can be used to pass an array of values which you would like to
  update.

$request->only(['name','money])

Instead of passing an array to $model->fill() you could have also
  used this.

$model->getDirty()

After changing a models attributes (and before saving it) you can use
  this to get an associative array of the attributes and corresponding
  values which have changed.

Body:
this might be a different question from the questions that has been asked here already about inserting arrays into the database, but mine is quite different.

Here's the code:

public function something(Request $request)
{
  $id = $request ->id;
  $name = $request->name;
  $money = $request ->money;

  $data = array(
    'name' => $name,
    'money' => $money,
  );

  $z = User::where('id',$id)
    ->select('name','money')
    ->first();

  $data2 = array(
    'name' => $z->name,
    'money' => $z->money,
  );

  $diff = array_diff($data,$data2);
  $diff_name = array_keys($diff);
  $diff_values = array_values($diff);
  for ($i = 0; $i < count($diff_name); $i++) {
    $z->$diff_name[$i] = $diff_values[$i];
    $z->save();
  }
  return 'Success';
}

Model:

class User extends Model
{
    protected $table = 'users';
    protected $fillable = ['name','money'];
    public $timestamps = false;
}

$data:
array(2) { ["name"]=> string(9) "Somewhere" ["money"]=> string(7) "5123.00"}

 $data2:
array(2) { ["name"]=> string(8) "Anywhere" ["money"]=> string(7) "5000.00"}

So I'm using array_diff to determine if the values that has been entered by the user is equal from the original value from the database, if theres a difference in value then get the column name($diff_name) and then insert the new value($diff_value).
I did it this way since I will be needing the values of $diff_name for history log purposes.
However I'm getting this error Array to string conversion
Thanks in advance.

Body:
There is are several built in Eloquent methods that you could implement.

    public function something(Request $request)
    {
      $z = User::where('id',$request->id)
        ->select('name','money')
        ->first(); // You could also use '->firstOrFail()' if you want to stop execution if a model was not retrieved.

      $z->fill([
        'name' => $request->name,
        'money' => $request->money,
      ]);

      $diff = array_keys($z->getDirty());

      $z->save()'

      return 'Success';
    }

$model->firstOrFail()

Can be used to stop execution to prevent an error from trying to
  manipulate a model which was not retrieved from the database.

$model->fill()

This can be used to pass an array of values which you would like to
  update.

$request->only(['name','money])

Instead of passing an array to $model->fill() you could have also
  used this.

$model->getDirty()

After changing a models attributes (and before saving it) you can use
  this to get an associative array of the attributes and corresponding
  values which have changed.


问:
OnChange for Storing Value of Selected Drop Down Option
I have a Material UI dropdown menu. I will make a search later on the basis of the selected option from the drop down menu. How exactly could I use onChange() to store the option selected?

For now, I am trying to print the stored value (criteria) using typography at the end but instead of showing the selected value, I get a black page.

```<code>export default class userSearchPage extends Component<{}, { searchItem: string, criteria: string }>{

  constructor(props: Readonly<{}>) {
    super(props);
    this.state = {
      searchItem: '',
      criteria: '',
    };
    this.handleDropDownChange = this.handleDropDownChange.bind(this);
  }

  handleDropDownChange(selected: any) {
    this.setState({
        criteria: selected
    });
  }

  render() {
    return (
      <div>
        <PermanentDrawerLeft></PermanentDrawerLeft>
        <div className='main-content'>
          <MuiThemeProvider>
            <DropDownMenu onChange = {this.handleDropDownChange}>
              <MenuItem style={{ fontSize: "20px" }} primaryText="Search By" />
              <MenuItem value={1} style={{ fontSize: "20px" }} primaryText="First Name" />
              <MenuItem value={2} style={{ fontSize: "20px" }} primaryText="Last Name" />
              <MenuItem value={3} style={{ fontSize: "20px" }} primaryText="Phone Number" />
              <MenuItem value={4} style={{ fontSize: "20px" }} primaryText="Email" />
            </DropDownMenu>
          </MuiThemeProvider>
          <Typography>{this.state.criteria}</Typography>
          <br></br><br></br>
          <SearchBar
            onChange={e => this.setState({ searchItem: e })}
            value = {this.state.searchItem}
            onRequestSearch={() => console.log('onRequestSearch')}
            style={{
              margin: '0 auto',
              maxWidth: 800
            }}
          />
           <Typography>{this.state.criteria}</Typography>
        </div>
      </div>
    );
  }
}
</code>```

How could I fix this?

Note: This is typescript

Added

```<code>export default class userSearchPage extends Component<{}, { searchItem: string, criteria: any}>{

  constructor(props: Readonly<{}>) {
    super(props);
    this.state = {
      searchItem: '',
      criteria: null,
    };
    this.handleDropDownChange = this.handleDropDownChange.bind(this);
  }

  handleDropDownChange(event: any) {
    console.log(event.target.value);
    this.setState({
      criteria: event.target.value
    });
  }

  render() {
    return (
      <div>
        <PermanentDrawerLeft></PermanentDrawerLeft>
        <div className='main-content'>
        <InputLabel id="demo-simple-select-label">Search By</InputLabel>
          <Select
            value={this.state.criteria}
            onChange={this.handleDropDownChange}
            displayEmpty
          >
            <MenuItem disabled value="  ">
              <em>Search By</em>
            </MenuItem>
            <MenuItem value={1}>First Name</MenuItem>
            <MenuItem value={2}>Last Name</MenuItem>
            <MenuItem value={3}>Phone Number</MenuItem>
            <MenuItem value={4}>Email</MenuItem>
          </Select>
        </div>
      </div>
    );
  }
}
</code>```

答:
Assuming the DropDownMenu component is just a Material-UI Select component (https://material-ui.com/components/selects/#select), you need to update the state of your searchItem to the value of the selected MenuItem.

```<code><DropDownMenu onChange={event => {this.setState({searchItem: event.target.value})}>
</code>```

Note, currently in your example the first name and last name item are using the same value of 1.

Update - added the comment that contained the solution's code:

Here's an example using Material-UI's Select component instead of DropDownMenu: https://codesandbox.io/s/eager-hugle-tlfri

Body:
I have a Material UI dropdown menu. I will make a search later on the basis of the selected option from the drop down menu. How exactly could I use onChange() to store the option selected?

For now, I am trying to print the stored value (criteria) using typography at the end but instead of showing the selected value, I get a black page.

export default class userSearchPage extends Component<{}, { searchItem: string, criteria: string }>{

  constructor(props: Readonly<{}>) {
    super(props);
    this.state = {
      searchItem: '',
      criteria: '',
    };
    this.handleDropDownChange = this.handleDropDownChange.bind(this);
  }

  handleDropDownChange(selected: any) {
    this.setState({
        criteria: selected
    });
  }

  render() {
    return (

        <PermanentDrawerLeft></PermanentDrawerLeft>

          <MuiThemeProvider>
            <DropDownMenu onChange = {this.handleDropDownChange}>
              <MenuItem style={{ fontSize: "20px" }} primaryText="Search By" />
              <MenuItem value={1} style={{ fontSize: "20px" }} primaryText="First Name" />
              <MenuItem value={2} style={{ fontSize: "20px" }} primaryText="Last Name" />
              <MenuItem value={3} style={{ fontSize: "20px" }} primaryText="Phone Number" />
              <MenuItem value={4} style={{ fontSize: "20px" }} primaryText="Email" />
            </DropDownMenu>
          </MuiThemeProvider>
          <Typography>{this.state.criteria}</Typography>

          <SearchBar
            onChange={e => this.setState({ searchItem: e })}
            value = {this.state.searchItem}
            onRequestSearch={() => console.log('onRequestSearch')}
            style={{
              margin: '0 auto',
              maxWidth: 800
            }}
          />
           <Typography>{this.state.criteria}</Typography>

    );
  }
}

How could I fix this?

Note: This is typescript

Added

export default class userSearchPage extends Component<{}, { searchItem: string, criteria: any}>{

  constructor(props: Readonly<{}>) {
    super(props);
    this.state = {
      searchItem: '',
      criteria: null,
    };
    this.handleDropDownChange = this.handleDropDownChange.bind(this);
  }

  handleDropDownChange(event: any) {
    console.log(event.target.value);
    this.setState({
      criteria: event.target.value
    });
  }

  render() {
    return (

        <PermanentDrawerLeft></PermanentDrawerLeft>

        <InputLabel id="demo-simple-select-label">Search By</InputLabel>
          <Select
            value={this.state.criteria}
            onChange={this.handleDropDownChange}
            displayEmpty
          >
            <MenuItem disabled value="  ">
              Search By
            </MenuItem>
            <MenuItem value={1}>First Name</MenuItem>
            <MenuItem value={2}>Last Name</MenuItem>
            <MenuItem value={3}>Phone Number</MenuItem>
            <MenuItem value={4}>Email</MenuItem>
          </Select>

    );
  }
}

Body:
Assuming the DropDownMenu component is just a Material-UI Select component (https://material-ui.com/components/selects/#select), you need to update the state of your searchItem to the value of the selected MenuItem.

<DropDownMenu onChange={event => {this.setState({searchItem: event.target.value})}>

Note, currently in your example the first name and last name item are using the same value of 1.

Update - added the comment that contained the solution's code:

Here's an example using Material-UI's Select component instead of DropDownMenu: https://codesandbox.io/s/eager-hugle-tlfri


问:
UNITY creating blendshape from script problem

I've made a script that converts Meshes into SkinnedMeshRenderer, and creates a BlendShape for it.

Depending on all the debug information within the editor, everything looks correct!

But when i move the BlendShape slider, wrong vertices are moved.

here:

GREEN - current position of vertices.

MAGENTA - path of each vertex from initial position to delta position.

BLUE - position of each vertex in it's final delta position.

RED - position of each vertex that are not within the _selection bounds. stay equal to Vector3.zero.

BUT, when i try to see the blend shape in action, i get this:

When i try the same script, but just moving the vertices to their deltas, it also looks OKAY:

my question is simple.
WHAT am i doing wrong in the process of making a new BlendShape data for the mesh??

here is my c# code:

private void AddMorph(GameObject _ref, GameObject selection_mesh) {
    Mesh _m = new Mesh();

    // _selection - Bounds for selecting group of vertices within.
    _selection = new Bounds(selection_mesh.transform.position, selection_mesh.transform.localScale);

    // movement delta for future group of vertices.
    Vector3 newDelta = new Vector3(0, -0.4f, 0);

    // name for the future blend shape.
    string MorphName = "Custom[50-250]";

    //
    // Convert Mesh Renderer to Skinned Mesh Renderer, and create and instance of the shared mesh.
    //
    if (_ref.GetComponent < SkinnedMeshRenderer > () == null && _ref.GetComponent < MeshRenderer > () != null) {
        _m = Instantiate(_ref.GetComponent < MeshFilter > ().sharedMesh);
        Destroy(_ref.GetComponent < MeshRenderer > ());
        Destroy(_ref.GetComponent < MeshFilter > ());
        _ref.AddComponent < SkinnedMeshRenderer > ();
        _ref.GetComponent < SkinnedMeshRenderer > ().sharedMesh = _m;
    }
    else if (_ref.GetComponent < SkinnedMeshRenderer > () != null) // Create instance of shared mesh.
    {
        _m = Instantiate(_ref.GetComponent < SkinnedMeshRenderer > ().sharedMesh);
        _ref.GetComponent < SkinnedMeshRenderer > ().sharedMesh = _m;
    }
    else return; // if object has no renderer at all, stop the script execution.

    // Assign the new mesh we instantiated before.
    _ref.GetComponent < SkinnedMeshRenderer > ().sharedMesh = _m;
    // create array with deltas.
    Vector3[] newVertexDeltas = new Vector3[_m.vertices.Length];

    for (int y = 0; y < newVertexDeltas.Length; y++) {
        if (_selection.Contains(_ref.transform.TransformPoint(_m.vertices[y]))) {
            // each vertex found within the _selection bounds, gets the delta.
            newVertexDeltas[y] = newDelta;

            //GREEN draw line - current position of vertices.
            Debug.DrawLine(
            _ref.transform.TransformPoint(_m.vertices[y]), _ref.transform.TransformPoint(_m.vertices[y] + _m.normals[y] * 0.05f), Color.green, 1000000.0f);

            //MAGENTA draw line - path of each vertex from initial position to delta position.
            Debug.DrawLine(
            _ref.transform.TransformPoint(_m.vertices[y]), _ref.transform.TransformPoint(_m.vertices[y] + newDelta), Color.magenta, 1000000.0f);

            //BLUE draw line - position of each vertex in it's delta position.
            Debug.DrawLine(
            _ref.transform.TransformPoint(_m.vertices[y] + newDelta), _ref.transform.TransformPoint((_m.vertices[y] - _m.normals[y] * 0.05f) + newDelta), Color.blue, 1000000.0f);
        }
        else {
            //RED draw line - position of each vertex that are not within the _selection bounds.
            newVertexDeltas[y] = Vector3.zero;
            Debug.DrawLine(
            _ref.transform.TransformPoint(_m.vertices[y]), _ref.transform.TransformPoint(_m.vertices[y] - _m.normals[y] * 0.05f), Color.red, 1000000.0f);
        }
    }

    // Create the new blendshape with vertecies deltas.
    _m.AddBlendShapeFrame(MorphName, 100f, newVertexDeltas, null, null);
}
```

答:
Fixed.
Just executed Normals and Tangets recalculation right after adding the new BlendShape.
everything works great now.

}

    // Create the new blendshape with vertecies deltas.
    _m.AddBlendShapeFrame(MorphName, 100f, newVertexDeltas, null, null);
    _m.RecalculateNormals();
    _m.RecalculateTangents();
```


问:
Why my test accuracy falls when i use more epochs for training my CNN
I have a problem with my CNN. I trained my model for 50 epochs (BN, Dropouts used) and i got test accuracy 92%. After that i trained my  exact same network again but for 100 epochs, with just the same tuning and generalization techniques, and my test set's accuracy fell to 79%. Due to my small data set i used data augmentation (horizontal and vertical flip). I cannot explain this, can somebody help?</p>

```<code>import numpy as np
import tensorflow as tf
from numpy.random import seed
seed(1)

tf.compat.v1.set_random_seed(2)
from tensorflow.python.client import device_lib
print(device_lib.list_local_devices())
import tensorflow as tf
sess = tf.compat.v1.Session(config=tf.compat.v1.ConfigProto(log_device_placement=True))
gpu_options = tf.GPUOptions(allow_growth=True)
session = tf.InteractiveSession(config=tf.ConfigProto(gpu_options=gpu_options))
import os
os.environ['KERAS_BACKEND']='tensorflow'

import keras
from tensorflow.keras.models import Sequential
from tensorflow.keras.callbacks import Callback, ModelCheckpoint, ReduceLROnPlateau
from tensorflow.keras.layers import Dense, Dropout, Activation, Flatten, BatchNormalization
from tensorflow.keras.layers import Conv2D,MaxPooling2D
from keras.utils import np_utils
from tensorflow.keras.optimizers import SGD,Adam
from tensorflow.keras.metrics import categorical_crossentropy
from keras.preprocessing.image import ImageDataGenerator
from tensorflow.keras.layers import BatchNormalization
import matplotlib as plt
from matplotlib import pyplot as plt
from sklearn.metrics import confusion_matrix
import itertools

keras.initializers.glorot_normal(seed=42)

train_path='C:/Users/Panagiotis Gkanos/Desktop/dataset/40X/train'
train_batches=ImageDataGenerator(rescale=1./255,horizontal_flip=True,
vertical_flip=True).flow_from_direct ory(train_path,
                                                  target_size=[400,400],
                                                  classes=['malignant','benign'],
                                                  class_mode='categorical',batch_size=40)

valid_path='C:/Users/Panagiotis Gkanos/Desktop/dataset/40X/valid'
valid_batches=ImageDataGenerator(rescale=1./255).flow_from_directory(valid_path,
                                                  target_size=[400,400],
                                                  classes=['malignant','benign'],
                                                  class_mode='categorical',batch_size=20)

test_path='C:/Users/Panagiotis Gkanos/Desktop/dataset/40X/test'
test_batches=ImageDataGenerator(rescale=1./255).flow_from_directory(test_path,
                                                  target_size=[400,400],
                                                  classes=['malignant','benign'],
                                                  class_mode='categorical',batch_size=20)

model=Sequential()

model.add(Conv2D(16,(3,3),strides=2,padding='same',input_shape=(400,400,3)))
model.add(Activation('relu'))
model.add(BatchNormalization())
model.add(Conv2D(16,(3,3),strides=1,padding='same'))
model.add(Activation('relu'))
model.add(BatchNormalization())
model.add(Conv2D(16,(3,3),strides=1,padding='same'))
model.add(Activation('relu'))
model.add(BatchNormalization())
model.add(MaxPooling2D(pool_size=(2, 2),strides=2))

model.add(Conv2D(32,(3,3),strides=1,padding='same'))
model.add(Activation('relu'))
model.add(BatchNormalization())
model.add(Conv2D(32,(3,3),strides=1,padding='same'))
model.add(Activation('relu'))
model.add(BatchNormalization())
model.add(Conv2D(32,(3,3),strides=1,padding='same'))
model.add(Activation('relu'))
model.add(BatchNormalization())
model.add(MaxPooling2D(pool_size=(2, 2),strides=2))

model.add(Conv2D(64,(3,3),padding='same'))
model.add(Activation('relu'))
model.add(BatchNormalization())
model.add(MaxPooling2D(pool_size=(2, 2),strides=2))

model.add(Conv2D(128,(3,3),padding='same'))
model.add(Activation('relu'))
model.add(BatchNormalization())
model.add(MaxPooling2D(pool_size=(2, 2),strides=2))

model.add(Flatten())
model.add(Dense(256,activation='relu'))
model.add(Dropout(0.3))
model.add(Dense(128,activation='relu'))

model.add(Dropout(0.3))

model.add(Dense(2,activation='softmax'))
model.summary()

#learn_control = ReduceLROnPlateau(monitor='val_acc', patience=5,
                             # verbose=1,factor=0.2, min_lr=1e-7)

model.compile(optimizer=Adam(lr=0.001),loss='categorical_crossentropy',metrics=['accuracy'])
history=model.fit_generator(train_batches,steps_per_epoch=20 ,validation_data=valid_batches,
                        validation_steps=8 ,epochs=100)
#,callbacks=[learn_control])

model.evaluate(test_batches)

def plot_loss(history):
    train_loss=history.history['loss']
    val_loss=history.history['val_loss']
    x=list(range(1,len(val_loss)+1))
    plt.plot(x,val_loss,color='red',label='validation loss')
    plt.plot(x,train_loss,label='training loss')
    plt.xlabel('Epoch')
    plt.ylabel('Loss')
    plt.title('Loss vs. Epoch')
    plt.legend()
    plt.show()

def plot_accuracy(history):
    train_acc=history.history['acc']
    val_acc=history.history['val_acc']
    x=list(range(1,len(val_acc)+1))
    plt.plot(x,val_acc,color='red',label='validation acc')
    plt.plot(x,train_acc,label='training acc')
    plt.xlabel('Epoch')
    plt.ylabel('Accuracy')
    plt.title('Accuracy vs. Epoch')
    plt.legend()
    plt.show()

plot_loss(history)

plot_accuracy(history)
</code>```

答:
This is what is referred to as "overfitting." If your network had better test performance at 50 epochs, you may want to stop there.

In this case it is likely due to having a small data set for which the network will be unable to find general patterns which fit all cases. Instead it is fitting to small recurring details from your training data.

For instance, if you were to train a CNN to perform animal classification, bird or dog, using only blue birds in your training set and dogs of various colors in your training set. If you test your network with a picture of a bird that is any color other than blue, it is likely that it will classify as a dog because your network learned that everything blue is a bird and everything else is a dog instead of learning what features are unique to birds and what features are unique to dogs.

The short of it is, you likely just need a bigger, more varied data set. You could also implement early stopping, which will stop the network from training before it overfits to the data. Otherwise you can try other forms of regularization, but this is a difficult problem to overcome.

Body:
I have a problem with my CNN. I trained my model for 50 epochs (BN, Dropouts used) and i got test accuracy 92%. After that i trained my  exact same network again but for 100 epochs, with just the same tuning and generalization techniques, and my test set's accuracy fell to 79%. Due to my small data set i used data augmentation (horizontal and vertical flip). I cannot explain this, can somebody help?

import numpy as np
import tensorflow as tf
from numpy.random import seed
seed(1)

tf.compat.v1.set_random_seed(2)
from tensorflow.python.client import device_lib
print(device_lib.list_local_devices())
import tensorflow as tf
sess = tf.compat.v1.Session(config=tf.compat.v1.ConfigProto(log_device_placement=True))
gpu_options = tf.GPUOptions(allow_growth=True)
session = tf.InteractiveSession(config=tf.ConfigProto(gpu_options=gpu_options))
import os
os.environ['KERAS_BACKEND']='tensorflow'

import keras
from tensorflow.keras.models import Sequential
from tensorflow.keras.callbacks import Callback, ModelCheckpoint, ReduceLROnPlateau
from tensorflow.keras.layers import Dense, Dropout, Activation, Flatten, BatchNormalization
from tensorflow.keras.layers import Conv2D,MaxPooling2D
from keras.utils import np_utils
from tensorflow.keras.optimizers import SGD,Adam
from tensorflow.keras.metrics import categorical_crossentropy
from keras.preprocessing.image import ImageDataGenerator
from tensorflow.keras.layers import BatchNormalization
import matplotlib as plt
from matplotlib import pyplot as plt
from sklearn.metrics import confusion_matrix
import itertools

keras.initializers.glorot_normal(seed=42)

train_path='C:/Users/Panagiotis Gkanos/Desktop/dataset/40X/train'
train_batches=ImageDataGenerator(rescale=1./255,horizontal_flip=True,
vertical_flip=True).flow_from_direct ory(train_path,
                                                  target_size=[400,400],
                                                  classes=['malignant','benign'],
                                                  class_mode='categorical',batch_size=40)

valid_path='C:/Users/Panagiotis Gkanos/Desktop/dataset/40X/valid'
valid_batches=ImageDataGenerator(rescale=1./255).flow_from_directory(valid_path,
                                                  target_size=[400,400],
                                                  classes=['malignant','benign'],
                                                  class_mode='categorical',batch_size=20)

test_path='C:/Users/Panagiotis Gkanos/Desktop/dataset/40X/test'
test_batches=ImageDataGenerator(rescale=1./255).flow_from_directory(test_path,
                                                  target_size=[400,400],
                                                  classes=['malignant','benign'],
                                                  class_mode='categorical',batch_size=20)

model=Sequential()

model.add(Conv2D(16,(3,3),strides=2,padding='same',input_shape=(400,400,3)))
model.add(Activation('relu'))
model.add(BatchNormalization())
model.add(Conv2D(16,(3,3),strides=1,padding='same'))
model.add(Activation('relu'))
model.add(BatchNormalization())
model.add(Conv2D(16,(3,3),strides=1,padding='same'))
model.add(Activation('relu'))
model.add(BatchNormalization())
model.add(MaxPooling2D(pool_size=(2, 2),strides=2))

model.add(Conv2D(32,(3,3),strides=1,padding='same'))
model.add(Activation('relu'))
model.add(BatchNormalization())
model.add(Conv2D(32,(3,3),strides=1,padding='same'))
model.add(Activation('relu'))
model.add(BatchNormalization())
model.add(Conv2D(32,(3,3),strides=1,padding='same'))
model.add(Activation('relu'))
model.add(BatchNormalization())
model.add(MaxPooling2D(pool_size=(2, 2),strides=2))

model.add(Conv2D(64,(3,3),padding='same'))
model.add(Activation('relu'))
model.add(BatchNormalization())
model.add(MaxPooling2D(pool_size=(2, 2),strides=2))

model.add(Conv2D(128,(3,3),padding='same'))
model.add(Activation('relu'))
model.add(BatchNormalization())
model.add(MaxPooling2D(pool_size=(2, 2),strides=2))

model.add(Flatten())
model.add(Dense(256,activation='relu'))
model.add(Dropout(0.3))
model.add(Dense(128,activation='relu'))

model.add(Dropout(0.3))

model.add(Dense(2,activation='softmax'))
model.summary()

#learn_control = ReduceLROnPlateau(monitor='val_acc', patience=5,
                             # verbose=1,factor=0.2, min_lr=1e-7)

model.compile(optimizer=Adam(lr=0.001),loss='categorical_crossentropy',metrics=['accuracy'])
history=model.fit_generator(train_batches,steps_per_epoch=20 ,validation_data=valid_batches,
                        validation_steps=8 ,epochs=100)
#,callbacks=[learn_control])

model.evaluate(test_batches)

def plot_loss(history):
    train_loss=history.history['loss']
    val_loss=history.history['val_loss']
    x=list(range(1,len(val_loss)+1))
    plt.plot(x,val_loss,color='red',label='validation loss')
    plt.plot(x,train_loss,label='training loss')
    plt.xlabel('Epoch')
    plt.ylabel('Loss')
    plt.title('Loss vs. Epoch')
    plt.legend()
    plt.show()

def plot_accuracy(history):
    train_acc=history.history['acc']
    val_acc=history.history['val_acc']
    x=list(range(1,len(val_acc)+1))
    plt.plot(x,val_acc,color='red',label='validation acc')
    plt.plot(x,train_acc,label='training acc')
    plt.xlabel('Epoch')
    plt.ylabel('Accuracy')
    plt.title('Accuracy vs. Epoch')
    plt.legend()
    plt.show()

plot_loss(history)

plot_accuracy(history)