问:
Very weird behaviour when scaling objects
I am trying to scale object through parameters at a GUI box

This is the code:

    window.onload = init();
    animate();

    var scene, camera, renderer;
    var cube;
    var raycaster, mouse;
    var INTERSECTED;

    var isClicked = false;

params = {
  yAxis: "0.00001"
}
var gui = new dat.GUI();
gui.add(params, "yAxis").onFinishChange(val => {
  cube.scale.y = parseFloat(val);
});

 let vis = gui.domElement.style.visibility;
 gui.domElement.style.visibility = vis == "" ? "hidden" : "";

    function init() {

        scene = new THREE.Scene();

        camera = new THREE.PerspectiveCamera(75,window.innerWidth/window.innerHeight,0.1,1000)
        camera.position.z = 5;

        renderer = new THREE.WebGLRenderer({antialias: true});
        renderer.setClearColor("#e5e5e5"); //background color
        renderer.setSize(window.innerWidth,window.innerHeight); //size of renderer

        document.getElementById("WebGL-output").appendChild(renderer.domElement);

        raycaster = new THREE.Raycaster();
        mouse = new THREE.Vector2(1,1);

        var cubeGeometry = new THREE.BoxGeometry(20, 0.00001, 20);
        var cubeMaterial = new THREE.MeshLambertMaterial({color: 0xffff00 }); //0xF7F7F7 = gray
        cube = new THREE.Mesh(cubeGeometry, cubeMaterial);
        cube.userData.originalColor = 0xffff00;

        cube.position.x = 0;
        cube.position.y = 3;
        cube.position.z = 0;

        scene.add(cube);

        var ambientLight = new THREE.AmbientLight(0x0c0c0c);
        scene.add(ambientLight);
        var spotLight = new THREE.SpotLight(0xffffff);
        spotLight.position.set(-40, 60, -10);
        spotLight.castShadow = true;
        scene.add(spotLight);

        camera.position.x = -30;
        camera.position.y = 40;
        camera.position.z = 30;
        camera.lookAt(scene.position);

        document.addEventListener('mousemove', onDocumentMouseMove, false);

        document.addEventListener('click', onDocumentMouseClick, false);
    }

    function onDocumentMouseMove(event)
    {

      event.preventDefault();
      mouse.x = (event.clientX / window.innerWidth) * 2 - 1;
      mouse.y = -(event.clientY / window.innerHeight) * 2 + 1;

        var intersects = raycaster.intersectObjects( scene.children );

        if ( intersects.length > 0 && intersects[ 0 ].object === cube && isClicked === false)
        {
            cube.material.color.set( 0xff0000 );
        }
        else if (isClicked === false)
        {
            cube.material.color.set( cube.userData.originalColor );
        }

    }

    function onDocumentMouseClick(event)
    {

        event.preventDefault();

        mouse.x = (event.clientX / window.innerWidth) * 2 - 1;
        mouse.y = -(event.clientY / window.innerHeight) * 2 + 1;

        var intersects = raycaster.intersectObjects( scene.children );

        if ( intersects.length > 0 && intersects[ 0 ].object === cube && isClicked === false)
        {
            isClicked = true;
            cube.material.color.set( 0xF7F7F7 );

            vis = gui.domElement.style.visibility;
            gui.domElement.style.visibility = vis == "" ? "hidden" : "";

        }
        else if ( intersects.length > 0 && intersects[ 0 ].object === cube && isClicked === true)
        {
            isClicked = false;
            cube.material.color.set( cube.userData.originalColor );

            vis = gui.domElement.style.visibility;
            gui.domElement.style.visibility = vis == "" ? "hidden" : "";
        }

    }

    function render()
    {

        raycaster.setFromCamera( mouse, camera );
        renderer.render(scene, camera);
    }

    function animate()
    {
        requestAnimationFrame( animate );
        render();
    }```
<pre class="snippet-code-html lang-html prettyprint-override"><code><!DOCTYPE html>

<html>

<head>
    <title>Example 01.02 - First Scene</title>
    <script type="text/javascript" src="https://cdnjs.cloudflare.com/ajax/libs/three.js/110/three.min.js"></script>
    <script src="https://cdnjs.cloudflare.com/ajax/libs/dat-gui/0.7.6/dat.gui.min.js"></script>
    <style>
        body {
            margin: 0;
            overflow: hidden;
        }
    </style>
</head>
<body>

<!-- Div which will hold the Output -->
<div id="WebGL-output">
</div>

</body>
</html></code>```

There is very weird behaviour that i cannot understand why it happens:

More specifically:

If i leave the cube as it is in the code (20, 0.00001, 20)
Then the y parameter cannot be changed from the GUI.
X and z get changed but if, for example i give the value 2, they mesh gets bigger.
How is that possible that from 20, to 2, the mesh gets bigger?

I experimented with changing the cube constructor and i used (20,20,20)
Now the y gets changed, but it always gets bigger as well....

Summing up, MY QUESTIONS:

1) When the values are initialized at 20... Why does a new values that is less than 20 make the mesh appear bigger?

2) When the y parameter has an initial value of 0.00001... Why it cannot be changed from the GUI at all?

答:
This is because cube.scale acts as a multiplication to the geometry, but it's multiplying a very small number.

Think of it this way, you have the Geometry and the Mesh, and Mesh.scale multiples the values of the geometry. Let's just look at the Y value:

```<code>Geometry.y = 0.00001
Mesh.scale.y = 1
Visible height = 0.00001 * 1 = 0.00001;

// Now if you change the scale of y to 20
Geometry.y = 0.00001
Mesh.scale.y = 20
Visible height = 0.00001 * 20 = 0.0002;
</code>```

The problem is that you're initiating your geometry to be very small. You should change your geometry to start with larger values, and apply the scaling to the Mesh:

```<code>var cubeGeometry = new THREE.BoxGeometry(20, 20, 20);
cube = new THREE.Mesh(cubeGeometry, cubeMaterial);
cube.scale.y = 0.00001;
</code>```

window.onload = init();
    animate();

    var scene, camera, renderer;
    var cube;
    var raycaster, mouse;
    var INTERSECTED;

    var isClicked = false;

params = {
  yAxis: "0.00001"
}
var gui = new dat.GUI();
gui.add(params, "yAxis").onFinishChange(val => {
  cube.scale.y = parseFloat(val);
});

 let vis = gui.domElement.style.visibility;
 gui.domElement.style.visibility = vis == "" ? "hidden" : "";

    function init() {

        scene = new THREE.Scene();

        camera = new THREE.PerspectiveCamera(75,window.innerWidth/window.innerHeight,0.1,1000)
        camera.position.z = 5;

        renderer = new THREE.WebGLRenderer({antialias: true});
        renderer.setClearColor("#e5e5e5"); //background color
        renderer.setSize(window.innerWidth,window.innerHeight); //size of renderer

        document.getElementById("WebGL-output").appendChild(renderer.domElement);

        raycaster = new THREE.Raycaster();
        mouse = new THREE.Vector2(1,1);

        var cubeGeometry = new THREE.BoxGeometry(20, 20, 20);
        var cubeMaterial = new THREE.MeshLambertMaterial({color: 0xffff00 }); //0xF7F7F7 = gray
        cube = new THREE.Mesh(cubeGeometry, cubeMaterial);
        cube.scale.y = 0.00001;
        cube.userData.originalColor = 0xffff00;

        cube.position.x = 0;
        cube.position.y = 3;
        cube.position.z = 0;

        scene.add(cube);

        var ambientLight = new THREE.AmbientLight(0x0c0c0c);
        scene.add(ambientLight);
        var spotLight = new THREE.SpotLight(0xffffff);
        spotLight.position.set(-40, 60, -10);
        spotLight.castShadow = true;
        scene.add(spotLight);

        camera.position.x = -30;
        camera.position.y = 40;
        camera.position.z = 30;
        camera.lookAt(scene.position);

        document.addEventListener('mousemove', onDocumentMouseMove, false);

        document.addEventListener('click', onDocumentMouseClick, false);
    }

    function onDocumentMouseMove(event)
    {

      event.preventDefault();
      mouse.x = (event.clientX / window.innerWidth) * 2 - 1;
      mouse.y = -(event.clientY / window.innerHeight) * 2 + 1;

        var intersects = raycaster.intersectObjects( scene.children );

        if ( intersects.length > 0 && intersects[ 0 ].object === cube && isClicked === false)
        {
            cube.material.color.set( 0xff0000 );
        }
        else if (isClicked === false)
        {
            cube.material.color.set( cube.userData.originalColor );
        }

    }

    function onDocumentMouseClick(event)
    {

        event.preventDefault();

        mouse.x = (event.clientX / window.innerWidth) * 2 - 1;
        mouse.y = -(event.clientY / window.innerHeight) * 2 + 1;

        var intersects = raycaster.intersectObjects( scene.children );

        if ( intersects.length > 0 && intersects[ 0 ].object === cube && isClicked === false)
        {
            isClicked = true;
            cube.material.color.set( 0xF7F7F7 );

            vis = gui.domElement.style.visibility;
            gui.domElement.style.visibility = vis == "" ? "hidden" : "";

        }
        else if ( intersects.length > 0 && intersects[ 0 ].object === cube && isClicked === true)
        {
            isClicked = false;
            cube.material.color.set( cube.userData.originalColor );

            vis = gui.domElement.style.visibility;
            gui.domElement.style.visibility = vis == "" ? "hidden" : "";
        }

    }

    function render()
    {

        raycaster.setFromCamera( mouse, camera );
        renderer.render(scene, camera);
    }

    function animate()
    {
        requestAnimationFrame( animate );
        render();
    }```
<pre class="snippet-code-html lang-html prettyprint-override"><code><!DOCTYPE html>

<html>

<head>
    <title>Example 01.02 - First Scene</title>
    <script type="text/javascript" src="https://cdnjs.cloudflare.com/ajax/libs/three.js/110/three.min.js"></script>
    <script src="https://cdnjs.cloudflare.com/ajax/libs/dat-gui/0.7.6/dat.gui.min.js"></script>
    <style>
        body {
            margin: 0;
            overflow: hidden;
        }
    </style>
</head>
<body>

<!-- Div which will hold the Output -->
<div id="WebGL-output">
</div>

</body>
</html></code>```

Body:
I am trying to scale object through parameters at a GUI box

This is the code:

    window.onload = init();
    animate();

    var scene, camera, renderer;
    var cube;
    var raycaster, mouse;
    var INTERSECTED;

    var isClicked = false;

params = {
  yAxis: "0.00001"
}
var gui = new dat.GUI();
gui.add(params, "yAxis").onFinishChange(val => {
  cube.scale.y = parseFloat(val);
});

 let vis = gui.domElement.style.visibility;
 gui.domElement.style.visibility = vis == "" ? "hidden" : "";

    function init() {

        scene = new THREE.Scene();

        camera = new THREE.PerspectiveCamera(75,window.innerWidth/window.innerHeight,0.1,1000)
        camera.position.z = 5;

        renderer = new THREE.WebGLRenderer({antialias: true});
        renderer.setClearColor("#e5e5e5"); //background color
        renderer.setSize(window.innerWidth,window.innerHeight); //size of renderer

        document.getElementById("WebGL-output").appendChild(renderer.domElement);

        raycaster = new THREE.Raycaster();
        mouse = new THREE.Vector2(1,1);

        var cubeGeometry = new THREE.BoxGeometry(20, 0.00001, 20);
        var cubeMaterial = new THREE.MeshLambertMaterial({color: 0xffff00 }); //0xF7F7F7 = gray
        cube = new THREE.Mesh(cubeGeometry, cubeMaterial);
        cube.userData.originalColor = 0xffff00;

        cube.position.x = 0;
        cube.position.y = 3;
        cube.position.z = 0;

        scene.add(cube);

        var ambientLight = new THREE.AmbientLight(0x0c0c0c);
        scene.add(ambientLight);
        var spotLight = new THREE.SpotLight(0xffffff);
        spotLight.position.set(-40, 60, -10);
        spotLight.castShadow = true;
        scene.add(spotLight);

        camera.position.x = -30;
        camera.position.y = 40;
        camera.position.z = 30;
        camera.lookAt(scene.position);

        document.addEventListener('mousemove', onDocumentMouseMove, false);

        document.addEventListener('click', onDocumentMouseClick, false);
    }

    function onDocumentMouseMove(event)
    {

      event.preventDefault();
      mouse.x = (event.clientX / window.innerWidth) * 2 - 1;
      mouse.y = -(event.clientY / window.innerHeight) * 2 + 1;

        var intersects = raycaster.intersectObjects( scene.children );

        if ( intersects.length > 0 && intersects[ 0 ].object === cube && isClicked === false)
        {
            cube.material.color.set( 0xff0000 );
        }
        else if (isClicked === false)
        {
            cube.material.color.set( cube.userData.originalColor );
        }

    }

    function onDocumentMouseClick(event)
    {

        event.preventDefault();

        mouse.x = (event.clientX / window.innerWidth) * 2 - 1;
        mouse.y = -(event.clientY / window.innerHeight) * 2 + 1;

        var intersects = raycaster.intersectObjects( scene.children );

        if ( intersects.length > 0 && intersects[ 0 ].object === cube && isClicked === false)
        {
            isClicked = true;
            cube.material.color.set( 0xF7F7F7 );

            vis = gui.domElement.style.visibility;
            gui.domElement.style.visibility = vis == "" ? "hidden" : "";

        }
        else if ( intersects.length > 0 && intersects[ 0 ].object === cube && isClicked === true)
        {
            isClicked = false;
            cube.material.color.set( cube.userData.originalColor );

            vis = gui.domElement.style.visibility;
            gui.domElement.style.visibility = vis == "" ? "hidden" : "";
        }

    }

    function render()
    {

        raycaster.setFromCamera( mouse, camera );
        renderer.render(scene, camera);
    }

    function animate()
    {
        requestAnimationFrame( animate );
        render();
    }

<!DOCTYPE html>

    <title>Example 01.02 - First Scene</title>

There is very weird behaviour that i cannot understand why it happens:

More specifically:

If i leave the cube as it is in the code (20, 0.00001, 20)
Then the y parameter cannot be changed from the GUI.
X and z get changed but if, for example i give the value 2, they mesh gets bigger.
How is that possible that from 20, to 2, the mesh gets bigger?

I experimented with changing the cube constructor and i used (20,20,20)
Now the y gets changed, but it always gets bigger as well....

Summing up, MY QUESTIONS:

1) When the values are initialized at 20... Why does a new values that is less than 20 make the mesh appear bigger?

2) When the y parameter has an initial value of 0.00001... Why it cannot be changed from the GUI at all?

Body:
This is because cube.scale acts as a multiplication to the geometry, but it's multiplying a very small number.

Think of it this way, you have the Geometry and the Mesh, and Mesh.scale multiples the values of the geometry. Let's just look at the Y value:

Geometry.y = 0.00001
Mesh.scale.y = 1
Visible height = 0.00001 * 1 = 0.00001;

// Now if you change the scale of y to 20
Geometry.y = 0.00001
Mesh.scale.y = 20
Visible height = 0.00001 * 20 = 0.0002;

The problem is that you're initiating your geometry to be very small. You should change your geometry to start with larger values, and apply the scaling to the Mesh:

var cubeGeometry = new THREE.BoxGeometry(20, 20, 20);
cube = new THREE.Mesh(cubeGeometry, cubeMaterial);
cube.scale.y = 0.00001;

window.onload = init();
    animate();

    var scene, camera, renderer;
    var cube;
    var raycaster, mouse;
    var INTERSECTED;

    var isClicked = false;

params = {
  yAxis: "0.00001"
}
var gui = new dat.GUI();
gui.add(params, "yAxis").onFinishChange(val => {
  cube.scale.y = parseFloat(val);
});

 let vis = gui.domElement.style.visibility;
 gui.domElement.style.visibility = vis == "" ? "hidden" : "";

    function init() {

        scene = new THREE.Scene();

        camera = new THREE.PerspectiveCamera(75,window.innerWidth/window.innerHeight,0.1,1000)
        camera.position.z = 5;

        renderer = new THREE.WebGLRenderer({antialias: true});
        renderer.setClearColor("#e5e5e5"); //background color
        renderer.setSize(window.innerWidth,window.innerHeight); //size of renderer

        document.getElementById("WebGL-output").appendChild(renderer.domElement);

        raycaster = new THREE.Raycaster();
        mouse = new THREE.Vector2(1,1);

        var cubeGeometry = new THREE.BoxGeometry(20, 20, 20);
        var cubeMaterial = new THREE.MeshLambertMaterial({color: 0xffff00 }); //0xF7F7F7 = gray
        cube = new THREE.Mesh(cubeGeometry, cubeMaterial);
        cube.scale.y = 0.00001;
        cube.userData.originalColor = 0xffff00;

        cube.position.x = 0;
        cube.position.y = 3;
        cube.position.z = 0;

        scene.add(cube);

        var ambientLight = new THREE.AmbientLight(0x0c0c0c);
        scene.add(ambientLight);
        var spotLight = new THREE.SpotLight(0xffffff);
        spotLight.position.set(-40, 60, -10);
        spotLight.castShadow = true;
        scene.add(spotLight);

        camera.position.x = -30;
        camera.position.y = 40;
        camera.position.z = 30;
        camera.lookAt(scene.position);

        document.addEventListener('mousemove', onDocumentMouseMove, false);

        document.addEventListener('click', onDocumentMouseClick, false);
    }

    function onDocumentMouseMove(event)
    {

      event.preventDefault();
      mouse.x = (event.clientX / window.innerWidth) * 2 - 1;
      mouse.y = -(event.clientY / window.innerHeight) * 2 + 1;

        var intersects = raycaster.intersectObjects( scene.children );

        if ( intersects.length > 0 && intersects[ 0 ].object === cube && isClicked === false)
        {
            cube.material.color.set( 0xff0000 );
        }
        else if (isClicked === false)
        {
            cube.material.color.set( cube.userData.originalColor );
        }

    }

    function onDocumentMouseClick(event)
    {

        event.preventDefault();

        mouse.x = (event.clientX / window.innerWidth) * 2 - 1;
        mouse.y = -(event.clientY / window.innerHeight) * 2 + 1;

        var intersects = raycaster.intersectObjects( scene.children );

        if ( intersects.length > 0 && intersects[ 0 ].object === cube && isClicked === false)
        {
            isClicked = true;
            cube.material.color.set( 0xF7F7F7 );

            vis = gui.domElement.style.visibility;
            gui.domElement.style.visibility = vis == "" ? "hidden" : "";

        }
        else if ( intersects.length > 0 && intersects[ 0 ].object === cube && isClicked === true)
        {
            isClicked = false;
            cube.material.color.set( cube.userData.originalColor );

            vis = gui.domElement.style.visibility;
            gui.domElement.style.visibility = vis == "" ? "hidden" : "";
        }

    }

    function render()
    {

        raycaster.setFromCamera( mouse, camera );
        renderer.render(scene, camera);
    }

    function animate()
    {
        requestAnimationFrame( animate );
        render();
    }

<!DOCTYPE html>

<html>

<head>
    <title>Example 01.02 - First Scene</title>
    <script type="text/javascript" src="https://cdnjs.cloudflare.com/ajax/libs/three.js/110/three.min.js"></script>
    <script src="https://cdnjs.cloudflare.com/ajax/libs/dat-gui/0.7.6/dat.gui.min.js"></script>
    <style>
        body {
            margin: 0;
            overflow: hidden;
        }
    </style>
</head>
<body>

<!-- Div which will hold the Output -->
<div id="WebGL-output">
</div>

</body>
</html>


来源: stackexchange

问:
How to rotate a two-dimensional array to an arbitrary degree?
Say I have a bool[][], and I want to rotate it by 37 degrees. I am aware that the transformation wouldn't always be perfect, and that's okay. I've ready plenty of answers on here similar to my question, but the only solutions I've found only solve the problem for 90 degree increments. </p>

答:
Where x, y are your Cartesian coordinates and R is your rotation angle:</p>

```<code>newx = x * cos(R) - y * sin(R)
newy = x * sin(R) + y * cos(R)
</code>```

ContentLicense: CC BY-SA 3.0

Body:
Where x, y are your Cartesian coordinates and R is your rotation angle:

newx = x * cos(R) - y * sin(R)
newy = x * sin(R) + y * cos(R)


问:
Using face_wrap, how can I create a legend with both color and shape in ggplot2
I am using face_wrap to present my results in four different groups (graphs that correspond to the variable "Tipo"). Each group has its own shape, and within each group, I use different colors to represent different types of results (in this case, a different type of illness "Enfermedad"). Thus, I cannot assign "shape" and "color" to the same variable, and also merge both columns doesn't work for my case. So basically, I've managed to assign the four different shapes to each group and the 16 different colors, but what I haven't managed is to create a legend with both color and shape.
Thank you in advance!

The table I use looks like this:

```<code> Enfermedad               Casos     Año        Tipo
 Amebiasis intestinal      100      1998       Parasitaria
 Amebiasis intestinal      250      1999       Parasitaria
 Fiebre tifoidea           300      1998       Bacteriana
 Fiebre tifoidea           225      1999       Bacteriana
 Hepatitis vírica A         50      1998       Vírica
 Hepatitis vírica A         33      1999       Vírica
</code>```

Here is my code:

```<code>library(RColorBrewer)

EnfermGastro<- read_excel("...")

colourCount = length(unique(EnfermGastro$Enfermedad))
getPalette = colorRampPalette(brewer.pal(16, "Set1"))

ggplot(EnfermGastro, aes(x=Año,y=Casos,shape=Tipo, colour=Enfermedad)) +

geom_point(size=2.5) +

scale_shape_manual(values =c(16, 1, 18, 8)) +

scale_fill_manual(values= getPalette(colourCount)) +

scale_x_continuous( breaks=c(1998,1999,2000,2001,2002,2003,2004,2005,2006,2007,
                           2008,2009,2010,2011,2012,2013,2014,2015,2016,2017,2018)) +
scale_y_continuous(labels=comma) +

theme_bw() +
theme(axis.line=element_line(colour = "black"),
      panel.grid.major.y = element_line(colour="grey75", linetype="dotted"),
      panel.grid.major.x = element_line(colour="grey75", linetype="dotted"),
      panel.border=element_blank(),
      legend.background=element_rect(fill="grey80", colour="black"),
      legend.title = element_text(size= 10),
      legend.text = element_text(size= 8),
      legend.position="bottom") +

   facet_wrap(~Tipo, scale= "free")
</code>```

答:
Ok, here is a possible solution, not the best one because I only wanted to have 4 different shapes, one type of shape in each facet, but at least I managed to create a legend with both color and shape in ggplot2. So, what I did is to repeat the same 4 shapes across the 16 different illness. Thus, I assigned "shape" and "color" to the variable Enfermedad (illness) and use scale_shape_manual. Again, it is not really what I wanted so if anyone has a better solution I would very much welcome it!

```<code>ggplot(EnfermGastro, aes(x=Año,y=Casos, shape=Enfermedad, colour=Enfermedad)) +

geom_point(size=2.5) +

scale_shape_manual(values =rep.int(c(16, 1, 18, 8),times=4)) +

scale_fill_manual(values= getPalette(colourCount)) +

scale_x_continuous( breaks=c(1998,1999,2000,2001,2002,2003,2004,2005,2006,2007,
                        2008,2009,2010,2011,2012,2013,2014,2015,2016,2017,2018)) +
scale_y_continuous(labels=comma) +

theme_bw() +
theme(axis.line=element_line(colour = "black"),
       panel.grid.major.y = element_line(colour="grey75", linetype="dotted"),
       panel.grid.major.x = element_line(colour="grey75", linetype="dotted"),
       panel.border=element_blank(),
       legend.background=element_rect(fill="grey80", colour="black"),
       legend.title = element_text(size= 10),
       legend.text = element_text(size= 8),
       legend.position="bottom") +

  facet_wrap(~Tipo, scale= "free")
</code>```

ContentLicense: CC BY-SA 4.0

Body:
I am using face_wrap to present my results in four different groups (graphs that correspond to the variable "Tipo"). Each group has its own shape, and within each group, I use different colors to represent different types of results (in this case, a different type of illness "Enfermedad"). Thus, I cannot assign "shape" and "color" to the same variable, and also merge both columns doesn't work for my case. So basically, I've managed to assign the four different shapes to each group and the 16 different colors, but what I haven't managed is to create a legend with both color and shape.
Thank you in advance!

The table I use looks like this:

 Enfermedad               Casos     Año        Tipo
 Amebiasis intestinal      100      1998       Parasitaria
 Amebiasis intestinal      250      1999       Parasitaria
 Fiebre tifoidea           300      1998       Bacteriana
 Fiebre tifoidea           225      1999       Bacteriana
 Hepatitis vírica A         50      1998       Vírica
 Hepatitis vírica A         33      1999       Vírica

Here is my code:

library(RColorBrewer)

EnfermGastro<- read_excel("...")

colourCount = length(unique(EnfermGastro$Enfermedad))
getPalette = colorRampPalette(brewer.pal(16, "Set1"))

ggplot(EnfermGastro, aes(x=Año,y=Casos,shape=Tipo, colour=Enfermedad)) +

geom_point(size=2.5) +

scale_shape_manual(values =c(16, 1, 18, 8)) +

scale_fill_manual(values= getPalette(colourCount)) +

scale_x_continuous( breaks=c(1998,1999,2000,2001,2002,2003,2004,2005,2006,2007,
                           2008,2009,2010,2011,2012,2013,2014,2015,2016,2017,2018)) +
scale_y_continuous(labels=comma) +

theme_bw() +
theme(axis.line=element_line(colour = "black"),
      panel.grid.major.y = element_line(colour="grey75", linetype="dotted"),
      panel.grid.major.x = element_line(colour="grey75", linetype="dotted"),
      panel.border=element_blank(),
      legend.background=element_rect(fill="grey80", colour="black"),
      legend.title = element_text(size= 10),
      legend.text = element_text(size= 8),
      legend.position="bottom") +

   facet_wrap(~Tipo, scale= "free")

Body:
Ok, here is a possible solution, not the best one because I only wanted to have 4 different shapes, one type of shape in each facet, but at least I managed to create a legend with both color and shape in ggplot2. So, what I did is to repeat the same 4 shapes across the 16 different illness. Thus, I assigned "shape" and "color" to the variable Enfermedad (illness) and use scale_shape_manual. Again, it is not really what I wanted so if anyone has a better solution I would very much welcome it!

ggplot(EnfermGastro, aes(x=Año,y=Casos, shape=Enfermedad, colour=Enfermedad)) +

geom_point(size=2.5) +

scale_shape_manual(values =rep.int(c(16, 1, 18, 8),times=4)) +

scale_fill_manual(values= getPalette(colourCount)) +

scale_x_continuous( breaks=c(1998,1999,2000,2001,2002,2003,2004,2005,2006,2007,
                        2008,2009,2010,2011,2012,2013,2014,2015,2016,2017,2018)) +
scale_y_continuous(labels=comma) +

theme_bw() +
theme(axis.line=element_line(colour = "black"),
       panel.grid.major.y = element_line(colour="grey75", linetype="dotted"),
       panel.grid.major.x = element_line(colour="grey75", linetype="dotted"),
       panel.border=element_blank(),
       legend.background=element_rect(fill="grey80", colour="black"),
       legend.title = element_text(size= 10),
       legend.text = element_text(size= 8),
       legend.position="bottom") +

  facet_wrap(~Tipo, scale= "free")


问:
"dynamic" naming of column in function
I'd like to assign a dynamic name, i.e. the name of the variable I'm passing to the function, as a column name in the dataframe that is being created by the function.

I've tried

```<code>- deparse(substitute(x))
- toString(x)
</code>```

but no success...

Code

```<code>a <- (1:3)
b <- (5:7)

df <- data.frame(a,b)

fun <- function(x){
  x %>% mutate(c=a+b)
  colnames(x)[3] <- deparse(substitute(x))
  }
</code>```

Expected behaviour

after running fun(df):

```<code>  a b  df
1 1 5  6
2 2 6  8
3 3 7 10
</code>```

instead:

```<code>> fun(df)
Error in names(x) <- value :
  'names' attribute [3] must be the same length as the vector [2]
</code>```

答:
We can use := with evaluation (!!)

```<code>fun <- function(x){
    nm1 <-  deparse(substitute(x))
     x %>%
        mutate(!! nm1 := a+b)

   }

fun(df)
#  a b df
#1 1 5  6
#2 2 6  8
#3 3 7 10
</code>```

In the OP's function, the the output of x %>% mutate is not assigned back, therefore, the original dataset have only two columns and not three i.e. if we do

```<code>fun <- function(x){
   nm1 <- deparse(substitute(x))
    x <- x %>% # assign the output after mutate
            mutate(c=a+b)
   colnames(x)[3] <- nm1
   x # return the dataset
  }

fun(df)
#  a b df
#1 1 5  6
#2 2 6  8
#3 3 7 10
</code>```

Title: "dynamic" naming of column in function

Body:
I'd like to assign a dynamic name, i.e. the name of the variable I'm passing to the function, as a column name in the dataframe that is being created by the function.

I've tried

- deparse(substitute(x))
- toString(x)

but no success...

Code

a <- (1:3)
b <- (5:7)

df <- data.frame(a,b)

fun <- function(x){
  x %>% mutate(c=a+b)
  colnames(x)[3] <- deparse(substitute(x))
  }

Expected behaviour

after running fun(df):

  a b  df
1 1 5  6
2 2 6  8
3 3 7 10

instead:

> fun(df)
Error in names(x) <- value :
  'names' attribute [3] must be the same length as the vector [2]

Body:
We can use := with evaluation (!!)

fun <- function(x){
    nm1 <-  deparse(substitute(x))
     x %>%
        mutate(!! nm1 := a+b)

   }

fun(df)
#  a b df
#1 1 5  6
#2 2 6  8
#3 3 7 10

In the OP's function, the the output of x %>% mutate is not assigned back, therefore, the original dataset have only two columns and not three i.e. if we do

fun <- function(x){
   nm1 <- deparse(substitute(x))
    x <- x %>% # assign the output after mutate
            mutate(c=a+b)
   colnames(x)[3] <- nm1
   x # return the dataset
  }

fun(df)
#  a b df
#1 1 5  6
#2 2 6  8
#3 3 7 10


问:
R - for loop - using values in previous row
create a new column in R, using timepoints corresponding to a rating in another column.</p>

答:
Tidyverse solution: </p>

```<code>install.packages("dplyr", dependencies = TRUE)
library(dplyr)
dataframe.df %>%
  as.data.frame() %>%
  mutate(Timepoint = as.numeric(gsub("[a-zA-Z]+", "", Timepoint))) %>%
  group_by(Replicate, Stimulus, Subject) %>%
  mutate(start_end_time = ifelse(Timepoint != max(Timepoint), min(Timepoint), max(Timepoint))) %>%
  ungroup()
</code>```

Body:
Tidyverse solution:

install.packages("dplyr", dependencies = TRUE)
library(dplyr)
dataframe.df %>%
  as.data.frame() %>%
  mutate(Timepoint = as.numeric(gsub("[a-zA-Z]+", "", Timepoint))) %>%
  group_by(Replicate, Stimulus, Subject) %>%
  mutate(start_end_time = ifelse(Timepoint != max(Timepoint), min(Timepoint), max(Timepoint))) %>%
  ungroup()


问:
why does const return prevent: (a1 = a2) = a3?
I do not understand why adding const to the return type prevents (a1 = a2) = a3, as the comment at line 2 says.

Can someone explain it for me?

```<code>// overloaded assignment operator;
// const return prevents: (a1 = a2) = a3
const Array& Array::operator=(const Array& right) {
    if (&right != this) { // avoid self-assignment
       // for Arrays of different sizes, deallocate original
       // left-side Array, then allocate new left-side Array
        if (size != right.size) {
            delete[] ptr; // release space
            size = right.size; // resize this object
            ptr = new int[size]; // create space for Array copy
        }

        for (size_t i{ 0 }; i < size; ++i) {
            ptr[i] = right.ptr[i]; // copy array into object
        }
    }

    return *this; // enables x = y = z, for example
}
</code>```

答:
When evaluating the expression:

```<code>a1 = a2 = a3
</code>```

the grouping is from right to left, so the expression becomes:

```<code>a1 = (a2 = a3)
//   ^^^^^^^^^ const, but evaluated first, so ok.
</code>```

This is fine, since the parenthesized expression yields a const value which can be used as the argument to operator=.

However in the expression:

```<code>  (a1 = a2) = a3
//^^^^^^^^^ const, but evaluated first, so assigning to the result is not ok.
</code>```

the parenthesized expression again yields a const value, but now you are trying to assign to a const value, which is impossible.

Body:
I do not understand why adding const to the return type prevents (a1 = a2) = a3, as the comment at line 2 says.

Can someone explain it for me?

// overloaded assignment operator;
// const return prevents: (a1 = a2) = a3
const Array& Array::operator=(const Array& right) {
    if (&right != this) { // avoid self-assignment
       // for Arrays of different sizes, deallocate original
       // left-side Array, then allocate new left-side Array
        if (size != right.size) {
            delete[] ptr; // release space
            size = right.size; // resize this object
            ptr = new int[size]; // create space for Array copy
        }

        for (size_t i{ 0 }; i < size; ++i) {
            ptr[i] = right.ptr[i]; // copy array into object
        }
    }

    return *this; // enables x = y = z, for example
}

Body:
When evaluating the expression:

a1 = a2 = a3

the grouping is from right to left, so the expression becomes:

a1 = (a2 = a3)
//   ^^^^^^^^^ const, but evaluated first, so ok.

This is fine, since the parenthesized expression yields a const value which can be used as the argument to operator=.

However in the expression:

  (a1 = a2) = a3
//^^^^^^^^^ const, but evaluated first, so assigning to the result is not ok.

the parenthesized expression again yields a const value, but now you are trying to assign to a const value, which is impossible.


问:
Converting lines in to columns
I used this  script to generate the below output from server show /system1/swid*" |egrep -w "name|VersionString" | sed 's/^[ \t]*//;s/[ \t]*$//', but I am unable to convert these lines into columns. please help me to get some idea to convert this into columns.

```<code>name=iLO
VersionString=2.73 Feb 11 2020
name=System ROM
VersionString=P89 v2.76 (10/21/2019)
name=Redundant System ROM
VersionString=P89 v2.64 (10/17/2018)
name=Intelligent Provisioning
VersionString=2.70.75
</code>```

Required output

```<code>    name=iLO                            name=System ROM                             name=Redundant System ROM                   name=Intelligent Provisioning
VersionString=2.73 Feb 11 2020      VersionString=P89 v2.76 (10/21/2019)        VersionString=P89 v2.64 (10/17/2018)        VersionString=2.70.75
</code>```

image

答:
```<code>#!/bin/bash
# these are arrays
declare -a headers
declare -a values

# loop over versions.txt
while read line
do
    # add array elements
    if [ "${line:0:5}" == "name=" ]; then
        headers+=("${line}")
    else
        values+=("${line}")
    fi
done < versions.txt

# start lines
values_line="${values[0]}"
header_line="    ${headers[0]}"
# Loop over arrays
for (( ii=1; ii<${#headers[@]}; ii++ )); do
    # Determine number of spaces to add to header line
    spaces=$(( ${#values_line} - ${#header_line} ))
    # add spaces
    for (( jj=0; jj<${spaces}; jj++ )); do
        header_line="${header_line} "
    done
    # Append current values to lines
    header_line="${header_line}        ${headers[ii]}"
    values_line="${values_line}    ${values[ii]}"
done
# output lines
echo "${header_line}"
echo "${values_line}"
</code>```

Title: Converting lines in to columns

Body:
I used this  script to generate the below output from server show /system1/swid*" |egrep -w "name|VersionString" | sed 's/^[ \t]*//;s/[ \t]*$//', but I am unable to convert these lines into columns. please help me to get some idea to convert this into columns.

name=iLO
VersionString=2.73 Feb 11 2020
name=System ROM
VersionString=P89 v2.76 (10/21/2019)
name=Redundant System ROM
VersionString=P89 v2.64 (10/17/2018)
name=Intelligent Provisioning
VersionString=2.70.75

Required output

    name=iLO                            name=System ROM                             name=Redundant System ROM                   name=Intelligent Provisioning
VersionString=2.73 Feb 11 2020      VersionString=P89 v2.76 (10/21/2019)        VersionString=P89 v2.64 (10/17/2018)        VersionString=2.70.75

image


问:
Why Spark structured streaming job is not terminating even after raising exception
I am raising a custom exception to test failure in my structured streaming job as below. I see the query gets terminated but not able to understand why driver script is not failing with a non zero exit code

```<code>streamingDF.writeStream
        .trigger(Trigger.ProcessingTime(10000L))
        .foreachBatch {
          (batchDF: DataFrame, batchId: Long) => {
            val transformedDF: DataFrame = DoSomeProcessing(batchDF)
            if (batchId == 1) {
              throw new Exception("Custom Exception as batchId is 1")
            }
</code>```

I get below trace on my console but the driver script is not exiting and no new logs are printed on console.

```<code>Exception in thread "main" org.apache.spark.sql.streaming.StreamingQueryException: Custom Exception as batchId is 1
=== Streaming Query ===
Identifier: [id = 6f4c3b4c-bc30-46fe-93ef-8378c23380ab, runId = 1241cb37-493b-4882-ab28-9df8a8c6fb1a]
Current Committed Offsets: ...
Current Available Offsets: ...

Current State: ACTIVE
Thread State: RUNNABLE

Logical Plan:
RepartitionByExpression [timestamp#12], 10
...
    at org.apache.spark.sql.execution.streaming.StreamExecution.org$apache$spark$sql$execution$streaming$StreamExecution$$runStream(StreamExecution.scala:295)
    at org.apache.spark.sql.execution.streaming.StreamExecution$$anon$1.run(StreamExecution.scala:189)
Caused by: java.lang.Exception: Custom Exception as batchId is 1
    at MySteamingApp$$anonfun$startSparkStructuredStreaming$1.apply(MySteamingApp.scala:61)
    at MySteamingApp$$anonfun$startSparkStructuredStreaming$1.apply(MySteamingApp.scala:57)
    at org.apache.spark.sql.execution.streaming.sources.ForeachBatchSink.addBatch(ForeachBatchSink.scala:35)
    at org.apache.spark.sql.execution.streaming.MicroBatchExecution$$anonfun$org$apache$spark$sql$execution$streaming$MicroBatchExecution$$runBatch$5$$anonfun$apply$17.apply(MicroBatchExecution.scala:534)
    at org.apache.spark.sql.execution.SQLExecution$$anonfun$withNewExecutionId$1.apply(SQLExecution.scala:78)
    at org.apache.spark.sql.execution.SQLExecution$.withSQLConfPropagated(SQLExecution.scala:125)
    at org.apache.spark.sql.execution.SQLExecution$.withNewExecutionId(SQLExecution.scala:73)
    at org.apache.spark.sql.execution.streaming.MicroBatchExecution$$anonfun$org$apache$spark$sql$execution$streaming$MicroBatchExecution$$runBatch$5.apply(MicroBatchExecution.scala:532)
    at org.apache.spark.sql.execution.streaming.ProgressReporter$class.reportTimeTaken(ProgressReporter.scala:351)
    at org.apache.spark.sql.execution.streaming.StreamExecution.reportTimeTaken(StreamExecution.scala:58)
    at org.apache.spark.sql.execution.streaming.MicroBatchExecution.org$apache$spark$sql$execution$streaming$MicroBatchExecution$$runBatch(MicroBatchExecution.scala:531)
    at org.apache.spark.sql.execution.streaming.MicroBatchExecution$$anonfun$runActivatedStream$1$$anonfun$apply$mcZ$sp$1.apply$mcV$sp(MicroBatchExecution.scala:198)
    at org.apache.spark.sql.execution.streaming.MicroBatchExecution$$anonfun$runActivatedStream$1$$anonfun$apply$mcZ$sp$1.apply(MicroBatchExecution.scala:166)
    at org.apache.spark.sql.execution.streaming.MicroBatchExecution$$anonfun$runActivatedStream$1$$anonfun$apply$mcZ$sp$1.apply(MicroBatchExecution.scala:166)
    at org.apache.spark.sql.execution.streaming.ProgressReporter$class.reportTimeTaken(ProgressReporter.scala:351)
    at org.apache.spark.sql.execution.streaming.StreamExecution.reportTimeTaken(StreamExecution.scala:58)
    at org.apache.spark.sql.execution.streaming.MicroBatchExecution$$anonfun$runActivatedStream$1.apply$mcZ$sp(MicroBatchExecution.scala:166)
    at org.apache.spark.sql.execution.streaming.ProcessingTimeExecutor.execute(TriggerExecutor.scala:56)
    at org.apache.spark.sql.execution.streaming.MicroBatchExecution.runActivatedStream(MicroBatchExecution.scala:160)
    at org.apache.spark.sql.execution.streaming.StreamExecution.org$apache$spark$sql$execution$streaming$StreamExecution$$runStream(StreamExecution.scala:279)
    ... 1 more
</code>```

答:
I think number of task failures were configured more

spark.task.maxFailures     default 4   Number of failures of any particular task before giving up on the job. The total number of failures spread across different tasks will not cause the job to fail; a particular task has to fail this number of attempts. Should be greater than or equal to 1. Number of allowed retries = this value - 1.

Further have a look at Is there a way to dynamically stop Spark Structured Streaming?

Body:
I am raising a custom exception to test failure in my structured streaming job as below. I see the query gets terminated but not able to understand why driver script is not failing with a non zero exit code

streamingDF.writeStream
        .trigger(Trigger.ProcessingTime(10000L))
        .foreachBatch {
          (batchDF: DataFrame, batchId: Long) => {
            val transformedDF: DataFrame = DoSomeProcessing(batchDF)
            if (batchId == 1) {
              throw new Exception("Custom Exception as batchId is 1")
            }

I get below trace on my console but the driver script is not exiting and no new logs are printed on console.

Exception in thread "main" org.apache.spark.sql.streaming.StreamingQueryException: Custom Exception as batchId is 1
=== Streaming Query ===
Identifier: [id = 6f4c3b4c-bc30-46fe-93ef-8378c23380ab, runId = 1241cb37-493b-4882-ab28-9df8a8c6fb1a]
Current Committed Offsets: ...
Current Available Offsets: ...

Current State: ACTIVE
Thread State: RUNNABLE

Logical Plan:
RepartitionByExpression [timestamp#12], 10
...
    at org.apache.spark.sql.execution.streaming.StreamExecution.org$apache$spark$sql$execution$streaming$StreamExecution$$runStream(StreamExecution.scala:295)
    at org.apache.spark.sql.execution.streaming.StreamExecution$$anon$1.run(StreamExecution.scala:189)
Caused by: java.lang.Exception: Custom Exception as batchId is 1
    at MySteamingApp$$anonfun$startSparkStructuredStreaming$1.apply(MySteamingApp.scala:61)
    at MySteamingApp$$anonfun$startSparkStructuredStreaming$1.apply(MySteamingApp.scala:57)
    at org.apache.spark.sql.execution.streaming.sources.ForeachBatchSink.addBatch(ForeachBatchSink.scala:35)
    at org.apache.spark.sql.execution.streaming.MicroBatchExecution$$anonfun$org$apache$spark$sql$execution$streaming$MicroBatchExecution$$runBatch$5$$anonfun$apply$17.apply(MicroBatchExecution.scala:534)
    at org.apache.spark.sql.execution.SQLExecution$$anonfun$withNewExecutionId$1.apply(SQLExecution.scala:78)
    at org.apache.spark.sql.execution.SQLExecution$.withSQLConfPropagated(SQLExecution.scala:125)
    at org.apache.spark.sql.execution.SQLExecution$.withNewExecutionId(SQLExecution.scala:73)
    at org.apache.spark.sql.execution.streaming.MicroBatchExecution$$anonfun$org$apache$spark$sql$execution$streaming$MicroBatchExecution$$runBatch$5.apply(MicroBatchExecution.scala:532)
    at org.apache.spark.sql.execution.streaming.ProgressReporter$class.reportTimeTaken(ProgressReporter.scala:351)
    at org.apache.spark.sql.execution.streaming.StreamExecution.reportTimeTaken(StreamExecution.scala:58)
    at org.apache.spark.sql.execution.streaming.MicroBatchExecution.org$apache$spark$sql$execution$streaming$MicroBatchExecution$$runBatch(MicroBatchExecution.scala:531)
    at org.apache.spark.sql.execution.streaming.MicroBatchExecution$$anonfun$runActivatedStream$1$$anonfun$apply$mcZ$sp$1.apply$mcV$sp(MicroBatchExecution.scala:198)
    at org.apache.spark.sql.execution.streaming.MicroBatchExecution$$anonfun$runActivatedStream$1$$anonfun$apply$mcZ$sp$1.apply(MicroBatchExecution.scala:166)
    at org.apache.spark.sql.execution.streaming.MicroBatchExecution$$anonfun$runActivatedStream$1$$anonfun$apply$mcZ$sp$1.apply(MicroBatchExecution.scala:166)
    at org.apache.spark.sql.execution.streaming.ProgressReporter$class.reportTimeTaken(ProgressReporter.scala:351)
    at org.apache.spark.sql.execution.streaming.StreamExecution.reportTimeTaken(StreamExecution.scala:58)
    at org.apache.spark.sql.execution.streaming.MicroBatchExecution$$anonfun$runActivatedStream$1.apply$mcZ$sp(MicroBatchExecution.scala:166)
    at org.apache.spark.sql.execution.streaming.ProcessingTimeExecutor.execute(TriggerExecutor.scala:56)
    at org.apache.spark.sql.execution.streaming.MicroBatchExecution.runActivatedStream(MicroBatchExecution.scala:160)
    at org.apache.spark.sql.execution.streaming.StreamExecution.org$apache$spark$sql$execution$streaming$StreamExecution$$runStream(StreamExecution.scala:279)
    ... 1 more


问:
Plotting a scatter data with error bars in x and y direction and adding a trend line
I have  a bunch of scattered data that I would like to plot and add a best fit line (y=ax+b) and represent the equation with the associated error (maybe R), and showing 95 % confidence level curves. Moreover, each point (x,y) has a name that should appear in the legend preferably each point should have different shape. Could anyone please help me out with this? </p>

```<code>x=np.array([100,65,20,85])
xerr=np.array([5,3,2,5])
y=np.array([1,0.75,1.25,2])
yerr=np.array([0.1,0.03,0.01,0])
</code>```

答:
Answering my question I know this much of the code but I want to add the 95% confidence boundaries as well as the error associated with trend line equation in the same graph!</p>

```<code>x=np.array([100,65,20,85])
xerr=np.array([5,3,2,5])
y=np.array([1,0.75,1.25,2])
yerr=np.array([0.1,0.03,0.01,0])

fig, ax = plt.subplots()

ax.errorbar(x, y,
            xerr=xerr,
            yerr=yerr,
            fmt='o')

ax.set_xlabel('X axis')
ax.set_ylabel('Y axis')
ax.set_title('Test Code')

z = np.polyfit(x.flatten(), y.flatten(), 1)
p = np.poly1d(z)
plt.plot(x,p(x),"r--")
plt.title("y=%.6fx+%.6f"%(z[0],z[1]))

plt.show()
</code>```

Body:
I have  a bunch of scattered data that I would like to plot and add a best fit line (y=ax+b) and represent the equation with the associated error (maybe R), and showing 95 % confidence level curves. Moreover, each point (x,y) has a name that should appear in the legend preferably each point should have different shape. Could anyone please help me out with this?

x=np.array([100,65,20,85])
xerr=np.array([5,3,2,5])
y=np.array([1,0.75,1.25,2])
yerr=np.array([0.1,0.03,0.01,0])

Body:
Answering my question I know this much of the code but I want to add the 95% confidence boundaries as well as the error associated with trend line equation in the same graph!

x=np.array([100,65,20,85])
xerr=np.array([5,3,2,5])
y=np.array([1,0.75,1.25,2])
yerr=np.array([0.1,0.03,0.01,0])

fig, ax = plt.subplots()

ax.errorbar(x, y,
            xerr=xerr,
            yerr=yerr,
            fmt='o')

ax.set_xlabel('X axis')
ax.set_ylabel('Y axis')
ax.set_title('Test Code')

z = np.polyfit(x.flatten(), y.flatten(), 1)
p = np.poly1d(z)
plt.plot(x,p(x),"r--")
plt.title("y=%.6fx+%.6f"%(z[0],z[1]))

plt.show()


问:
Forget Platform and Tweak the Performance of "a Web Server"
Unusual interview question I got.

Being completely agnostic about the platform, what are some things you can do to detect performance bottlenecks?

I mentioned examining CPU and memory to narrow it down to a problematic process, but got the hunch a better answer was expected.

答:
Since no one else has thoughts, a really decent collection of tips here:

http://developer.yahoo.com/performance/rules.html


问:
Property init in C#
I am used in many cases to write a properties like

```<code>public string Data {get; private set; }
</code>```

And usual I initialize them in the constructor
How can I give the Data some value ,not explicitly using constructor

答:
C# 9.0 will provide new init accessor for this particular problem:

```<code>public class DataClass
{
    public string Data {get; init; }
}
</code>```

Now you can use object initializer for your DataClass instead of constructor:

```<code>var d = new DataClass { Data = "newValue" };
</code>```

More details here.

Title: Property init in C#

Body:
I am used in many cases to write a properties like

public string Data {get; private set; }

And usual I initialize them in the constructor
How can I give the Data some value ,not explicitly using constructor

Body:
C# 9.0 will provide new init accessor for this particular problem:

public class DataClass
{
    public string Data {get; init; }
}

Now you can use object initializer for your DataClass instead of constructor:

var d = new DataClass { Data = "newValue" };

More details here.


问:
Difference in Dates Based on Value of Separate Variable
I have a dataframe that looks like this:

```<code>        Date Value Value_Increase
1 2020-05-01     5          FALSE
2 2020-05-02     4          FALSE
3 2020-05-03    10           TRUE
4 2020-05-04     9          FALSE
5 2020-05-05     7          FALSE
6 2020-05-06    12           TRUE
7 2020-05-07     8          FALSE
</code>```

I want to create a new column that provides the numbers of days since the "Value" column increased.

The results would look like the dataframe below.

```<code>        Date Value Value_Increase Days_Since_Value_Increase
1 2020-05-01     5          FALSE                        NA
2 2020-05-02     4          FALSE                        NA
3 2020-05-03    10           TRUE                        NA
4 2020-05-04     9          FALSE                         1
5 2020-05-05     7          FALSE                         2
6 2020-05-06    12           TRUE                         3
7 2020-05-07     8          FALSE                         1
</code>```

Thanks for any help or suggestion, especially those that might use dplyr approach.

Code to create working example:

```<code>Date <- as.Date(c("2020-05-01", "2020-05-02", "2020-05-03", "2020-05-04", "2020-05-05", "2020-05-06", "2020-05-07"))
Value <- c(5, 4, 10, 9, 7, 12, 8)
Value_Increase <- c(FALSE, FALSE, TRUE, FALSE, FALSE, TRUE, FALSE)
df <- data.frame(Date, Value, Value_Increase, Days_Since_Value_Increase)
</code>```

答:
If you want to make it robust to missing days</p>

```<code>df %>%
  group_by(g = cumsum(lag(Value_Increase, default = 0))) %>%
  mutate(Days_Since_Value_Increase = ifelse(g == 0, NA, Date - min(Date) + 1))`

# A tibble: 7 x 4
# Groups:   g [3]
  Date       Value     g Days_Since_Value_Increase
  <date>     <dbl> <dbl>                     <dbl>
1 2020-05-01     5     0                        NA
2 2020-05-02     4     0                        NA
3 2020-05-03    10     0                        NA
4 2020-05-04     9     1                         1
5 2020-05-05     7     1                         2
6 2020-05-06    12     1                         3
7 2020-05-07     8     2                         1
</code>```

Body:
I have a dataframe that looks like this:

        Date Value Value_Increase
1 2020-05-01     5          FALSE
2 2020-05-02     4          FALSE
3 2020-05-03    10           TRUE
4 2020-05-04     9          FALSE
5 2020-05-05     7          FALSE
6 2020-05-06    12           TRUE
7 2020-05-07     8          FALSE

I want to create a new column that provides the numbers of days since the "Value" column increased.

The results would look like the dataframe below.

        Date Value Value_Increase Days_Since_Value_Increase
1 2020-05-01     5          FALSE                        NA
2 2020-05-02     4          FALSE                        NA
3 2020-05-03    10           TRUE                        NA
4 2020-05-04     9          FALSE                         1
5 2020-05-05     7          FALSE                         2
6 2020-05-06    12           TRUE                         3
7 2020-05-07     8          FALSE                         1

Thanks for any help or suggestion, especially those that might use dplyr approach.

Code to create working example:

Date <- as.Date(c("2020-05-01", "2020-05-02", "2020-05-03", "2020-05-04", "2020-05-05", "2020-05-06", "2020-05-07"))
Value <- c(5, 4, 10, 9, 7, 12, 8)
Value_Increase <- c(FALSE, FALSE, TRUE, FALSE, FALSE, TRUE, FALSE)
df <- data.frame(Date, Value, Value_Increase, Days_Since_Value_Increase)

Body:
If you want to make it robust to missing days

df %>%
  group_by(g = cumsum(lag(Value_Increase, default = 0))) %>%
  mutate(Days_Since_Value_Increase = ifelse(g == 0, NA, Date - min(Date) + 1))`

# A tibble: 7 x 4
# Groups:   g [3]
  Date       Value     g Days_Since_Value_Increase
  <date>     <dbl> <dbl>                     <dbl>
1 2020-05-01     5     0                        NA
2 2020-05-02     4     0                        NA
3 2020-05-03    10     0                        NA
4 2020-05-04     9     1                         1
5 2020-05-05     7     1                         2
6 2020-05-06    12     1                         3
7 2020-05-07     8     2                         1


问:
Local Dynamodb Console
As the title speaks, is there a way to visualize data in local dynamodb like how it is on AWS Console? This seems to be one of the drawback to me because using localhost:8000/shell (default endpoint) and doing scans requiring the setup of the attributes and etc.</p>

答:
Dynobase is good (however it is not free - at least not forever...).

DynamoDB Admin is very simple, but its better than nothing.

e.g. simple docker-compose line:

```<code>   dynamo-admin:
    image: instructure/dynamo-local-admin
    ports:
      - "8001:8001"
      - "8042:8042"
    environment:
      DYNAMO_ENDPOINT: http://dynamodb:8000
</code>```

Title: Local Dynamodb Console

Body:
Dynobase is good (however it is not free - at least not forever...).

DynamoDB Admin is very simple, but its better than nothing.

e.g. simple docker-compose line:

   dynamo-admin:
    image: instructure/dynamo-local-admin
    ports:
      - "8001:8001"
      - "8042:8042"
    environment:
      DYNAMO_ENDPOINT: http://dynamodb:8000


问:
Using 'as' prop for Link element in Next.js leads to 404 and refresh
So I'm following along a tutorial and it's a very short video on the 'as' prop in next js. Seems simple. Add an 'as' prop and your Link element will route to the href in the link but will have the 'as' prop contents in the browser bar.

My code worked just fine before, but when I added 'as' for the link below, I got a 404. Browser console output showed that an attempt at a GET request was made... for the link in the 'as' prop.

Why is that? Isn't that the opposite of what it's meant to do? Why is my code trying to GET the contents of the 'as' prop instead of the 'href' prop?

For what it's worth, the instructor is using getInitialProps and I'm using getServerSide props (for both the index shown below and the post that it leads to). But I don't see why that would cause a GET to the 'as' prop, and also cause a refresh.

In the course it's highlighted that this will cause a 404 for a refresh, but it should work just fine if used without refreshing.

```<code>import React, { Component } from 'react';
import axios from 'axios';
import Link from 'next/link';

const Index = ({ posts }) => {
  return (
    <div>
      <h1>Our index page!!!</h1>
      {posts.map(post => (
        <li key={post.id}>
          <Link href={`/post?id=${post.id}`} as={`/p/${post.id}`}>
            <a>{post.title}</a>
          </Link>
        </li>
      ))}
    </div>
  );
};

export async function getServerSideProps(context) {
  const res = await axios.get('https://jsonplaceholder.typicode.com/posts');
  const {data} = res;
  return {
    props: { posts: data }, // will be passed to the page component as props
  }
}

export default Index;
</code>```

Here is the code for the component it renders:

```<code>import { withRouter } from 'next/router';
import axios from 'axios';

const Post = ({ id, comments }) => {
  return (
    <div>
      <h1>Comments for Post #{id}</h1>
      {comments.map(comment => (
        <Comment key={comment.id} {...comment}/>
      ))}
    </div>
  );
};

const Comment = ({ email, body }) => (
  <div>
    <h5>{email}</h5>
    <p>{body}</p>
  </div>
);

export async function getServerSideProps(context) {
  const { query } = context;
  const res = await axios.get(`https://jsonplaceholder.typicode.com/comments?postId=${query.id}`);
  return {
    props: { ...query, comments: res.data }, // will be passed to the page component as props
  }
}

export default withRouter(Post);
</code>```

Thank you.

Output:

Console output shows a GET request to the link specified in the 'as' prop! Why!?

答:
It's actually the other way around. The href prop should be the system path of the page component you're linking to. It's not a dynamic value that changes at runtime.

And the as prop is the path that the browser requests (as shown in the URL bar).

This is the correct usage:

```<code><Link href={`/post/[pid]`} as={`/post?id=${post.id}`}>
  <a>{post.title}</a>
</Link>
</code>```

This assumes your page component is stored at /pages/post/[pid]. If you've stored the Post component at /pages/Post.js, move it to /pages/post/[pid].

Update based on your new comment:

If you instead want the page URLs to be /p/1, /p/2 etc. you can do the following:

Create a Page component at pages/p/[pid].js. Include getServerSideProps:

```<code>export async function getServerSideProps(context) {
  const { params } = context;
  const res = await axios.get(`https://jsonplaceholder.typicode.com/comments?postId=${params.pid}`);
  return {
    props: { id: params.pid, comments: res.data }, // Will be passed to the page component as props
  }
}
</code>```

In your Index component, use the Link component like this (assuming you haven't made any other changes to the component):

      {posts.map(post => (

          <Link href="/p/[pid]" as={`/p/${post.id}`}>
            {post.title}
          </Link>

      ))}
```

Next.js uses a file-based router, and the links have to match the component path. You can't put whatever you want in the as prop.

Body:
So I'm following along a tutorial and it's a very short video on the 'as' prop in next js. Seems simple. Add an 'as' prop and your Link element will route to the href in the link but will have the 'as' prop contents in the browser bar.

My code worked just fine before, but when I added 'as' for the link below, I got a 404. Browser console output showed that an attempt at a GET request was made... for the link in the 'as' prop.

Why is that? Isn't that the opposite of what it's meant to do? Why is my code trying to GET the contents of the 'as' prop instead of the 'href' prop?

For what it's worth, the instructor is using getInitialProps and I'm using getServerSide props (for both the index shown below and the post that it leads to). But I don't see why that would cause a GET to the 'as' prop, and also cause a refresh.

In the course it's highlighted that this will cause a 404 for a refresh, but it should work just fine if used without refreshing.

import React, { Component } from 'react';
import axios from 'axios';
import Link from 'next/link';

const Index = ({ posts }) => {
  return (

Our index page!!!

      {posts.map(post => (

          <Link href={`/post?id=${post.id}`} as={`/p/${post.id}`}>
            {post.title}
          </Link>

      ))}

  );
};

export async function getServerSideProps(context) {
  const res = await axios.get('https://jsonplaceholder.typicode.com/posts');
  const {data} = res;
  return {
    props: { posts: data }, // will be passed to the page component as props
  }
}

export default Index;

Here is the code for the component it renders:

import { withRouter } from 'next/router';
import axios from 'axios';

const Post = ({ id, comments }) => {
  return (

Comments for Post #{id}

      {comments.map(comment => (
        <Comment key={comment.id} {...comment}/>
      ))}

  );
};

const Comment = ({ email, body }) => (

{email}

{body}

);

export async function getServerSideProps(context) {
  const { query } = context;
  const res = await axios.get(`https://jsonplaceholder.typicode.com/comments?postId=${query.id}`);
  return {
    props: { ...query, comments: res.data }, // will be passed to the page component as props
  }
}

export default withRouter(Post);

Thank you.

Output:

Console output shows a GET request to the link specified in the 'as' prop! Why!?

Body:
It's actually the other way around. The href prop should be the system path of the page component you're linking to. It's not a dynamic value that changes at runtime.

And the as prop is the path that the browser requests (as shown in the URL bar).

This is the correct usage:

<Link href={`/post/[pid]`} as={`/post?id=${post.id}`}>
  <a>{post.title}</a>
</Link>

This assumes your page component is stored at /pages/post/[pid]. If you've stored the Post component at /pages/Post.js, move it to /pages/post/[pid].

Update based on your new comment:

If you instead want the page URLs to be /p/1, /p/2 etc. you can do the following:

Create a Page component at pages/p/[pid].js. Include getServerSideProps:

export async function getServerSideProps(context) {
  const { params } = context;
  const res = await axios.get(`https://jsonplaceholder.typicode.com/comments?postId=${params.pid}`);
  return {
    props: { id: params.pid, comments: res.data }, // Will be passed to the page component as props
  }
}

In your Index component, use the Link component like this (assuming you haven't made any other changes to the component):

      {posts.map(post => (
        <li key={post.id}>
          <Link href="/p/[pid]" as={`/p/${post.id}`}>
            <a>{post.title}</a>
          </Link>
        </li>
      ))}

Next.js uses a file-based router, and the links have to match the component path. You can't put whatever you want in the as prop.


问:
How can I hide the app name in androidstudio?
i need help how can hide app name without delete name in

string name="app_name"

like this . Thanks for the straightforward answer .

答:
As mentioned previously by another user, you can do it programatically:

```<code>import android.app.Activity;
import android.os.Bundle;
import android.view.Window;
import android.view.WindowManager;

public class ActivityName extends Activity {
    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        // remove title
        requestWindowFeature(Window.FEATURE_NO_TITLE);
        getWindow().setFlags(WindowManager.LayoutParams.FLAG_FULLSCREEN,
            WindowManager.LayoutParams.FLAG_FULLSCREEN);
        setContentView(R.layout.main);
    }
}
</code>```

Or you can do it via your AndroidManifest.xml file:

```<code><activity android:name=".ActivityName"
    android:label="@string/app_name"
    android:theme="@android:style/Theme.Black.NoTitleBar.Fullscreen">
</activity>
</code>```

Body:
As mentioned previously by another user, you can do it programatically:

import android.app.Activity;
import android.os.Bundle;
import android.view.Window;
import android.view.WindowManager;

public class ActivityName extends Activity {
    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        // remove title
        requestWindowFeature(Window.FEATURE_NO_TITLE);
        getWindow().setFlags(WindowManager.LayoutParams.FLAG_FULLSCREEN,
            WindowManager.LayoutParams.FLAG_FULLSCREEN);
        setContentView(R.layout.main);
    }
}

Or you can do it via your AndroidManifest.xml file:

<activity android:name=".ActivityName"
    android:label="@string/app_name"
    android:theme="@android:style/Theme.Black.NoTitleBar.Fullscreen">
</activity>


问:
Fabric UI Detailslist Additional Columns[React SPFx]
I'm building a SPFx Webpart with the Fabric/Fluent UI DetailsList component and I'm trying to add dynamic columns based on security groups selected from a picker (this is likely to change but will remain an array). I've found some code that does just this and have adopted it to my project but the gulp serve fails to mount the webpart in the workbench.

```<code>  private _columns: IColumn[] = [
    {
      key: 'filepath',
      name: 'File path',
      onRender: item => (
        // tslint:disable-next-line:jsx-no-lxambda
        <Link key={item} onClick={() => this._navigate(item)}>
          {item}
        </Link>
      ),
    } as IColumn,
  ];

  private _addcolumns(_columns:IColumn[]): IColumn[] {
    for (let user of this.props.people) {
      _columns.push({
          key: 'permissionset',
          name: 'Permission',
          onRender: item => (<DropPermissionItem/>)
        } as IColumn,
      )
    }
    return _columns
  };

...

      <DetailsList
        key={this.state.key}
        items={this.state.items}
        columns={this._addcolumns(this._columns)}
        onItemInvoked={this._navigate}
        initialFocusedIndex={this.state.initialFocusedIndex}
        ariaLabelForSelectionColumn="Toggle selection"
        ariaLabelForSelectAllCheckbox="Toggle selection for all items"
        checkButtonAriaLabel="Row checkbox"
      />
</code>```

The DetailsList uses the _addColumns and passes in the _columns to append the additional columns. Is there something I'm missing or is there a better way?

答:
I've been able to dynamically set the number of columns.

```<code>  private _columns: IColumn[] = [
    {
      key: 'file',
      name: "File",
      minWidth: 60,
      onRender: item => (
        // tslint:disable-next-line:jsx-no-lxambda
        <Link key={item} onClick={() => this._navigate(item)}>
          {item}
        </Link>
      )
    },
    {
      key: 'permission',
      name: "permission",
      minWidth: 60,
      onRender: item => (<DropPermissionItem/>),
    }
  ];

  private _addcolumns(column: IColumn[]): IColumn[] {
    let _loadColumn = this._loadUser();
    if (_loadColumn == null){
        return column;
      } else
      {
        for (let col of _loadColumn) {
          column.push({
              key: 'permission',
              name: 'Permission',
              minWidth: 60,
              onRender: item => (<DropPermissionItem/>),
            }
          );
        }
        return column;
      }
  }

  private displayColumns: IColumn[] = this._addcolumns(this._columns);
</code>```

Use the this.displayColumns inside the column property of the detail list.

Body:
I'm building a SPFx Webpart with the Fabric/Fluent UI DetailsList component and I'm trying to add dynamic columns based on security groups selected from a picker (this is likely to change but will remain an array). I've found some code that does just this and have adopted it to my project but the gulp serve fails to mount the webpart in the workbench.

  private _columns: IColumn[] = [
    {
      key: 'filepath',
      name: 'File path',
      onRender: item => (
        // tslint:disable-next-line:jsx-no-lxambda
        <Link key={item} onClick={() => this._navigate(item)}>
          {item}
        </Link>
      ),
    } as IColumn,
  ];

  private _addcolumns(_columns:IColumn[]): IColumn[] {
    for (let user of this.props.people) {
      _columns.push({
          key: 'permissionset',
          name: 'Permission',
          onRender: item => (<DropPermissionItem/>)
        } as IColumn,
      )
    }
    return _columns
  };

...

      <DetailsList
        key={this.state.key}
        items={this.state.items}
        columns={this._addcolumns(this._columns)}
        onItemInvoked={this._navigate}
        initialFocusedIndex={this.state.initialFocusedIndex}
        ariaLabelForSelectionColumn="Toggle selection"
        ariaLabelForSelectAllCheckbox="Toggle selection for all items"
        checkButtonAriaLabel="Row checkbox"
      />

The DetailsList uses the _addColumns and passes in the _columns to append the additional columns. Is there something I'm missing or is there a better way?

Body:
I've been able to dynamically set the number of columns.

  private _columns: IColumn[] = [
    {
      key: 'file',
      name: "File",
      minWidth: 60,
      onRender: item => (
        // tslint:disable-next-line:jsx-no-lxambda
        <Link key={item} onClick={() => this._navigate(item)}>
          {item}
        </Link>
      )
    },
    {
      key: 'permission',
      name: "permission",
      minWidth: 60,
      onRender: item => (<DropPermissionItem/>),
    }
  ];

  private _addcolumns(column: IColumn[]): IColumn[] {
    let _loadColumn = this._loadUser();
    if (_loadColumn == null){
        return column;
      } else
      {
        for (let col of _loadColumn) {
          column.push({
              key: 'permission',
              name: 'Permission',
              minWidth: 60,
              onRender: item => (<DropPermissionItem/>),
            }
          );
        }
        return column;
      }
  }

  private displayColumns: IColumn[] = this._addcolumns(this._columns);

Use the this.displayColumns inside the column property of the detail list.


问:
How to sort pandas dataframe in a special way
Given a pandas dataframe

```<code>df = pd.DataFrame({'a': [1,2,3,4,5,6,7,8],
                   'b': [0,0,1,1,2,2,3,3]})
</code>```

How to sort it along the column b in such a way that it is rearranged as {0,1,2,3,0,1,2,3}.

I.e. the resulting dataframe is

```<code>1   0
3   1
5   2
7   3
2   0
4   1
6   2
8   3
</code>```

答:
This is simplistic and specific to your question, and builds off of the knowledge that column b is already sorted :</p>
```<code>res = df.to_numpy()

pd.DataFrame(np.vstack((res[::2],res[1::2])),columns=df.columns)

#similar
pd.concat((df.iloc[::2], df.iloc[1::2]))

    a   b
0   1   0
1   3   1
2   5   2
3   7   3
4   2   0
5   4   1
6   6   2
7   8   3
</code>```

Body:
Given a pandas dataframe

df = pd.DataFrame({'a': [1,2,3,4,5,6,7,8],
                   'b': [0,0,1,1,2,2,3,3]})

How to sort it along the column b in such a way that it is rearranged as {0,1,2,3,0,1,2,3}.

I.e. the resulting dataframe is

1   0
3   1
5   2
7   3
2   0
4   1
6   2
8   3

Body:
This is simplistic and specific to your question, and builds off of the knowledge that column b is already sorted :

res = df.to_numpy()

pd.DataFrame(np.vstack((res[::2],res[1::2])),columns=df.columns)

#similar
pd.concat((df.iloc[::2], df.iloc[1::2]))

    a   b
0   1   0
1   3   1
2   5   2
3   7   3
4   2   0
5   4   1
6   6   2
7   8   3


问:
Javascript - export image into excel
Using this function, I can export image into excel(XLS). This code require physical location of the image. But instead of physical path, I want to pass dataUri of the image. e.g. data:image/jpeg;base64,/9j/4AAQSkZJRgABAQAAAQABAA...

Is it possible?

function exportExcel() {

    var template = { excel: '<meta name=ProgId content=Excel.Sheet> <meta name=Generator content="Microsoft Excel 11"><meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
{table}
' };

    var format = function (s, c) {
        return s.replace(new RegExp("{(\\w+)}", "g"), function (m, p) {
            return c[p];
        });
    };

    var base64 = function (s) {
        return window.btoa(window.unescape(encodeURIComponent(s)));
    };

    var ctx = { worksheet: 'Worksheet', table: '' };

    var b64 = base64(format(template.excel, ctx));

    blob = b64toBlob(b64, 'application/vnd.ms-excel');
    var blobUrl = window.URL.createObjectURL(blob);

    var saveLink = document.createElement('a');

    saveLink.download = 'export.xls';
    saveLink.href = blobUrl;
    saveLink.click();
}

function b64toBlob(b64Data, contentType, sliceSize) {
    contentType = contentType || '';
    sliceSize = sliceSize || 512;

    var byteCharacters = window.atob(b64Data);
    var byteArrays = [];

    var offset;
    for (offset = 0; offset < byteCharacters.length; offset += sliceSize) {
        var slice = byteCharacters.slice(offset, offset + sliceSize);

        var byteNumbers = new Array(slice.length);
        var i;
        for (i = 0; i < slice.length; i = i + 1) {
            byteNumbers[i] = slice.charCodeAt(i);
        }

        var byteArray = new window.Uint8Array(byteNumbers);

        byteArrays.push(byteArray);
    }

    var blob = new window.Blob(byteArrays, {
        type: contentType
    });
    return blob;
}```

Attached screenshot of requirement.
enter image description here
Thanks!

答:
I ran into the same problem, after several hours researching I solved it this way.

```<code>// Code HTML
 <div id="chart-container" style="background: #fff;">
                            <canvas class="mt-5 w-100" id="doughnutChart"></canvas>
 </div>
// Code javascript
// Convert the div to image (canvas)
html2canvas(document.getElementById("chart-container"), {
    onrendered: function (canvas) {
        var img = canvas.toDataURL("image/jpeg", 0.9); //image data of canvas

        var a = document.createElement("a"); //Create <a>
        //a.href = "data:image/png;base64," + ImageBase64;
        a.href = img;
        a.download = fileName + ".jpeg"; //File name Here

        var uri = 'data:application/vnd.ms-excel;base64,'
            , template = '<html xmlns:o="urn:schemas-microsoft-com:office:office" xmlns:x="urn:schemas-microsoft-com:office:excel" xmlns="http://www.w3.org/TR/REC-html40"><head><!--[if gte mso 9]><xml><x:ExcelWorkbook><x:ExcelWorksheets><x:ExcelWorksheet><x:Name>{worksheet}</x:Name><x:WorksheetOptions><x:DisplayGridlines/></x:WorksheetOptions></x:ExcelWorksheet></x:ExcelWorksheets></x:ExcelWorkbook></xml><![endif]--></head><body><img src="{table}" alt="grafica" /></body></html>'
            , base64 = function (s) { return window.btoa(unescape(encodeURIComponent(s))) }
            , format = function (s, c) { return s.replace(/{(\w+)}/g, function (m, p) { return c[p]; }) }

        var ctx = { worksheet: name || 'Hoja1', table: fileName + ".jpeg" }
        //window.location.href = uri + base64(format(template, ctx))
        var link = document.createElement("a");
        link.download = fileName+".xls";
        link.href = uri + base64(format(template, ctx));
        link.click();
    }
});
</code>```

Result:
enter image description here

Title: Javascript - export image into excel

Body:
Using this function, I can export image into excel(XLS). This code require physical location of the image. But instead of physical path, I want to pass dataUri of the image. e.g. data:image/jpeg;base64,/9j/4AAQSkZJRgABAQAAAQABAA...

Is it possible?

function exportExcel() {

    var template = { excel: '<meta name=ProgId content=Excel.Sheet> <meta name=Generator content="Microsoft Excel 11"><meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
{table}
' };

    var format = function (s, c) {
        return s.replace(new RegExp("{(\\w+)}", "g"), function (m, p) {
            return c[p];
        });
    };

    var base64 = function (s) {
        return window.btoa(window.unescape(encodeURIComponent(s)));
    };

    var ctx = { worksheet: 'Worksheet', table: '' };

    var b64 = base64(format(template.excel, ctx));

    blob = b64toBlob(b64, 'application/vnd.ms-excel');
    var blobUrl = window.URL.createObjectURL(blob);

    var saveLink = document.createElement('a');

    saveLink.download = 'export.xls';
    saveLink.href = blobUrl;
    saveLink.click();
}

function b64toBlob(b64Data, contentType, sliceSize) {
    contentType = contentType || '';
    sliceSize = sliceSize || 512;

    var byteCharacters = window.atob(b64Data);
    var byteArrays = [];

    var offset;
    for (offset = 0; offset < byteCharacters.length; offset += sliceSize) {
        var slice = byteCharacters.slice(offset, offset + sliceSize);

        var byteNumbers = new Array(slice.length);
        var i;
        for (i = 0; i < slice.length; i = i + 1) {
            byteNumbers[i] = slice.charCodeAt(i);
        }

        var byteArray = new window.Uint8Array(byteNumbers);

        byteArrays.push(byteArray);
    }

    var blob = new window.Blob(byteArrays, {
        type: contentType
    });
    return blob;
}

Attached screenshot of requirement.
enter image description here
Thanks!

Body:
I ran into the same problem, after several hours researching I solved it this way.

// Code HTML
 <div id="chart-container" style="background: #fff;">
                            <canvas class="mt-5 w-100" id="doughnutChart"></canvas>
 </div>
// Code javascript
// Convert the div to image (canvas)
html2canvas(document.getElementById("chart-container"), {
    onrendered: function (canvas) {
        var img = canvas.toDataURL("image/jpeg", 0.9); //image data of canvas

        var a = document.createElement("a"); //Create <a>
        //a.href = "data:image/png;base64," + ImageBase64;
        a.href = img;
        a.download = fileName + ".jpeg"; //File name Here

        var uri = 'data:application/vnd.ms-excel;base64,'
            , template = '<html xmlns:o="urn:schemas-microsoft-com:office:office" xmlns:x="urn:schemas-microsoft-com:office:excel" xmlns="http://www.w3.org/TR/REC-html40"><head><!--[if gte mso 9]><xml><x:ExcelWorkbook><x:ExcelWorksheets><x:ExcelWorksheet><x:Name>{worksheet}</x:Name><x:WorksheetOptions><x:DisplayGridlines/></x:WorksheetOptions></x:ExcelWorksheet></x:ExcelWorksheets></x:ExcelWorkbook></xml><![endif]--></head><body><img src="{table}" alt="grafica" /></body></html>'
            , base64 = function (s) { return window.btoa(unescape(encodeURIComponent(s))) }
            , format = function (s, c) { return s.replace(/{(\w+)}/g, function (m, p) { return c[p]; }) }

        var ctx = { worksheet: name || 'Hoja1', table: fileName + ".jpeg" }
        //window.location.href = uri + base64(format(template, ctx))
        var link = document.createElement("a");
        link.download = fileName+".xls";
        link.href = uri + base64(format(template, ctx));
        link.click();
    }
});

Result:
enter image description here


问:
How can I get the count of windows in the current workspace?
Within the context of X (), how can I get a count of the current windows in the workspace?

I know how to get the count from WindowSet and there is a function of windows :: (WindowSet -> WindowSet) -> X (). However I'd like to actually return a value so it would have to be something like (WindowSet -> WindowSet) -> X Int.

答:
Even shorter variants thanks to W.index:</p>

```<code>winCount = length . W.index . windowset <$> get
winCount = gets (windowset) >>= return . length . W.index
winCount = gets (W.index . windowset) >>= return . length
</code>```

Body:
Even shorter variants thanks to W.index:

winCount = length . W.index . windowset <$> get
winCount = gets (windowset) >>= return . length . W.index
winCount = gets (W.index . windowset) >>= return . length


问:
How to append output to the end of a text file
How do I append the output of a command to the end of a text file?</p>

答:
Use >> instead of > when directing output to a file:

```<code>your_command >> file_to_append_to
</code>```

If file_to_append_to does not exist, it will be created.

Example:

```<code>$ echo "hello" > file
$ echo "world" >> file
$ cat file
hello
world
</code>```

Body:
Use >> instead of > when directing output to a file:

your_command >> file_to_append_to

If file_to_append_to does not exist, it will be created.

Example:

$ echo "hello" > file
$ echo "world" >> file
$ cat file
hello
world


问:
Plotting multiple values to one key in python
I am trying to make a scatter plot with this dictionary

```<code>d = {1: [1, 2, 3, 4, 5], 3: [3, 6, 9, 12, 15], 5: [5, 10, 15, 20, 25]}
</code>```

I want the keys to be in X-axis and the values to be on Y-axis, and also to show a legend with different key values. I have tried this code-

```<code>import matplotlib.pyplot as plt

d = {1: [1, 2, 3, 4, 5], 3: [3, 6, 9, 12, 15], 5: [5, 10, 15, 20, 25]}
colors = list("rgbk")
x, y =[], []
for i in d.keys():
   for j in d[i]:
       x.append(i)
       y.append(j)
   plt.scatter(x, y, color = colors.pop())
   plt.legend(d.keys())
plt.show()
</code>```

But this is giving me a plot with points with only one colour but the legends are alright.

答: You initialize the x and y lists before the loop. In each iteration, you add new values to the list, and they overpaint the old points. Move the line x, y =[], [] into the loop.

Body:
I am trying to make a scatter plot with this dictionary

d = {1: [1, 2, 3, 4, 5], 3: [3, 6, 9, 12, 15], 5: [5, 10, 15, 20, 25]}

I want the keys to be in X-axis and the values to be on Y-axis, and also to show a legend with different key values. I have tried this code-

import matplotlib.pyplot as plt

d = {1: [1, 2, 3, 4, 5], 3: [3, 6, 9, 12, 15], 5: [5, 10, 15, 20, 25]}
colors = list("rgbk")
x, y =[], []
for i in d.keys():
   for j in d[i]:
       x.append(i)
       y.append(j)
   plt.scatter(x, y, color = colors.pop())
   plt.legend(d.keys())
plt.show()

But this is giving me a plot with points with only one colour but the legends are alright.


问:
Need insight on building a blog with firebase
Okay. So I've built a couple of websites for people. I'm a front end developer and I've toggled with backed a bit but not much to be confident about it. I am now ready to build my portfolio but it comes in combination with my blog.

I have to options.

Static website - I don't have a lot of time. I'm on clock for certain reasons so I'm not sure of this option. However I feel as though it will be easier to add the firebase series I want. Such as firebase hosting,  database, storage and authentication. Also you know how in blogs when your going through their post and you click 'next'and it pops up more blog posts. Can this be done with firebase?

WordPress - every person,  even none developers have toggled with WordPress. I'm no expert in it but Im sure it will be much easier to pick up that javascript. Because of time this seems the best option but I'm confused about integration with the services I want. I know that on WordPress I can create a post and it pops it up live. I don't need to create that with firebase? Will I even need firebase database or storage? How would I work with login in and authentication?

Any advice?

答:
If your goal is simply to build a page about yourself + blog pick the easiest CMS known which is Wordpress, in fact almost every even free template offers just that. The fastest, the simplest and the least time-consuming thing. Firebase is a nice tool rather intended for building applications with data streaming like real time application which is not your goal here. I have both firebase and wordpress projects behind me, and I'm a front end developer as well and with a clear conscience, if you only want to create a blog and your portfolio, don't worry about authentication and possible security, choose Wordpress.

However, if you approach this as a challenge and both the construction of the blog is to be a lesson to you, try one of the available starters for firebase blogs, e.g. https://github.com/NeoWu1216/firebase-blog

the idea of using firebase may seem cool but not for that purpose. Save your time and just install wordpress ;)


问:
In Serilog dynamically changing log file path?
I am having feature of dynamically changing log file path. But when I am changing the path which is configurable in Consul, it writes partial log at both places i.e. at old path as well at new path. Changing log file path should work without any service restart. How we can archive that?

We are writing in log file as follow:

```<code>.WriteTo.File(logFolderFullPath + "\\" + applicationName + "_.txt",
                         LogEventLevel.Error, shared: true,
                         fileSizeLimitBytes: fileSizeLimitBytes, rollOnFileSizeLimit: true, rollingInterval: RollingInterval.Day,
                          outputTemplate: "{Timestamp:yyyy-MM-dd HH:mm:ss} [{Level}] [{MachineName}] [{SourceContext}] {RequestId} {CorrelationId} {Message}{NewLine}{Exception}{properties}")
</code>```

logFolderFullPath is configurable path from appsetting.json. When we are changing the path it creates a log files at new path, but at the same time keeps writing in old path files also.

So we want it should stop writing to old path.

答:
You can try to use Serilog.Settings.Reloader which can swap your logger instance at run-time when your configuration changes.

Another common way to change properties of a logger at run-time, is to use Serilog.Sinks.Map, a sink that dispatches events based on properties of log events.

The example below uses a log event property called FileName to decide the name of the log file it'll write to, so whenever this property changes, the log file changes accordingly:

```<code>Log.Logger = new LoggerConfiguration()
    .WriteTo.Map("FileName", "IDontKnow", (fileName, wt) => wt.File($"{fileName}.txt"))
    .CreateLogger();

Log.ForContext("FileName", "Alice").Information("Hey!"); // writes to Alice.txt
Log.ForContext("FileName", "Bob").Information("Hello!"); // writes to Bob.txt
Log.Information("Hi Again!"); // writes to IDontKnow.txt (default if property is missing)

Log.CloseAndFlush();
</code>```

In your case, you want to change this property name dynamically based on changes to your configuration. A simple way of doing that is by creating a custom enricher that can change the values of a property like the one above based on your configuration settings.

Your custom enricher would look something like this:

```<code>internal class LogFilePathEnricher : ILogEventEnricher
{
    private string _cachedLogFilePath;
    private LogEventProperty _cachedLogFilePathProperty;

    public const string LogFilePathPropertyName = "LogFilePath";

    public void Enrich(LogEvent logEvent, ILogEventPropertyFactory propertyFactory)
    {
        var logFilePath = // Read path from your appsettings.json
        // Check for null, etc...

        LogEventProperty logFilePathProperty;

        if (logFilePath.Equals(_cachedLogFilePath))
        {
            // Path hasn't changed, so let's use the cached property
            logFilePathProperty = _cachedLogFilePathProperty;
        }
        else
        {
            // We've got a new path for the log. Let's create a new property
            // and cache it for future log events to use
            _cachedLogFilePath = logFilePath;

            _cachedLogFilePathProperty = logFilePathProperty =
                propertyFactory.CreateProperty(LogFilePathPropertyName, logFilePath);
        }

        logEvent.AddPropertyIfAbsent(logFilePathProperty);
    }
}
</code>```

NB: The example enricher above could be more efficient if you use the Options pattern, instead of checking the configuration every time a log message is written.

With an enricher that can dynamically set the LogFilePath property for you based on the configuration, you just have to configure the logging pipeline to map based on that property.

```<code>Log.Logger = new LoggerConfiguration()
    .Enrich.FromLogContext()
    .Enrich.With<LogFileNameEnricher>()
    .WriteTo.Map(LogFileNameEnricher.LogFilePathPropertyName,
        (logFilePath, wt) => wt.File($"{logFilePath}"), sinkMapCountLimit: 1)
    .CreateLogger();

// ...

Log.CloseAndFlush();
</code>```

Body:
I am having feature of dynamically changing log file path. But when I am changing the path which is configurable in Consul, it writes partial log at both places i.e. at old path as well at new path. Changing log file path should work without any service restart. How we can archive that?

We are writing in log file as follow:

.WriteTo.File(logFolderFullPath + "\\" + applicationName + "_.txt",
                         LogEventLevel.Error, shared: true,
                         fileSizeLimitBytes: fileSizeLimitBytes, rollOnFileSizeLimit: true, rollingInterval: RollingInterval.Day,
                          outputTemplate: "{Timestamp:yyyy-MM-dd HH:mm:ss} [{Level}] [{MachineName}] [{SourceContext}] {RequestId} {CorrelationId} {Message}{NewLine}{Exception}{properties}")

logFolderFullPath is configurable path from appsetting.json. When we are changing the path it creates a log files at new path, but at the same time keeps writing in old path files also.

So we want it should stop writing to old path.

Body:
You can try to use Serilog.Settings.Reloader which can swap your logger instance at run-time when your configuration changes.

Another common way to change properties of a logger at run-time, is to use Serilog.Sinks.Map, a sink that dispatches events based on properties of log events.

The example below uses a log event property called FileName to decide the name of the log file it'll write to, so whenever this property changes, the log file changes accordingly:

Log.Logger = new LoggerConfiguration()
    .WriteTo.Map("FileName", "IDontKnow", (fileName, wt) => wt.File($"{fileName}.txt"))
    .CreateLogger();

Log.ForContext("FileName", "Alice").Information("Hey!"); // writes to Alice.txt
Log.ForContext("FileName", "Bob").Information("Hello!"); // writes to Bob.txt
Log.Information("Hi Again!"); // writes to IDontKnow.txt (default if property is missing)

Log.CloseAndFlush();

In your case, you want to change this property name dynamically based on changes to your configuration. A simple way of doing that is by creating a custom enricher that can change the values of a property like the one above based on your configuration settings.

Your custom enricher would look something like this:

internal class LogFilePathEnricher : ILogEventEnricher
{
    private string _cachedLogFilePath;
    private LogEventProperty _cachedLogFilePathProperty;

    public const string LogFilePathPropertyName = "LogFilePath";

    public void Enrich(LogEvent logEvent, ILogEventPropertyFactory propertyFactory)
    {
        var logFilePath = // Read path from your appsettings.json
        // Check for null, etc...

        LogEventProperty logFilePathProperty;

        if (logFilePath.Equals(_cachedLogFilePath))
        {
            // Path hasn't changed, so let's use the cached property
            logFilePathProperty = _cachedLogFilePathProperty;
        }
        else
        {
            // We've got a new path for the log. Let's create a new property
            // and cache it for future log events to use
            _cachedLogFilePath = logFilePath;

            _cachedLogFilePathProperty = logFilePathProperty =
                propertyFactory.CreateProperty(LogFilePathPropertyName, logFilePath);
        }

        logEvent.AddPropertyIfAbsent(logFilePathProperty);
    }
}

NB: The example enricher above could be more efficient if you use the Options pattern, instead of checking the configuration every time a log message is written.

With an enricher that can dynamically set the LogFilePath property for you based on the configuration, you just have to configure the logging pipeline to map based on that property.

Log.Logger = new LoggerConfiguration()
    .Enrich.FromLogContext()
    .Enrich.With<LogFileNameEnricher>()
    .WriteTo.Map(LogFileNameEnricher.LogFilePathPropertyName,
        (logFilePath, wt) => wt.File($"{logFilePath}"), sinkMapCountLimit: 1)
    .CreateLogger();

// ...

Log.CloseAndFlush();


问:
CSS transition to work when object is toggled by jQuery
I have this simple horizontal chart script.
When you click on the button, width of the filler changes to 100%.

I've tried to add transition to the .filler, but it does not work.

How can I animate it?

$("#button").on("click", function() {
  $(".filler").css("width", "100%");
  $(".filler").html("100%");
});```
<pre class="snippet-code-css lang-css prettyprint-override"><code>.borders {
margin: 10px 0px 10px 0px;
width: 200px;
border: 1px solid black;
}

.filler {
background-color: green;
white-space: nowrap;
color: white;
}</code>```

<button id="button">Click me to fill the chart</button>

15%

```

答:
Add transition to filter class</p>

```<code>.filter {transition: all 0.5s;}
</code>```

Body:
I have this simple horizontal chart script.
When you click on the button, width of the filler changes to 100%.

I've tried to add transition to the .filler, but it does not work.

How can I animate it?

$("#button").on("click", function() {
  $(".filler").css("width", "100%");
  $(".filler").html("100%");
});

.borders {
margin: 10px 0px 10px 0px;
width: 200px;
border: 1px solid black;
}

.filler {
background-color: green;
white-space: nowrap;
color: white;
}

<button id="button">Click me to fill the chart</button>

15%

Body:
Add transition to filter class

.filter {transition: all 0.5s;}


问:
Add quotes to item in list - Python
How do you add quotes "" to each item in the list? I'm getting the data from an excel file using pandas then converting it to a list. I've added a picture of the excel file and the output I'm getting. I've also added the desired output. How can I achieve this?

```<code>import xlrd
import pandas as pd
import io
import numpy as np

path = r'C:\Temp Files\Excel_2.xlsx'
df = pd.read_excel(path).replace('"','')

res = (df.dropna(how='all') #remove completely empty rows
.dropna(how='all',axis=1) #remove completely empty columns
.T #flip columns into row position
#convert to list
.to_numpy()
.tolist()

)

print(res)
</code>```

OUTPUT

[[nan, 'Title_1', 'RED_100', Timestamp('2019-01-01 00:00:00'), 10], [nan, 'Title_2', 'GREEN_200', Timestamp('2018-02-02 00:00:00'), 20], [nan, 'Title_3', 'RED_300', Timestamp('2019-11-15 00:00:00'), 30], [123456, 'Title_4', 'YELLOW_100', Timestamp('2019-01-01 00:00:00'), 40]]

DESIRED OUTPUT

[[nan, "Title_1", "RED_100", "Timestamp('2019-01-01 00:00:00')", "10"],[nan, "Title_2", "GREEN_200", "Timestamp('2018-02-02 00:00:00')", "20"],[nan, "Title_3", "RED_300", "Timestamp('2019-11-15 00:00:00')", "30"],["123456", "Title_4", "YELLOW_100", "Timestamp('2019-01-01 00:00:00')", "40"]]

Excel File

答:
I was able to solve this by changing

df = pd.read_excel(path).replace('"','')

to

df = pd.read_excel(path, dtype=str)

adding dtype=str changes all the values into a string and adds the quotes around that data

Title: Add quotes to item in list - Python

Body:
How do you add quotes "" to each item in the list? I'm getting the data from an excel file using pandas then converting it to a list. I've added a picture of the excel file and the output I'm getting. I've also added the desired output. How can I achieve this?

import xlrd
import pandas as pd
import io
import numpy as np

path = r'C:\Temp Files\Excel_2.xlsx'
df = pd.read_excel(path).replace('"','')

res = (df.dropna(how='all') #remove completely empty rows
.dropna(how='all',axis=1) #remove completely empty columns
.T #flip columns into row position
#convert to list
.to_numpy()
.tolist()

)

print(res)

OUTPUT

[[nan, 'Title_1', 'RED_100', Timestamp('2019-01-01 00:00:00'), 10], [nan, 'Title_2', 'GREEN_200', Timestamp('2018-02-02 00:00:00'), 20], [nan, 'Title_3', 'RED_300', Timestamp('2019-11-15 00:00:00'), 30], [123456, 'Title_4', 'YELLOW_100', Timestamp('2019-01-01 00:00:00'), 40]]

DESIRED OUTPUT

[[nan, "Title_1", "RED_100", "Timestamp('2019-01-01 00:00:00')", "10"],[nan, "Title_2", "GREEN_200", "Timestamp('2018-02-02 00:00:00')", "20"],[nan, "Title_3", "RED_300", "Timestamp('2019-11-15 00:00:00')", "30"],["123456", "Title_4", "YELLOW_100", "Timestamp('2019-01-01 00:00:00')", "40"]]

Excel File