问:
mysql query - clash between not in and/or
I'm trying to get all my products , from A specific categories and without some products from those categories .

i did this query:

```<code>SELECT `ps_product`.`id_product`,`ps_product_lang`.`name`
FROM `ps_product`, `ps_product_lang`
WHERE
    `ps_product`.`id_product` = `ps_product_lang`.`id_product`
    AND `ps_product`.`id_manufacturer` NOT IN (3,7,10,11,13,14,19,22,23,24,25,30,31,32,33,34,37,38,41,42,43,44,45,46,47,48,49,50)
    AND `ps_product_lang`.`name` not in ( '%OLP%' ,'%LicSAPk%' ,'%SPLA%','%SA OLP%')
</code>```

The problem is that i'm still getting products with the string 'SPLA' or 'SA OLP' - because the NOT IN clash with the categories

How to solve it ?

答:
The operator IN is used to match a value exactly and not partially against a list of values. So you can't use wildcards like '%'.

You have to use the operator LIKE for each of the values:

```<code>AND `ps_product_lang`.`name` not like '%OLP%'
AND `ps_product_lang`.`name` not like '%LicSAPk%'
AND `ps_product_lang`.`name` not like '%SPLA%'
AND `ps_product_lang`.`name` not like '%SA OLP%'
</code>```

Body:
I'm trying to get all my products , from A specific categories and without some products from those categories .

i did this query:

SELECT `ps_product`.`id_product`,`ps_product_lang`.`name`
FROM `ps_product`, `ps_product_lang`
WHERE
    `ps_product`.`id_product` = `ps_product_lang`.`id_product`
    AND `ps_product`.`id_manufacturer` NOT IN (3,7,10,11,13,14,19,22,23,24,25,30,31,32,33,34,37,38,41,42,43,44,45,46,47,48,49,50)
    AND `ps_product_lang`.`name` not in ( '%OLP%' ,'%LicSAPk%' ,'%SPLA%','%SA OLP%')

The problem is that i'm still getting products with the string 'SPLA' or 'SA OLP' - because the NOT IN clash with the categories

How to solve it ?

Body:
The operator IN is used to match a value exactly and not partially against a list of values. So you can't use wildcards like '%'.

You have to use the operator LIKE for each of the values:

AND `ps_product_lang`.`name` not like '%OLP%'
AND `ps_product_lang`.`name` not like '%LicSAPk%'
AND `ps_product_lang`.`name` not like '%SPLA%'
AND `ps_product_lang`.`name` not like '%SA OLP%'


来源: stackexchange

问:
When/why to prefix variables with "$" when using jQuery?

Possible Duplicate:

  Why would a javascript variable start with a dollar sign?

I see people using the dollar sign in front of variables when using jQuery. Is there any reason behind this? I'm I missing something basic or is it just a common practice?

答:
It's a common reference to a jQuery wrapped object.  It makes reading the code easier to know which variables are jQuery wrapped.</p>

```<code>//Item has been "cached" for later use in the script as a jQuery object.
var $item = $(this);
</code>```

ContentLicense: CC BY-SA 3.0

Body:
It's a common reference to a jQuery wrapped object.  It makes reading the code easier to know which variables are jQuery wrapped.

//Item has been "cached" for later use in the script as a jQuery object.
var $item = $(this);


问:
List of same components with same functions - code bloat?
I'm using Vue and I wonder if I have a list of components (50 button with the very same function within each one of them) - will Vue recognize it as a repetetive code and reduce to one function that all those 50 button will use or each one will compile it's own function while bundling? </p>

答:
will Vue recognize it as a repetetive code and reduce to one..

No. Vue will not scan your code for similar code and try to optimize it.

However, when Vue is updating a list of elements rendered with v-for, by default it uses an “in-place patch” strategy. If the order of the data items has changed, instead of moving the DOM elements to match the order of the items, Vue will patch each element in-place and make sure it reflects what should be rendered at that particular index.

Maybe this is what you are confused with? This is not the same as the question you are asking, but the closest thing vue would do "magically".

If you have 50 similar buttons, I would advice you to rather take advantage of props, slots and slot scopes to only have one button component that you can tweek in place where you need them to be different. 50 alike buttons sounds like a bad pattern.

ContentLicense: CC BY-SA 4.0


问:
How do I remove the bounce effect when translating away from the screen with css transition?
It's kind of hard to explain in words what I'm looking for without a visual example, so here's the basic idea:
https://codepen.io/jwiggiff/full/xxwvVbr

var cube = $('.cube');
var wrapper = $('.wrapper');

$(document).mousemove((e) => {
  if(!cube.hasClass('locked')) {
    var deltaX = e.pageX - (wrapper.offset().left+(wrapper.width()/2));
    var deltaY = e.pageY - (wrapper.offset().top+(wrapper.height()/2));
    var rotateY = deltaX/($(document).width()/2) * 90;
    var rotateX = deltaY/(($(document).height()/2)) * -90;
    cube.css("transform", " rotateY("+rotateY+"deg) rotateX("+rotateX+"deg)");
  }
});

$('.top-label').click((e) => {
  cube.toggleClass('locked locked-bottom');
  $('.labels div:not(.top-label)').fadeToggle();
});
$('.bottom-label').click((e) => {
  cube.toggleClass('locked locked-top');
  $('.labels div:not(.bottom-label)').fadeToggle();
});
$('.left-label').click((e) => {
  cube.toggleClass('locked locked-right');
  $('.labels div:not(.left-label)').fadeToggle();
});
$('.right-label').click((e) => {
  cube.toggleClass('locked locked-left');
  $('.labels div:not(.right-label)').fadeToggle();
});```
<pre class="snippet-code-css lang-css prettyprint-override"><code>/* Variables */
:root {
  --cube-scale: 60vh;
}

/* Styles */
* {
  margin: 0;
  padding: 0;
  box-sizing: border-box;
}

body {
  font-family: "Montserrat", sans-serif;
  overflow: hidden;
}

.cube div {
  padding: 10vh;
  border: 5px solid blue;
  transition: all 500ms ease-in-out;
}

.cube div h1 {
  font-family: "Carter One", cursive;
}

.cube div p {
  font-size: 14px;
}

/* Labels */
.labels {
  color: black;
  position: absolute;
  top: 0;
  left: 0;
  width: 100%;
  height: 100%;
}

.labels div {
  transition: all 500ms ease-in-out;
}

.left-label {
  position: absolute;
  top: 50%;
  left: 0;
  transform: translate(0, -50%);
  padding: 20px 10px;
}

.right-label {
  position: absolute;
  top: 50%;
  right: 0;
  transform: translate(0, -50%);
  padding: 20px 10px;
}

.top-label {
  position: absolute;
  top: 0;
  left: 50%;
  width: 100%;
  text-align: center;
  transform: translate(-50%, 0);
  padding: 10px 20px;
}

.bottom-label {
  position: absolute;
  bottom: 0;
  left: 50%;
  width: 100%;
  text-align: center;
  transform: translate(-50%, 0);
  padding: 10px 20px;
}

/* 3D Cube */
.wrapper {
  width: var(--cube-scale);
  height: var(--cube-scale);
  position: absolute;
  top: 50%;
  left: 50%;
  transform: translate(-50%, -50%);
  perspective: calc(var(--cube-scale)*4);
}

.cube {
  width: 100%;
  height: 100%;
  position: relative;
  transform-style: preserve-3d;
}

.cube.locked.locked-bottom {
  transition: all 500ms ease-in-out;
  transform: rotateX(90deg) translateY(calc(var(--cube-scale) / -2)) !important;
}
.locked-bottom .bottom {
  height: 100vh;
  width: 100vw;
  transform: rotateX(-90deg) translateZ(calc(var(--cube-scale) / 2)) translate(calc(((100vw/2) - (var(--cube-scale)/2)) * -1), calc(((100vh/2) - (var(--cube-scale)/2)) * -1));
}

.cube.locked.locked-top {
  transition: all 500ms ease-in-out;
  transform: rotateX(-90deg) translateY(calc(var(--cube-scale) / 2)) !important;
}
.locked-top .top {
  height: 100vh;
  width: 100vw;
  transform: rotateX(90deg) translateZ(calc(var(--cube-scale) / 2)) translate(calc(((100vw/2) - (var(--cube-scale)/2)) * -1), calc(((100vh/2) - (var(--cube-scale)/2)) * -1));
}

.cube.locked.locked-right {
  transition: all 500ms ease-in-out;
  transform: rotateY(-90deg) translateX(calc(var(--cube-scale) / -2)) !important;
}
.locked-right .right {
  height: 100vh;
  width: 100vw;
  transform: rotateY(90deg) translateZ(calc(var(--cube-scale) / 2)) translate(calc(((100vw/2) - (var(--cube-scale)/2)) * -1), calc(((100vh/2) - (var(--cube-scale)/2)) * -1));
}

.cube.locked.locked-left {
  transition: all 500ms ease-in-out;
  transform: rotateY(90deg) translateX(calc(var(--cube-scale) / 2)) !important;
}
.locked-left .left {
  height: 100vh;
  width: 100vw;
  transform: rotateY(-90deg) translateZ(calc(var(--cube-scale) / 2)) translate(calc(((100vw/2) - (var(--cube-scale)/2)) * -1), calc(((100vh/2) - (var(--cube-scale)/2)) * -1));
}

.cube div {
  transform-origin: calc(var(--cube-scale)/2) calc(var(--cube-scale)/2);
 position: absolute;
 width: var(--cube-scale);
 height: var(--cube-scale);
}

.front {
  background: rgba(255,0,0,0.7);
  transform: rotateY(0deg) translateZ(calc(var(--cube-scale) / 2));
}

.right {
  background-color: rgba(0,255,0,0.7);
  transform: rotateY(90deg) translateZ(calc(var(--cube-scale) / 2));
}

.back {
  background-color: rgba(0,0,255,0.7);
  transform: rotateY(180deg) translateZ(calc(var(--cube-scale) / 2));
}

.left {
  background-color: rgba(255,165,0,0.7);
  transform: rotateY(-90deg) translateZ(calc(var(--cube-scale) / 2));
}

.top {
  background-color: rgba(128,0,128,0.7);
  transform: rotateX(90deg) translateZ(calc(var(--cube-scale) / 2));
}

.bottom {
  background-color: rgba(255,0,255,0.7);
  transform: rotateX(-90deg) translateZ(calc(var(--cube-scale) / 2));
}</code>```

Right

Left

Bottom

Top

```

In the codepen, if you click the text on the edge of the screen, it moves the current face to cover the entire window. When you click the left or right text, it has the expected result. However, if you click the top or the bottom text, you can see the cube has a bit of an arc when translating away from the screen, whereas the left/right ones do not. Any ideas as to what is causing this bounce/arc and how to fix it would be much appreciated!

答:
Add rotateY(0) to .cube.locked.locked-bottom and to .cube.locked.locked-top to avoid this issue.

It's a bit tricky but this is due to the fact that you are applying a dynamic transformation using  rotateY(a) rotateX(b) and this will not transition the same way to rotateX() translateZ() and to rotateY() translateZ(). If you make rotateX() translateZ() equal to rotateY(0) rotateX() translateZ() you will have the same transition:

var cube = $('.cube');
var wrapper = $('.wrapper');

$(document).mousemove((e) => {
  if(!cube.hasClass('locked')) {
    var deltaX = e.pageX - (wrapper.offset().left+(wrapper.width()/2));
    var deltaY = e.pageY - (wrapper.offset().top+(wrapper.height()/2));
    var rotateY = deltaX/($(document).width()/2) * 90;
    var rotateX = deltaY/(($(document).height()/2)) * -90;
    cube.css("transform", " rotateY("+rotateY+"deg) rotateX("+rotateX+"deg)");
  }
});

$('.top-label').click((e) => {
  cube.toggleClass('locked locked-bottom');
  $('.labels div:not(.top-label)').fadeToggle();
});
$('.bottom-label').click((e) => {
  cube.toggleClass('locked locked-top');
  $('.labels div:not(.bottom-label)').fadeToggle();
});
$('.left-label').click((e) => {
  cube.toggleClass('locked locked-right');
  $('.labels div:not(.left-label)').fadeToggle();
});
$('.right-label').click((e) => {
  cube.toggleClass('locked locked-left');
  $('.labels div:not(.right-label)').fadeToggle();
});```
<pre class="snippet-code-css lang-css prettyprint-override"><code>/* Variables */
:root {
  --cube-scale: 60vh;
}

/* Styles */
* {
  margin: 0;
  padding: 0;
  box-sizing: border-box;
}

body {
  font-family: "Montserrat", sans-serif;
  overflow: hidden;
}

.cube div {
  padding: 10vh;
  border: 5px solid blue;
  transition: all 500ms ease-in-out;
}

.cube div h1 {
  font-family: "Carter One", cursive;
}

.cube div p {
  font-size: 14px;
}

/* Labels */
.labels {
  color: black;
  position: absolute;
  top: 0;
  left: 0;
  width: 100%;
  height: 100%;
}

.labels div {
  transition: all 500ms ease-in-out;
}

.left-label {
  position: absolute;
  top: 50%;
  left: 0;
  transform: translate(0, -50%);
  padding: 20px 10px;
}

.right-label {
  position: absolute;
  top: 50%;
  right: 0;
  transform: translate(0, -50%);
  padding: 20px 10px;
}

.top-label {
  position: absolute;
  top: 0;
  left: 50%;
  width: 100%;
  text-align: center;
  transform: translate(-50%, 0);
  padding: 10px 20px;
}

.bottom-label {
  position: absolute;
  bottom: 0;
  left: 50%;
  width: 100%;
  text-align: center;
  transform: translate(-50%, 0);
  padding: 10px 20px;
}

/* 3D Cube */
.wrapper {
  width: var(--cube-scale);
  height: var(--cube-scale);
  position: absolute;
  top: 50%;
  left: 50%;
  transform: translate(-50%, -50%);
  perspective: calc(var(--cube-scale)*4);
}

.cube {
  width: 100%;
  height: 100%;
  position: relative;
  transform-style: preserve-3d;
}

/*here*/
.cube.locked.locked-bottom {
  transition: all 500ms ease-in-out;
  transform:rotateY(0) rotateX(90deg) translateY(calc(var(--cube-scale) / -2)) !important;
}
.locked-bottom .bottom {
  height: 100vh;
  width: 100vw;
  transform: rotateX(-90deg) translateZ(calc(var(--cube-scale) / 2)) translate(calc(((100vw/2) - (var(--cube-scale)/2)) * -1), calc(((100vh/2) - (var(--cube-scale)/2)) * -1));
}

/* here */
.cube.locked.locked-top {
  transition: all 500ms ease-in-out;
  transform:rotateY(0) rotateX(-90deg) translateY(calc(var(--cube-scale) / 2)) !important;
}
.locked-top .top {
  height: 100vh;
  width: 100vw;
  transform:rotateY(0) rotateX(90deg) translateZ(calc(var(--cube-scale) / 2)) translate(calc(((100vw/2) - (var(--cube-scale)/2)) * -1), calc(((100vh/2) - (var(--cube-scale)/2)) * -1));
}

.cube.locked.locked-right {
  transition: all 500ms ease-in-out;
  transform: rotateY(-90deg) translateX(calc(var(--cube-scale) / -2)) !important;
}
.locked-right .right {
  height: 100vh;
  width: 100vw;
  transform: rotateY(90deg) translateZ(calc(var(--cube-scale) / 2)) translate(calc(((100vw/2) - (var(--cube-scale)/2)) * -1), calc(((100vh/2) - (var(--cube-scale)/2)) * -1));
}

.cube.locked.locked-left {
  transition: all 500ms ease-in-out;
  transform: rotateY(90deg) translateX(calc(var(--cube-scale) / 2)) !important;
}
.locked-left .left {
  height: 100vh;
  width: 100vw;
  transform: rotateY(-90deg) translateZ(calc(var(--cube-scale) / 2)) translate(calc(((100vw/2) - (var(--cube-scale)/2)) * -1), calc(((100vh/2) - (var(--cube-scale)/2)) * -1));
}

.cube div {
  transform-origin: calc(var(--cube-scale)/2) calc(var(--cube-scale)/2);
 position: absolute;
 width: var(--cube-scale);
 height: var(--cube-scale);
}

.front {
  background: rgba(255,0,0,0.7);
  transform: rotateY(0deg) translateZ(calc(var(--cube-scale) / 2));
}

.right {
  background-color: rgba(0,255,0,0.7);
  transform: rotateY(90deg) translateZ(calc(var(--cube-scale) / 2));
}

.back {
  background-color: rgba(0,0,255,0.7);
  transform: rotateY(180deg) translateZ(calc(var(--cube-scale) / 2));
}

.left {
  background-color: rgba(255,165,0,0.7);
  transform: rotateY(-90deg) translateZ(calc(var(--cube-scale) / 2));
}

.top {
  background-color: rgba(128,0,128,0.7);
  transform:  rotateX(90deg) translateZ(calc(var(--cube-scale) / 2));
}

.bottom {
  background-color: rgba(255,0,255,0.7);
  transform: rotateX(-90deg) translateZ(calc(var(--cube-scale) / 2));
}</code>```

Right

Left

Bottom

Top

```

Related question to get more details about how interpolation is done between transform: Weird behavior when rotating an element on hover

Body:
It's kind of hard to explain in words what I'm looking for without a visual example, so here's the basic idea:
https://codepen.io/jwiggiff/full/xxwvVbr

var cube = $('.cube');
var wrapper = $('.wrapper');

$(document).mousemove((e) => {
  if(!cube.hasClass('locked')) {
    var deltaX = e.pageX - (wrapper.offset().left+(wrapper.width()/2));
    var deltaY = e.pageY - (wrapper.offset().top+(wrapper.height()/2));
    var rotateY = deltaX/($(document).width()/2) * 90;
    var rotateX = deltaY/(($(document).height()/2)) * -90;
    cube.css("transform", " rotateY("+rotateY+"deg) rotateX("+rotateX+"deg)");
  }
});

$('.top-label').click((e) => {
  cube.toggleClass('locked locked-bottom');
  $('.labels div:not(.top-label)').fadeToggle();
});
$('.bottom-label').click((e) => {
  cube.toggleClass('locked locked-top');
  $('.labels div:not(.bottom-label)').fadeToggle();
});
$('.left-label').click((e) => {
  cube.toggleClass('locked locked-right');
  $('.labels div:not(.left-label)').fadeToggle();
});
$('.right-label').click((e) => {
  cube.toggleClass('locked locked-left');
  $('.labels div:not(.right-label)').fadeToggle();
});

/* Variables */
:root {
  --cube-scale: 60vh;
}

/* Styles */
* {
  margin: 0;
  padding: 0;
  box-sizing: border-box;
}

body {
  font-family: "Montserrat", sans-serif;
  overflow: hidden;
}

.cube div {
  padding: 10vh;
  border: 5px solid blue;
  transition: all 500ms ease-in-out;
}

.cube div h1 {
  font-family: "Carter One", cursive;
}

.cube div p {
  font-size: 14px;
}

/* Labels */
.labels {
  color: black;
  position: absolute;
  top: 0;
  left: 0;
  width: 100%;
  height: 100%;
}

.labels div {
  transition: all 500ms ease-in-out;
}

.left-label {
  position: absolute;
  top: 50%;
  left: 0;
  transform: translate(0, -50%);
  padding: 20px 10px;
}

.right-label {
  position: absolute;
  top: 50%;
  right: 0;
  transform: translate(0, -50%);
  padding: 20px 10px;
}

.top-label {
  position: absolute;
  top: 0;
  left: 50%;
  width: 100%;
  text-align: center;
  transform: translate(-50%, 0);
  padding: 10px 20px;
}

.bottom-label {
  position: absolute;
  bottom: 0;
  left: 50%;
  width: 100%;
  text-align: center;
  transform: translate(-50%, 0);
  padding: 10px 20px;
}

/* 3D Cube */
.wrapper {
  width: var(--cube-scale);
  height: var(--cube-scale);
  position: absolute;
  top: 50%;
  left: 50%;
  transform: translate(-50%, -50%);
  perspective: calc(var(--cube-scale)*4);
}

.cube {
  width: 100%;
  height: 100%;
  position: relative;
  transform-style: preserve-3d;
}

.cube.locked.locked-bottom {
  transition: all 500ms ease-in-out;
  transform: rotateX(90deg) translateY(calc(var(--cube-scale) / -2)) !important;
}
.locked-bottom .bottom {
  height: 100vh;
  width: 100vw;
  transform: rotateX(-90deg) translateZ(calc(var(--cube-scale) / 2)) translate(calc(((100vw/2) - (var(--cube-scale)/2)) * -1), calc(((100vh/2) - (var(--cube-scale)/2)) * -1));
}

.cube.locked.locked-top {
  transition: all 500ms ease-in-out;
  transform: rotateX(-90deg) translateY(calc(var(--cube-scale) / 2)) !important;
}
.locked-top .top {
  height: 100vh;
  width: 100vw;
  transform: rotateX(90deg) translateZ(calc(var(--cube-scale) / 2)) translate(calc(((100vw/2) - (var(--cube-scale)/2)) * -1), calc(((100vh/2) - (var(--cube-scale)/2)) * -1));
}

.cube.locked.locked-right {
  transition: all 500ms ease-in-out;
  transform: rotateY(-90deg) translateX(calc(var(--cube-scale) / -2)) !important;
}
.locked-right .right {
  height: 100vh;
  width: 100vw;
  transform: rotateY(90deg) translateZ(calc(var(--cube-scale) / 2)) translate(calc(((100vw/2) - (var(--cube-scale)/2)) * -1), calc(((100vh/2) - (var(--cube-scale)/2)) * -1));
}

.cube.locked.locked-left {
  transition: all 500ms ease-in-out;
  transform: rotateY(90deg) translateX(calc(var(--cube-scale) / 2)) !important;
}
.locked-left .left {
  height: 100vh;
  width: 100vw;
  transform: rotateY(-90deg) translateZ(calc(var(--cube-scale) / 2)) translate(calc(((100vw/2) - (var(--cube-scale)/2)) * -1), calc(((100vh/2) - (var(--cube-scale)/2)) * -1));
}

.cube div {
  transform-origin: calc(var(--cube-scale)/2) calc(var(--cube-scale)/2);
 position: absolute;
 width: var(--cube-scale);
 height: var(--cube-scale);
}

.front {
  background: rgba(255,0,0,0.7);
  transform: rotateY(0deg) translateZ(calc(var(--cube-scale) / 2));
}

.right {
  background-color: rgba(0,255,0,0.7);
  transform: rotateY(90deg) translateZ(calc(var(--cube-scale) / 2));
}

.back {
  background-color: rgba(0,0,255,0.7);
  transform: rotateY(180deg) translateZ(calc(var(--cube-scale) / 2));
}

.left {
  background-color: rgba(255,165,0,0.7);
  transform: rotateY(-90deg) translateZ(calc(var(--cube-scale) / 2));
}

.top {
  background-color: rgba(128,0,128,0.7);
  transform: rotateX(90deg) translateZ(calc(var(--cube-scale) / 2));
}

.bottom {
  background-color: rgba(255,0,255,0.7);
  transform: rotateX(-90deg) translateZ(calc(var(--cube-scale) / 2));
}

Right

Left

Bottom

Top

In the codepen, if you click the text on the edge of the screen, it moves the current face to cover the entire window. When you click the left or right text, it has the expected result. However, if you click the top or the bottom text, you can see the cube has a bit of an arc when translating away from the screen, whereas the left/right ones do not. Any ideas as to what is causing this bounce/arc and how to fix it would be much appreciated!

Body:
Add rotateY(0) to .cube.locked.locked-bottom and to .cube.locked.locked-top to avoid this issue.

It's a bit tricky but this is due to the fact that you are applying a dynamic transformation using  rotateY(a) rotateX(b) and this will not transition the same way to rotateX() translateZ() and to rotateY() translateZ(). If you make rotateX() translateZ() equal to rotateY(0) rotateX() translateZ() you will have the same transition:

var cube = $('.cube');
var wrapper = $('.wrapper');

$(document).mousemove((e) => {
  if(!cube.hasClass('locked')) {
    var deltaX = e.pageX - (wrapper.offset().left+(wrapper.width()/2));
    var deltaY = e.pageY - (wrapper.offset().top+(wrapper.height()/2));
    var rotateY = deltaX/($(document).width()/2) * 90;
    var rotateX = deltaY/(($(document).height()/2)) * -90;
    cube.css("transform", " rotateY("+rotateY+"deg) rotateX("+rotateX+"deg)");
  }
});

$('.top-label').click((e) => {
  cube.toggleClass('locked locked-bottom');
  $('.labels div:not(.top-label)').fadeToggle();
});
$('.bottom-label').click((e) => {
  cube.toggleClass('locked locked-top');
  $('.labels div:not(.bottom-label)').fadeToggle();
});
$('.left-label').click((e) => {
  cube.toggleClass('locked locked-right');
  $('.labels div:not(.left-label)').fadeToggle();
});
$('.right-label').click((e) => {
  cube.toggleClass('locked locked-left');
  $('.labels div:not(.right-label)').fadeToggle();
});

/* Variables */
:root {
  --cube-scale: 60vh;
}

/* Styles */
* {
  margin: 0;
  padding: 0;
  box-sizing: border-box;
}

body {
  font-family: "Montserrat", sans-serif;
  overflow: hidden;
}

.cube div {
  padding: 10vh;
  border: 5px solid blue;
  transition: all 500ms ease-in-out;
}

.cube div h1 {
  font-family: "Carter One", cursive;
}

.cube div p {
  font-size: 14px;
}

/* Labels */
.labels {
  color: black;
  position: absolute;
  top: 0;
  left: 0;
  width: 100%;
  height: 100%;
}

.labels div {
  transition: all 500ms ease-in-out;
}

.left-label {
  position: absolute;
  top: 50%;
  left: 0;
  transform: translate(0, -50%);
  padding: 20px 10px;
}

.right-label {
  position: absolute;
  top: 50%;
  right: 0;
  transform: translate(0, -50%);
  padding: 20px 10px;
}

.top-label {
  position: absolute;
  top: 0;
  left: 50%;
  width: 100%;
  text-align: center;
  transform: translate(-50%, 0);
  padding: 10px 20px;
}

.bottom-label {
  position: absolute;
  bottom: 0;
  left: 50%;
  width: 100%;
  text-align: center;
  transform: translate(-50%, 0);
  padding: 10px 20px;
}

/* 3D Cube */
.wrapper {
  width: var(--cube-scale);
  height: var(--cube-scale);
  position: absolute;
  top: 50%;
  left: 50%;
  transform: translate(-50%, -50%);
  perspective: calc(var(--cube-scale)*4);
}

.cube {
  width: 100%;
  height: 100%;
  position: relative;
  transform-style: preserve-3d;
}

/*here*/
.cube.locked.locked-bottom {
  transition: all 500ms ease-in-out;
  transform:rotateY(0) rotateX(90deg) translateY(calc(var(--cube-scale) / -2)) !important;
}
.locked-bottom .bottom {
  height: 100vh;
  width: 100vw;
  transform: rotateX(-90deg) translateZ(calc(var(--cube-scale) / 2)) translate(calc(((100vw/2) - (var(--cube-scale)/2)) * -1), calc(((100vh/2) - (var(--cube-scale)/2)) * -1));
}

/* here */
.cube.locked.locked-top {
  transition: all 500ms ease-in-out;
  transform:rotateY(0) rotateX(-90deg) translateY(calc(var(--cube-scale) / 2)) !important;
}
.locked-top .top {
  height: 100vh;
  width: 100vw;
  transform:rotateY(0) rotateX(90deg) translateZ(calc(var(--cube-scale) / 2)) translate(calc(((100vw/2) - (var(--cube-scale)/2)) * -1), calc(((100vh/2) - (var(--cube-scale)/2)) * -1));
}

.cube.locked.locked-right {
  transition: all 500ms ease-in-out;
  transform: rotateY(-90deg) translateX(calc(var(--cube-scale) / -2)) !important;
}
.locked-right .right {
  height: 100vh;
  width: 100vw;
  transform: rotateY(90deg) translateZ(calc(var(--cube-scale) / 2)) translate(calc(((100vw/2) - (var(--cube-scale)/2)) * -1), calc(((100vh/2) - (var(--cube-scale)/2)) * -1));
}

.cube.locked.locked-left {
  transition: all 500ms ease-in-out;
  transform: rotateY(90deg) translateX(calc(var(--cube-scale) / 2)) !important;
}
.locked-left .left {
  height: 100vh;
  width: 100vw;
  transform: rotateY(-90deg) translateZ(calc(var(--cube-scale) / 2)) translate(calc(((100vw/2) - (var(--cube-scale)/2)) * -1), calc(((100vh/2) - (var(--cube-scale)/2)) * -1));
}

.cube div {
  transform-origin: calc(var(--cube-scale)/2) calc(var(--cube-scale)/2);
 position: absolute;
 width: var(--cube-scale);
 height: var(--cube-scale);
}

.front {
  background: rgba(255,0,0,0.7);
  transform: rotateY(0deg) translateZ(calc(var(--cube-scale) / 2));
}

.right {
  background-color: rgba(0,255,0,0.7);
  transform: rotateY(90deg) translateZ(calc(var(--cube-scale) / 2));
}

.back {
  background-color: rgba(0,0,255,0.7);
  transform: rotateY(180deg) translateZ(calc(var(--cube-scale) / 2));
}

.left {
  background-color: rgba(255,165,0,0.7);
  transform: rotateY(-90deg) translateZ(calc(var(--cube-scale) / 2));
}

.top {
  background-color: rgba(128,0,128,0.7);
  transform:  rotateX(90deg) translateZ(calc(var(--cube-scale) / 2));
}

.bottom {
  background-color: rgba(255,0,255,0.7);
  transform: rotateX(-90deg) translateZ(calc(var(--cube-scale) / 2));
}

<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<div class="wrapper">
  <div class="cube">
    <div class="front"></div>
    <div class="back"></div>
    <div class="left"></div>
    <div class="right"></div>
    <div class="top"></div>
    <div class="bottom"></div>
  </div>
</div>
<div class="labels">
  <div class="left-label"><span>Right</span></div>
  <div class="right-label"><span>Left</span></div>
  <div class="top-label"><span>Bottom</span></div>
  <div class="bottom-label"><span>Top</span></div>
</div>

Related question to get more details about how interpolation is done between transform: Weird behavior when rotating an element on hover


问:
Using regex replacement in Sublime 3
I am trying to use replace in Sublime using regular expressions but I'm stuck. I tried various combinations but don't seem to be getting there.

This is the input and my desired output:

Input: N_BBP_c_46137_n

Output : BBP

I tried combinations of:

```<code>[^BBP]+\b
\*BBP*+\g
</code>```

But none of the above (and many others) don't seem to work.

答:
You may use

```<code>(N_)[^_]*(_c_\d+_n)
</code>```

Replace with ${1}some new value$2.

Details

(N_)  - Group 1 ($1 or ${1} if the next char is a digit): N_

[^_]* - any 0 or more chars other than _
-(_c_\d+_n) - Group 2 ($2): _c_, 1 or more digits and then _n.

See the regex demo.

Title: Using regex replacement in Sublime 3

Body:
I am trying to use replace in Sublime using regular expressions but I'm stuck. I tried various combinations but don't seem to be getting there.

This is the input and my desired output:

Input: N_BBP_c_46137_n

Output : BBP

I tried combinations of:

[^BBP]+\b
\*BBP*+\g

But none of the above (and many others) don't seem to work.

Body:
You may use

(N_)[^_]*(_c_\d+_n)

Replace with ${1}some new value$2.

Details

(N_)  - Group 1 ($1 or ${1} if the next char is a digit): N_

[^_]* - any 0 or more chars other than _
-(_c_\d+_n) - Group 2 ($2): _c_, 1 or more digits and then _n.

See the regex demo.


问:
how to add a sequence column based on index?
I have a dataframe that (simplified) looks something like this:

I would like to create a third column that creates a sequence from 0 and increment of 50 that begins when the StudioEvent = MovieStart and ends when StudioEvent = MovieEnd. So something like this:

Any idea how I can do it? Thank you in advance.

I've been asked to attach the code, but honestly, no idea how to even get started which is why I didn't add code in the first place. I thought I'd need to use some type of loop and perhaps mutate function but I wasn't sure. Here's what I initially thought and obviously was wrong.

```<code>new_data <- data %>%
  group_by(ParticipantName) %>%
  mutate(Index = StudioEvent$MovieStart == 0)
  ungroup() %>%
</code>```

答:
You have to be careful here. If you want a numeric column in a data frame in R, you can't have blank entries like in your example output. They have to be NA values. The alternative, depending on your needs, are to have them stored as character strings.

There are probably neater ways to do this, but here is a method in base R using a for loop and if statements that gets the desired output. Here I'm assuming your data frame is called df:

df$sequence   <- numeric(15)
movie_started <- FALSE

for(i in 1:nrow(df))
{
  if(movie_started) df$sequence[i] <- df$sequence[i - 1] + 50
  if(df$Studio.Event[i] == "MovieStart") movie_started <- TRUE
  if(df$Studio.Event[i] == "MovieEnd")   movie_started <- FALSE
}

df$sequence <- as.character(df$sequence)
df$sequence[df$sequence == "0" & df$Studio.Event != "MovieStart"] <- ""

df
#>    index Studio.Event sequence
#> 1      1
#> 2      2   MovieStart        0
#> 3      3                    50
#> 4      4                   100
#> 5      5                   150
#> 6      6                   200
#> 7      7     MovieEnd      250
#> 8      8
#> 9      9
#> 10    10   MovieStart        0
#> 11    11                    50
#> 12    12                   100
#> 13    13                   150
#> 14    14                   200
#> 15    15     MovieEnd      250
```

<p>If you want the <code>sequence</code> column in numeric format, you can now do:</p>

```df$sequence <- as.numeric(df$sequence)
```

<hr>

<p><strong>Data used</strong></p>

```df <- structure(list(index = 1:15, Studio.Event = c("", "MovieStart",
                "", "", "", "", "MovieEnd", "", "", "MovieStart", "", "", "",
                "", "MovieEnd")), row.names = c(NA, -15L), class = "data.frame")
```

Created on 2020-05-29 by the reprex package (v0.3.0)

Body:
I have a dataframe that (simplified) looks something like this:

I would like to create a third column that creates a sequence from 0 and increment of 50 that begins when the StudioEvent = MovieStart and ends when StudioEvent = MovieEnd. So something like this:

Any idea how I can do it? Thank you in advance.

I've been asked to attach the code, but honestly, no idea how to even get started which is why I didn't add code in the first place. I thought I'd need to use some type of loop and perhaps mutate function but I wasn't sure. Here's what I initially thought and obviously was wrong.

new_data <- data %>%
  group_by(ParticipantName) %>%
  mutate(Index = StudioEvent$MovieStart == 0)
  ungroup() %>%

Body:
You have to be careful here. If you want a numeric column in a data frame in R, you can't have blank entries like in your example output. They have to be NA values. The alternative, depending on your needs, are to have them stored as character strings.

There are probably neater ways to do this, but here is a method in base R using a for loop and if statements that gets the desired output. Here I'm assuming your data frame is called df:

df$sequence   <- numeric(15)
movie_started <- FALSE

for(i in 1:nrow(df))
{
  if(movie_started) df$sequence[i] <- df$sequence[i - 1] + 50
  if(df$Studio.Event[i] == "MovieStart") movie_started <- TRUE
  if(df$Studio.Event[i] == "MovieEnd")   movie_started <- FALSE
}

df$sequence <- as.character(df$sequence)
df$sequence[df$sequence == "0" & df$Studio.Event != "MovieStart"] <- ""

df
#>    index Studio.Event sequence
#> 1      1
#> 2      2   MovieStart        0
#> 3      3                    50
#> 4      4                   100
#> 5      5                   150
#> 6      6                   200
#> 7      7     MovieEnd      250
#> 8      8
#> 9      9
#> 10    10   MovieStart        0
#> 11    11                    50
#> 12    12                   100
#> 13    13                   150
#> 14    14                   200
#> 15    15     MovieEnd      250

If you want the sequence column in numeric format, you can now do:

df$sequence <- as.numeric(df$sequence)

Data used

df <- structure(list(index = 1:15, Studio.Event = c("", "MovieStart",
                "", "", "", "", "MovieEnd", "", "", "MovieStart", "", "", "",
                "", "MovieEnd")), row.names = c(NA, -15L), class = "data.frame")

Created on 2020-05-29 by the reprex package (v0.3.0)


问:
Detect if device is iOS
I'm wondering if it's possible to detect whether a browser is running on iOS, similar to how you can feature detect with Modernizr (although this is obviously device detection rather than feature detection).

Normally I would favour feature detection instead, but I need to find out whether a device is iOS because of the way they handle videos as per this question YouTube API not working with iPad / iPhone / non-Flash device

答:
None of the previous answers here work for all major browsers on all versions of iOS, including iOS 13. Here is a solution that works for Safari, Chrome and Firefox for all iOS versions:

```<code>var isIOS = (function () {
    var iosQuirkPresent = function () {
        var audio = new Audio();

        audio.volume = 0.5;
        return audio.volume === 1;   // volume cannot be changed from "1" on iOS 12 and below
    };

    var isIOS = /iPad|iPhone|iPod/.test(navigator.userAgent);
    var isAppleDevice = navigator.userAgent.includes('Macintosh');
    var isTouchScreen = navigator.maxTouchPoints >= 1;   // true for iOS 13 (and hopefully beyond)

    return isIOS || (isAppleDevice && (isTouchScreen || iosQuirkPresent()));
})();
</code>```

Note that this code snippet was written with priority on readability, not conciseness or performance.

Explanation:

If the user agent contains any of "iPod|iPhone|iPad" then clearly the device is iOS. Otherwise, continue...

Any other user agent that does not contain "Macintosh" is not an Apple device and therefore cannot be iOS. Otherwise, it is an Apple device, so continue...

If maxTouchPoints has a value of 1 or greater then the Apple device has a touch screen and therefore must be iOS since there are no Macs with touch screens (kudos to kikiwora for mentioning maxTouchPoints). Note that maxTouchPoints is undefined for iOS 12 and below, so we need a different solution for that scenario...

iOS 12 and below has a quirk that does not exist in Mac OS. The quirk is that the volume property of an Audio element cannot be successfully set to any value other than 1. This is because Apple does not allow volume changes on the Audio element for iOS devices, but does for Mac OS. That quirk can be used as the final fallback method for distinguishing an iOS device from a Mac OS device.

Title: Detect if device is iOS

Body:
None of the previous answers here work for all major browsers on all versions of iOS, including iOS 13. Here is a solution that works for Safari, Chrome and Firefox for all iOS versions:

var isIOS = (function () {
    var iosQuirkPresent = function () {
        var audio = new Audio();

        audio.volume = 0.5;
        return audio.volume === 1;   // volume cannot be changed from "1" on iOS 12 and below
    };

    var isIOS = /iPad|iPhone|iPod/.test(navigator.userAgent);
    var isAppleDevice = navigator.userAgent.includes('Macintosh');
    var isTouchScreen = navigator.maxTouchPoints >= 1;   // true for iOS 13 (and hopefully beyond)

    return isIOS || (isAppleDevice && (isTouchScreen || iosQuirkPresent()));
})();

Note that this code snippet was written with priority on readability, not conciseness or performance.

Explanation:

If the user agent contains any of "iPod|iPhone|iPad" then clearly the device is iOS. Otherwise, continue...

Any other user agent that does not contain "Macintosh" is not an Apple device and therefore cannot be iOS. Otherwise, it is an Apple device, so continue...

If maxTouchPoints has a value of 1 or greater then the Apple device has a touch screen and therefore must be iOS since there are no Macs with touch screens (kudos to kikiwora for mentioning maxTouchPoints). Note that maxTouchPoints is undefined for iOS 12 and below, so we need a different solution for that scenario...

iOS 12 and below has a quirk that does not exist in Mac OS. The quirk is that the volume property of an Audio element cannot be successfully set to any value other than 1. This is because Apple does not allow volume changes on the Audio element for iOS devices, but does for Mac OS. That quirk can be used as the final fallback method for distinguishing an iOS device from a Mac OS device.


问:
Laravel view with variable, missing required parameters for route
I am losing too much time for (I am sure) a small missing, but I am not able to find it.
Here my issue.

I want to create an open blade, so without authentication, with a variable parameter in the URL.

Here my codes

```<code>// routes/web.php
  Route::get('/{org_id}/tickets/ext/index', array('as' => 'tickets.ext.index', 'uses' => 'Ext\ExtTicketsController@index'));

// Ext\ExtTicketsController
 public function index(Request $request, $org_id)
 {
   //$org_id = 'my_organization';
   //dd(app()->getLocale());
   $locale=substr($request->server('HTTP_ACCEPT_LANGUAGE'), 0, 2);

   return view('tickets/ext/index')
   ->with('org_id',$org_id)
   ->with('locale',$locale);
 }
</code>```

When I try to land on http://localhost/app/public/en/my_organization/tickets/ext/index I get error, for which I don't understand origin:

```<code>Missing required parameters for [Route: tickets.ext.index] [URI: {locale}/{org_id}/tickets/ext/index]
</code>```

I have the blade into views/ticket/ext/index file.

Thanks in advance!

答:
You can simplify your code like this, I hope it'll work</p>

```<code>// routes/web.php
Route::get('/{org_id}/tickets/ext/index', 'Ext\ExtTicketsController@index');

// Ext\ExtTicketsController
public function index($org_id)
{
   $org_id = $org_id';
   $locale=substr($request->server('HTTP_ACCEPT_LANGUAGE'), 0, 2);
   return view('tickets.ext.index',compact('org_id','locale'));
}
</code>```

Body:
I am losing too much time for (I am sure) a small missing, but I am not able to find it.
Here my issue.

I want to create an open blade, so without authentication, with a variable parameter in the URL.

Here my codes

// routes/web.php
  Route::get('/{org_id}/tickets/ext/index', array('as' => 'tickets.ext.index', 'uses' => 'Ext\ExtTicketsController@index'));

// Ext\ExtTicketsController
 public function index(Request $request, $org_id)
 {
   //$org_id = 'my_organization';
   //dd(app()->getLocale());
   $locale=substr($request->server('HTTP_ACCEPT_LANGUAGE'), 0, 2);

   return view('tickets/ext/index')
   ->with('org_id',$org_id)
   ->with('locale',$locale);
 }

When I try to land on http://localhost/app/public/en/my_organization/tickets/ext/index I get error, for which I don't understand origin:

Missing required parameters for [Route: tickets.ext.index] [URI: {locale}/{org_id}/tickets/ext/index]

I have the blade into views/ticket/ext/index file.

Thanks in advance!

Body:
You can simplify your code like this, I hope it'll work

// routes/web.php
Route::get('/{org_id}/tickets/ext/index', 'Ext\ExtTicketsController@index');

// Ext\ExtTicketsController
public function index($org_id)
{
   $org_id = $org_id';
   $locale=substr($request->server('HTTP_ACCEPT_LANGUAGE'), 0, 2);
   return view('tickets.ext.index',compact('org_id','locale'));
}


问:
Problem with trusted authentication in SSRS or any apps that connect to data source
What issues we face when using SSPI/trusted authentication for applications of any kinds that connect to data sources? Is there any alternative to this ... if so could you please specify?

This question has ben asked in one of the interview I attended recently.

Thanks

答:
They probably mean, "What problems can software that calls reporting services have using trusted authentication"; and they're likely referring to the double-hop authentication issue.

If the caller, the report server and the data source are all on different computers, when the caller passes its credentials to the report server, it will have problems passing those credentials onto the data source.

It might also occur in slightly simpler scenarios; I'm not sure because I haven't come across it, though it's very common because it returns a bunch of Google results.

The traditional workaround has been to "use Kerberos authentication", and if you look up the whitepaper you'll find it extremely hard to find clear and simple guidelines on how to implement it. I mean, it's a few hundred pages long, and it's not a How-To.

Apparently there are other ways to get around it using slightly newer versions of Windows (2003+).

But good luck on finding it if you need it. It's really poorly explained and assumes a lot of understanding of Windows authentication internals that only the most hardcore Windows network administrators would understand; let alone us SSRS and DBA folk.


问:
case distinction within octave expression
I would like to use a function that behaves by the following pseudocode:

```<code>f = @(x,y) if x*y > 0 then 1 else 0;
</code>```

How can I implement this in one line in Octave?

Body:
I would like to use a function that behaves by the following pseudocode:

f = @(x,y) if x*y > 0 then 1 else 0;

How can I implement this in one line in Octave?

Body:
Maybe you can try

f = 1*(x*y>0)

or

f = @(x,y) 1*(x*y>0)


问:
Putting several plots side by side
I have 9 histograms made with matplotlib.pyplot.

Is there an easy way to "stick" them to each other, so that every new histogram would not start with a new row?

Data: data

Providing code:

```<code>for column in data:
   plt.figure(figsize=(5,5))

   a1 = data[(data['Outcome'] == 0)][column]
   a2 = data[(data['Outcome'] == 1)][column]

   ax = np.linspace(0, data[column].max(), 50)

   plt.hist(a1, ax, color='blue', alpha=0.6, label='Have Diabetes = NO')
   plt.hist(a2, ax, color='yellow', alpha=0.6, label='Have Diabetes = YES')

   plt.title(f'Histogram for {column}')
   plt.xlabel(f'{column}')
   plt.ylabel('number of people')

   plt.grid(True)
   leg = plt.legend(loc='upper right', frameon=True)
</code>```

What I want is something like this:

I actually don't need it to be 3x3, just not go in a column. Is it possible? Thanks for any possible help.

答:
I think you should be plotting using axes rather than pyplot:

```<code> from matplotlib import pyplot as plt
 fig, axes = plt.subplots(3,3, figsize=(9,9))

 for d, ax in zip(data_list, axes.ravel()):
      ax.hist(d)   # or something similar
</code>```

Title: Putting several plots side by side

Body:
I have 9 histograms made with matplotlib.pyplot.

Is there an easy way to "stick" them to each other, so that every new histogram would not start with a new row?

Data: data

Providing code:

for column in data:
   plt.figure(figsize=(5,5))

   a1 = data[(data['Outcome'] == 0)][column]
   a2 = data[(data['Outcome'] == 1)][column]

   ax = np.linspace(0, data[column].max(), 50)

   plt.hist(a1, ax, color='blue', alpha=0.6, label='Have Diabetes = NO')
   plt.hist(a2, ax, color='yellow', alpha=0.6, label='Have Diabetes = YES')

   plt.title(f'Histogram for {column}')
   plt.xlabel(f'{column}')
   plt.ylabel('number of people')

   plt.grid(True)
   leg = plt.legend(loc='upper right', frameon=True)

What I want is something like this:

I actually don't need it to be 3x3, just not go in a column. Is it possible? Thanks for any possible help.

Body:
I think you should be plotting using axes rather than pyplot:

 from matplotlib import pyplot as plt
 fig, axes = plt.subplots(3,3, figsize=(9,9))

 for d, ax in zip(data_list, axes.ravel()):
      ax.hist(d)   # or something similar


问:
Select with join into custom type
I have entities that look like the following:

@Entity
@Data
@NoArgsConstructor
@AllArgsConstructor
public class MyEntity {
    @Id
    private UUID id;

    @OneToMany(targetEntity = Relation.class, fetch = FetchType.EAGER)
    private List<Relation> relatedList;
}

@Entity
@Data
public class Relation {
    @Id
    private UUID id;
}
```

<p>In addition, I have another type:</p>

<pre class="lang-java prettyprint-override"><code>@Data
public class OtherType extends MyEntity {
    private String otherField;

    public OtherType(UUID id, List<Relation> relations, String otherField) {
        super(id, relations);
        this.otherField = otherField;
    }
}
</code>```

What I want to do now is to select the objects in the table of MyEntity together with some additional info (otherField) into an object of type OtherType:

select e.id, e.relatedList, 'otherStuff' as otherField from MyEntity e
```

If I use this query with HQL, it converts e.relatedList to . as col_x_x_, which obviously is a syntax error. I was trying to use a native query, but that just says that OtherType is not an Entity. If I use a NamedNativeQuery with a resultSetMapping, it can't map a list of values to a Collection (No dialect mapping for JDBC type 1111). What I also tried is use the postgres array_agg function to get only an array of IDs for my relation, but that can't be mapped either. Is there any way to achieve this except defining a constructor in OtherType that accepts a single value instead of a list, doing an actual real SQL join (where every instance of Relation adds another MyEntity row), and mapping that afterwards?

答:
This is a perfect use case for Blaze-Persistence Entity Views.

I created the library to allow easy mapping between JPA models and custom interface or abstract class defined models, something like Spring Data Projections on steroids. The idea is that you define your target structure(domain model) the way you like and map attributes(getters) via JPQL expressions to the entity model. Since the attribute name is used as default mapping, you mostly don't need explicit mappings as 80% of the use cases is to have DTOs that are a subset of the entity model.

The interesting part for you is, that it supports collections. A sample model could look like the following:

```<code>@EntityView(MyEntity.class)
public interface MyEntityView {
    @IdMapping
    UUID getId();
    String getOtherField();
    List<RelationView> getRelations();
}
@EntityView(Relation.class)
public interface RelationView {
    @IdMapping
    UUID getId();
}
</code>```

Querying is a matter of applying the entity view to a query, the simplest being just a query by id.

MyEntityView p = entityViewManager.find(entityManager, MyEntityView.class, id);

The Spring Data integration allows you to use it almost like Spring Data Projections: https://persistence.blazebit.com/documentation/entity-view/manual/en_US/index.html#spring-data-features

Title: Select with join into custom type

Body:
I have entities that look like the following:

@Entity
@Data
@NoArgsConstructor
@AllArgsConstructor
public class MyEntity {
    @Id
    private UUID id;

    @OneToMany(targetEntity = Relation.class, fetch = FetchType.EAGER)
    private List<Relation> relatedList;
}

@Entity
@Data
public class Relation {
    @Id
    private UUID id;
}

In addition, I have another type:

@Data
public class OtherType extends MyEntity {
    private String otherField;

    public OtherType(UUID id, List<Relation> relations, String otherField) {
        super(id, relations);
        this.otherField = otherField;
    }
}

What I want to do now is to select the objects in the table of MyEntity together with some additional info (otherField) into an object of type OtherType:

select e.id, e.relatedList, 'otherStuff' as otherField from MyEntity e

If I use this query with HQL, it converts e.relatedList to . as col_x_x_, which obviously is a syntax error. I was trying to use a native query, but that just says that OtherType is not an Entity. If I use a NamedNativeQuery with a resultSetMapping, it can't map a list of values to a Collection (No dialect mapping for JDBC type 1111). What I also tried is use the postgres array_agg function to get only an array of IDs for my relation, but that can't be mapped either. Is there any way to achieve this except defining a constructor in OtherType that accepts a single value instead of a list, doing an actual real SQL join (where every instance of Relation adds another MyEntity row), and mapping that afterwards?

Body:
This is a perfect use case for Blaze-Persistence Entity Views.

I created the library to allow easy mapping between JPA models and custom interface or abstract class defined models, something like Spring Data Projections on steroids. The idea is that you define your target structure(domain model) the way you like and map attributes(getters) via JPQL expressions to the entity model. Since the attribute name is used as default mapping, you mostly don't need explicit mappings as 80% of the use cases is to have DTOs that are a subset of the entity model.

The interesting part for you is, that it supports collections. A sample model could look like the following:

@EntityView(MyEntity.class)
public interface MyEntityView {
    @IdMapping
    UUID getId();
    String getOtherField();
    List<RelationView> getRelations();
}
@EntityView(Relation.class)
public interface RelationView {
    @IdMapping
    UUID getId();
}

Querying is a matter of applying the entity view to a query, the simplest being just a query by id.

MyEntityView p = entityViewManager.find(entityManager, MyEntityView.class, id);

The Spring Data integration allows you to use it almost like Spring Data Projections: https://persistence.blazebit.com/documentation/entity-view/manual/en_US/index.html#spring-data-features


问:
Sass configuration map with default values
I am creating css using SASS and would like to make it possible for another developer to create a custom css by changing sass variables. This works fine when I in my base file use a single variable like this:

```<code>$text-color: #000 !default;
</code>```

To test the override I create a new project where I first declare an override for the variable and then import the "base" sass file.

```<code>$text-color: #0074b;
@import "base-file";
</code>```

But I would also like to use maps for configuration but then I do not get the override to work. How should I use configuration maps that can be overriden?

```<code>$colors: (text-color: #000, icon-color: #ccc );
</code>```

Adding !default after #000 gives me a compilation error: expected ")", was "!default,")
Adding !default after the ) gives no error but the variables does not get overwritten either.

Any ideas on what I am doing wrong?

答:
Bootstrap has solved this issue as:

```<code>$grays: () !default;
// stylelint-disable-next-line scss/dollar-variable-default
$grays: map-merge(
  (
    "100": $gray-100,
    "200": $gray-200,
    "300": $gray-300,
    "400": $gray-400,
    "500": $gray-500,
    "600": $gray-600,
    "700": $gray-700,
    "800": $gray-800,
    "900": $gray-900
  ),
  $grays
);
</code>```

https://github.com/twbs/bootstrap/blob/v4.1.3/scss/_variables.scss#L23

Body:
I am creating css using SASS and would like to make it possible for another developer to create a custom css by changing sass variables. This works fine when I in my base file use a single variable like this:

$text-color: #000 !default;

To test the override I create a new project where I first declare an override for the variable and then import the "base" sass file.

$text-color: #0074b;
@import "base-file";

But I would also like to use maps for configuration but then I do not get the override to work. How should I use configuration maps that can be overriden?

$colors: (text-color: #000, icon-color: #ccc );

Adding !default after #000 gives me a compilation error: expected ")", was "!default,")
Adding !default after the ) gives no error but the variables does not get overwritten either.

Any ideas on what I am doing wrong?

Body:
Bootstrap has solved this issue as:

$grays: () !default;
// stylelint-disable-next-line scss/dollar-variable-default
$grays: map-merge(
  (
    "100": $gray-100,
    "200": $gray-200,
    "300": $gray-300,
    "400": $gray-400,
    "500": $gray-500,
    "600": $gray-600,
    "700": $gray-700,
    "800": $gray-800,
    "900": $gray-900
  ),
  $grays
);

https://github.com/twbs/bootstrap/blob/v4.1.3/scss/_variables.scss#L23


问:
Convert a call method Cdecl convention to a call method pascal convention
I'm trying to develop some code to make generic calls to methods by it's name.
For example, some one from web send me a text as 'TTest.MethodTest.Param1.Param2', and I find the class and call it method by it's name with the parameters.
Ok, I did this, I got some code from Andreas Hausladen did little adjusts to work where I need. But, the implementation of ExecuteAsyncCall, was create to cdecl functions I need to change it's code to work with pascal convention methods.

Here is the code sample, if some one would like to test.
Some one can help me ? I'm studying to solve this but it's complicated to me.

```<code>unit Unit1;

interface

uses
  Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
  Dialogs, StdCtrls;

type
  TForm1 = class(TForm)
    Button1: TButton;
    procedure Button1Click(Sender: TObject);
  private
    { Private declarations }
  published
    { Public declarations }
    procedure Test(AString: string; AInteger: Integer); cdecl;
  end;

var
  Form1: TForm1;

implementation

{$R *.dfm}

function CopyVarRec(const Data: TVarRec): TVarRec;
begin
  if (Data.VPointer <> nil) and
     (Data.VType in [vtString, vtAnsiString, vtWideString,
                     {$IFDEF UNICODE}vtUnicodeString,{$ENDIF} vtExtended,
                     vtCurrency, vtInt64, vtVariant, vtInterface]) then
  begin
    Result.VType := Data.VType;
    Result.VPointer := nil;
    { Copy and redirect TVarRec data to prevent conflicts with other threads,
      especially the calling thread. Otherwise reference counted types could
      be freed while this asynchron function is still executed. }
    case Result.VType of
      vtAnsiString: AnsiString(Result.VAnsiString) := AnsiString(Data.VAnsiString);
      vtWideString: WideString(Result.VWideString) := WideString(Data.VWideString);
      {$IFDEF UNICODE}
      vtUnicodeString: UnicodeString(Result.VUnicodeString) := UnicodeString(data.VUnicodeString);
      {$ENDIF UNICODE}
      vtInterface : IInterface(Result.VInterface) := IInterface(Data.VInterface);

      vtString    : begin New(Result.VString);   Result.VString^ := Data.VString^; end;
      vtExtended  : begin New(Result.VExtended); Result.VExtended^ := Data.VExtended^; end;
      vtCurrency  : begin New(Result.VCurrency); Result.VCurrency^ := Data.VCurrency^; end;
      vtInt64     : begin New(Result.VInt64);    Result.VInt64^ := Data.VInt64^; end;
      vtVariant   : begin New(Result.VVariant);  Result.VVariant^ := Data.VVariant^; end;
    end;
  end
  else
    Result := Data;
end;

function ExecuteAsyncCall(AProc: Pointer; MethodData: TObject; const AArgs: array of const): Integer;
var
  I: Integer;
  V: ^TVarRec;
  ByteCount: Integer;
  FArgs: array of TVarRec;
  FProc: function: Integer register;
begin
  FProc := AProc;
  SetLength(FArgs, 1 + Length(AArgs));

  // insert "Self"
  FArgs[0].VType := vtObject;
  FArgs[0].VObject := MethodData;

  for I := 0 to High(AArgs) do
    FArgs[I + 1] := CopyVarRec(AArgs[I]);

  ByteCount := Length(FArgs) * SizeOf(Integer) + $40;
  { Create a zero filled buffer for functions that want more arguments than
    specified. }
  asm
    xor eax, eax
    mov ecx, $40 / 8
@@FillBuf:
    push eax
    push eax
//    push eax
    dec ecx
    jnz @@FillBuf
  end;

  for I := High(FArgs) downto 0 do // cdecl => right to left
  begin
    V := @FArgs[I];
    case V.VType of
      vtInteger:     // [const] Arg: Integer
        asm
          mov eax, V
          push [eax].TVarRec.VInteger
        end;

      vtBoolean,     // [const] Arg: Boolean
      vtChar:        // [const] Arg: AnsiChar
        asm
          mov eax, V
          xor edx, edx
          mov dl, [eax].TVarRec.VBoolean
          push edx
        end;

      vtWideChar:    // [const] Arg: WideChar
        asm
          mov eax, V
          xor edx, edx
          mov dx, [eax].TVarRec.VWideChar
          push edx
        end;

      vtExtended:    // [const] Arg: Extended
        asm
          add [ByteCount], 8 // two additional DWORDs
          mov eax, V
          mov edx, [eax].TVarRec.VExtended
          movzx eax, WORD PTR [edx + 8]
          push eax
          push DWORD PTR [edx + 4]
          push DWORD PTR [edx]
        end;

      vtCurrency,    // [const] Arg: Currency
      vtInt64:       // [const] Arg: Int64
        asm
          add [ByteCount], 4 // an additional DWORD
          mov eax, V
          mov edx, [eax].TVarRec.VCurrency
          push DWORD PTR [edx + 4]
          push DWORD PTR [edx]
        end;

      vtString,      // [const] Arg: ShortString
      vtPointer,     // [const] Arg: Pointer
      vtPChar,       // [const] Arg: PChar
      vtObject,      // [const] Arg: TObject
      vtClass,       // [const] Arg: TClass
      vtAnsiString,  // [const] Arg: AnsiString
      {$IFDEF UNICODE}
      vtUnicodeString, // [const] Arg: UnicodeString
      {$ENDIF UNICODE}
      vtPWideChar,   // [const] Arg: PWideChar
      vtVariant,     // const Arg: Variant
      vtInterface,   // [const]: IInterface
      vtWideString:  // [const] Arg: WideString
        asm
          mov eax, V
          push [eax].TVarRec.VPointer
        end;
    end;
  end;

  Result := FProc;

  asm // cdecl => we must clean up
    add esp, [ByteCount]
  end;
end;

procedure TForm1.Button1Click(Sender: TObject);
begin
  ExecuteAsyncCall(Self.MethodAddress('Test'), Self, ['Test ', 1])
end;

procedure TForm1.Test(AString: string; AInteger: Integer);
begin
  ShowMessage(AString +   IntToStr(AInteger));
end;

end.
</code>```

Att.

Obs: I'm working on Delphi 2007

答:
The pascal calling convention passes parameters from left to right, whereas cdecl passes them right to left. To account for that difference, simply reverse the order that the parameters get pushed onto the stack:

<s>

```<code>for I := High(FArgs) downto 0 do // cdecl => right to left
</code>```

</s>

```<code>for I := 0 to High(FArgs) do // pascal => left to right
</code>```

Next, the Self parameter of a method gets passed last instead of first in the pascal convention. The net effect is that in both conventions, Self is the last parameter pushed onto the stack. You can add it to the end of your FArgs array, but if this were my code, I'd just push it manually after the main argument loop (which would also allow omitting the second argument array entirely):

```<code>asm
  push [MethodData]
end;
</code>```

Finally, in the pascal convention, the receiver cleans up the stack, whereas in cdecl, the caller cleans it up. Remove this code:

<s>

```<code>asm // cdecl => we must clean up
  add esp, [ByteCount]
end;
</code>```

</s>

```<code>// pascal => do nothing
</code>```

The code also makes an allowance for calling functions with fewer parameters than the target function expects. It allocates a 40-byte buffer and fills it with zeros. That won't work with a pascal function, though. A pascal function always pops the same number of parameters from the stack, so if you provide the wrong number of parameters when you call it, you'll end up trashing the stack when the function returns. Remove the assembler block below the comment:

<s>

```<code>{ Create a zero filled buffer for functions that want more arguments than
  specified. }
asm
  ...
end;
</code>```

</s>

There's nothing you can do to check whether you've received the correct number of parameters. All you can do is make sure the stack pointer upon return from the function is the same as it was before you started pushing parameters.

Body:
I'm trying to develop some code to make generic calls to methods by it's name.
For example, some one from web send me a text as 'TTest.MethodTest.Param1.Param2', and I find the class and call it method by it's name with the parameters.
Ok, I did this, I got some code from Andreas Hausladen did little adjusts to work where I need. But, the implementation of ExecuteAsyncCall, was create to cdecl functions I need to change it's code to work with pascal convention methods.

Here is the code sample, if some one would like to test.
Some one can help me ? I'm studying to solve this but it's complicated to me.

unit Unit1;

interface

uses
  Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
  Dialogs, StdCtrls;

type
  TForm1 = class(TForm)
    Button1: TButton;
    procedure Button1Click(Sender: TObject);
  private
    { Private declarations }
  published
    { Public declarations }
    procedure Test(AString: string; AInteger: Integer); cdecl;
  end;

var
  Form1: TForm1;

implementation

{$R *.dfm}

function CopyVarRec(const Data: TVarRec): TVarRec;
begin
  if (Data.VPointer <> nil) and
     (Data.VType in [vtString, vtAnsiString, vtWideString,
                     {$IFDEF UNICODE}vtUnicodeString,{$ENDIF} vtExtended,
                     vtCurrency, vtInt64, vtVariant, vtInterface]) then
  begin
    Result.VType := Data.VType;
    Result.VPointer := nil;
    { Copy and redirect TVarRec data to prevent conflicts with other threads,
      especially the calling thread. Otherwise reference counted types could
      be freed while this asynchron function is still executed. }
    case Result.VType of
      vtAnsiString: AnsiString(Result.VAnsiString) := AnsiString(Data.VAnsiString);
      vtWideString: WideString(Result.VWideString) := WideString(Data.VWideString);
      {$IFDEF UNICODE}
      vtUnicodeString: UnicodeString(Result.VUnicodeString) := UnicodeString(data.VUnicodeString);
      {$ENDIF UNICODE}
      vtInterface : IInterface(Result.VInterface) := IInterface(Data.VInterface);

      vtString    : begin New(Result.VString);   Result.VString^ := Data.VString^; end;
      vtExtended  : begin New(Result.VExtended); Result.VExtended^ := Data.VExtended^; end;
      vtCurrency  : begin New(Result.VCurrency); Result.VCurrency^ := Data.VCurrency^; end;
      vtInt64     : begin New(Result.VInt64);    Result.VInt64^ := Data.VInt64^; end;
      vtVariant   : begin New(Result.VVariant);  Result.VVariant^ := Data.VVariant^; end;
    end;
  end
  else
    Result := Data;
end;

function ExecuteAsyncCall(AProc: Pointer; MethodData: TObject; const AArgs: array of const): Integer;
var
  I: Integer;
  V: ^TVarRec;
  ByteCount: Integer;
  FArgs: array of TVarRec;
  FProc: function: Integer register;
begin
  FProc := AProc;
  SetLength(FArgs, 1 + Length(AArgs));

  // insert "Self"
  FArgs[0].VType := vtObject;
  FArgs[0].VObject := MethodData;

  for I := 0 to High(AArgs) do
    FArgs[I + 1] := CopyVarRec(AArgs[I]);

  ByteCount := Length(FArgs) * SizeOf(Integer) + $40;
  { Create a zero filled buffer for functions that want more arguments than
    specified. }
  asm
    xor eax, eax
    mov ecx, $40 / 8
@@FillBuf:
    push eax
    push eax
//    push eax
    dec ecx
    jnz @@FillBuf
  end;

  for I := High(FArgs) downto 0 do // cdecl => right to left
  begin
    V := @FArgs[I];
    case V.VType of
      vtInteger:     // [const] Arg: Integer
        asm
          mov eax, V
          push [eax].TVarRec.VInteger
        end;

      vtBoolean,     // [const] Arg: Boolean
      vtChar:        // [const] Arg: AnsiChar
        asm
          mov eax, V
          xor edx, edx
          mov dl, [eax].TVarRec.VBoolean
          push edx
        end;

      vtWideChar:    // [const] Arg: WideChar
        asm
          mov eax, V
          xor edx, edx
          mov dx, [eax].TVarRec.VWideChar
          push edx
        end;

      vtExtended:    // [const] Arg: Extended
        asm
          add [ByteCount], 8 // two additional DWORDs
          mov eax, V
          mov edx, [eax].TVarRec.VExtended
          movzx eax, WORD PTR [edx + 8]
          push eax
          push DWORD PTR [edx + 4]
          push DWORD PTR [edx]
        end;

      vtCurrency,    // [const] Arg: Currency
      vtInt64:       // [const] Arg: Int64
        asm
          add [ByteCount], 4 // an additional DWORD
          mov eax, V
          mov edx, [eax].TVarRec.VCurrency
          push DWORD PTR [edx + 4]
          push DWORD PTR [edx]
        end;

      vtString,      // [const] Arg: ShortString
      vtPointer,     // [const] Arg: Pointer
      vtPChar,       // [const] Arg: PChar
      vtObject,      // [const] Arg: TObject
      vtClass,       // [const] Arg: TClass
      vtAnsiString,  // [const] Arg: AnsiString
      {$IFDEF UNICODE}
      vtUnicodeString, // [const] Arg: UnicodeString
      {$ENDIF UNICODE}
      vtPWideChar,   // [const] Arg: PWideChar
      vtVariant,     // const Arg: Variant
      vtInterface,   // [const]: IInterface
      vtWideString:  // [const] Arg: WideString
        asm
          mov eax, V
          push [eax].TVarRec.VPointer
        end;
    end;
  end;

  Result := FProc;

  asm // cdecl => we must clean up
    add esp, [ByteCount]
  end;
end;

procedure TForm1.Button1Click(Sender: TObject);
begin
  ExecuteAsyncCall(Self.MethodAddress('Test'), Self, ['Test ', 1])
end;

procedure TForm1.Test(AString: string; AInteger: Integer);
begin
  ShowMessage(AString +   IntToStr(AInteger));
end;

end.

Att.

Obs: I'm working on Delphi 2007

Body:
The pascal calling convention passes parameters from left to right, whereas cdecl passes them right to left. To account for that difference, simply reverse the order that the parameters get pushed onto the stack:

<s>

for I := High(FArgs) downto 0 do // cdecl => right to left

</s>

for I := 0 to High(FArgs) do // pascal => left to right

Next, the Self parameter of a method gets passed last instead of first in the pascal convention. The net effect is that in both conventions, Self is the last parameter pushed onto the stack. You can add it to the end of your FArgs array, but if this were my code, I'd just push it manually after the main argument loop (which would also allow omitting the second argument array entirely):

asm
  push [MethodData]
end;

Finally, in the pascal convention, the receiver cleans up the stack, whereas in cdecl, the caller cleans it up. Remove this code:

<s>

asm // cdecl => we must clean up
  add esp, [ByteCount]
end;

</s>

// pascal => do nothing

The code also makes an allowance for calling functions with fewer parameters than the target function expects. It allocates a 40-byte buffer and fills it with zeros. That won't work with a pascal function, though. A pascal function always pops the same number of parameters from the stack, so if you provide the wrong number of parameters when you call it, you'll end up trashing the stack when the function returns. Remove the assembler block below the comment:

<s>

{ Create a zero filled buffer for functions that want more arguments than
  specified. }
asm
  ...
end;

</s>

There's nothing you can do to check whether you've received the correct number of parameters. All you can do is make sure the stack pointer upon return from the function is the same as it was before you started pushing parameters.


问:
why custom allocator for std::string does not work
I define a new allocator like this:

```<code>template <class T>
class CodecAlloc: public std::allocator<T> {
public:
  typedef size_t    size_type;
  typedef ptrdiff_t difference_type;
  typedef T*        pointer;
  typedef const T*  const_pointer;
  typedef T&        reference;
  typedef const T&  const_reference;
  typedef T         value_type;

  CodecAlloc() {}
  CodecAlloc(const CodecAlloc&) {}

  pointer allocate(size_type n, const void * = 0) {
              T* t = (T*) malloc(n * sizeof(T));
              std::cout
              << "  used CodecAlloc to allocate   at address "
              << t << " (+)" << std::endl;
              return t;
            }

  void deallocate(void* p, size_type) {
              if (p) {
                free(p);
                std::cout
                << "  used CodecAlloc to deallocate at address "
                << p << " (-)" <<
                std::endl;
              }
            }

  template <class U>
  struct rebind { typedef CodecAlloc<U> other; };
};
</code>```

if I typedef a new type:

```<code>typedef std::basic_string<char, std::char_traits<char>, CodecAlloc<char>> String;
</code>```

it work well，CodecAlloc::allocate has been called.  but now there is a interface like this:

```<code>void SetBinary(const std::string&)
</code>```

it's parameter is a std::string, the type String does not match. So I use this way to construct std::string

```<code>std::string str = std::string("Hello !!", CodecAlloc<char>);
SetBinary(str)
</code>```

but the CodecAlloc allocator does not been called!! why? and how should i solve this problem. the SetBinary interface can not be changed. thks

答:
I have bad news for you.

The other answers already covered this nicely, but I wanted to be more explicit about this: you will not be able to use this interface with a string that uses a custom allocator. Or with any other kind of string, for that matter.

To understand why, you need to know what std::string is. If you look for "string" on cppreference, you'll be directed to the page for std::basic_string. This is intentional, std::basic_string is a template that defines a collection of string classes, and std::string is one of them.

If you look at the definition of std::string, you'll see that it is defined as std::basic_string<char>, which is a shortcut for std::basic_string<char, std::char_traits<char>, std::allocator<char>>. This means that std::string already comes embedded with its own allocator, which is not extensible: the member functions std::allocator<T>::allocate and std::allocator<T>::deallocate are not virtual. Assuming you wanted to use this constructor from std::basic_string:

```<code>basic_string( const CharT* s, const Allocator& alloc = Allocator() );
</code>```

... that means that even if the constructor is using a reference to the allocator, these functions (allocate and deallocate) will not be overridden: the constructor doesn't even know about your version of them. Instead, it will use the versions from the base class.

Body:
I define a new allocator like this:

template <class T>
class CodecAlloc: public std::allocator<T> {
public:
  typedef size_t    size_type;
  typedef ptrdiff_t difference_type;
  typedef T*        pointer;
  typedef const T*  const_pointer;
  typedef T&        reference;
  typedef const T&  const_reference;
  typedef T         value_type;

  CodecAlloc() {}
  CodecAlloc(const CodecAlloc&) {}

  pointer allocate(size_type n, const void * = 0) {
              T* t = (T*) malloc(n * sizeof(T));
              std::cout
              << "  used CodecAlloc to allocate   at address "
              << t << " (+)" << std::endl;
              return t;
            }

  void deallocate(void* p, size_type) {
              if (p) {
                free(p);
                std::cout
                << "  used CodecAlloc to deallocate at address "
                << p << " (-)" <<
                std::endl;
              }
            }

  template <class U>
  struct rebind { typedef CodecAlloc other; };
};

if I typedef a new type:

typedef std::basic_string<char, std::char_traits<char>, CodecAlloc<char>> String;

it work well，CodecAlloc::allocate has been called.  but now there is a interface like this:

void SetBinary(const std::string&)

it's parameter is a std::string, the type String does not match. So I use this way to construct std::string

std::string str = std::string("Hello !!", CodecAlloc<char>);
SetBinary(str)

but the CodecAlloc allocator does not been called!! why? and how should i solve this problem. the SetBinary interface can not be changed. thks

Body:
I have bad news for you.

The other answers already covered this nicely, but I wanted to be more explicit about this: you will not be able to use this interface with a string that uses a custom allocator. Or with any other kind of string, for that matter.

To understand why, you need to know what std::string is. If you look for "string" on cppreference, you'll be directed to the page for std::basic_string. This is intentional, std::basic_string is a template that defines a collection of string classes, and std::string is one of them.

If you look at the definition of std::string, you'll see that it is defined as std::basic_string<char>, which is a shortcut for std::basic_string<char, std::char_traits<char>, std::allocator<char>>. This means that std::string already comes embedded with its own allocator, which is not extensible: the member functions std::allocator<T>::allocate and std::allocator<T>::deallocate are not virtual. Assuming you wanted to use this constructor from std::basic_string:

basic_string( const CharT* s, const Allocator& alloc = Allocator() );

... that means that even if the constructor is using a reference to the allocator, these functions (allocate and deallocate) will not be overridden: the constructor doesn't even know about your version of them. Instead, it will use the versions from the base class.


问:
Flutter Dart Bottomsheet error context = context
I hope somebody can help me solve this error;
I used this showModalBottomSheet Widget already, and just tried to implement the structure onto a new site. The error I get and just don't understand in the BottomSheet has something to do with " context = context, " . Do I have to iplement the void funktion somwhere else or should I create a new class that is extending the Header class? Can somebody please help me?</p>

```<code>class Home extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return Scaffold(
      resizeToAvoidBottomPadding: false,
      body: ListView(
        children: <Widget>[
          Header(),
          //SelectOption(),
          //Chats(),
          //MoodsDetector(),
          //NextUp(),
          //PostFeed(),
        ],
      ),
    );
  }
}

class Header extends StatelessWidget {
  const Header({
    Key key,
  }) : super(key: key);

  @override
  Widget build(BuildContext context) {
    return Container(
      padding: EdgeInsets.fromLTRB(25, 50, 50, 25),
      child: Row(
        mainAxisAlignment: MainAxisAlignment.spaceBetween,
        children: <Widget>[
          Column(
            crossAxisAlignment: CrossAxisAlignment.start,
            children: <Widget>[
              Text(
                'Welcome back,',
                style: TextStyle(color: secondColor, fontSize: 20),
              ),
              Text(
                'Henri',
                style: TextStyle(color: mainColor, fontSize: 30),
              ),
            ],
          ),
          Container(
            width: 50,
            height: 50,
            decoration: BoxDecoration(
              shape: BoxShape.circle,
              color: Colors.white,
              boxShadow: [
                BoxShadow(color: secondColor.withOpacity(0.5), blurRadius: 20),
              ],
            ),
            child: new IconButton(
              icon: new Icon(Icons.search),
              highlightColor: Colors.pink,
              onPressed: _showSearch,
            ),
          ),
        ],
      ),
    );
  }

  void _showSearch(){
    showModalBottomSheet(
        backgroundColor: Colors.white,
        shape: RoundedRectangleBorder(
            borderRadius: BorderRadius.only(topRight: Radius.circular(30.0),topLeft: Radius.circular(30.0))
        ),
        isScrollControlled: true,
        isDismissible: true,
        context: context,
        builder: (builder) {
          return SingleChildScrollView(
            child: Column(
              children: <Widget>[
                Stack(
                  children: <Widget>[
                    SingleChildScrollView(
                      padding: const EdgeInsets.all(15.0),
                      child: Column(
                        crossAxisAlignment: CrossAxisAlignment.start,
                        children: <Widget>[
                          Card(
                            elevation: 8.0,
                            shape: RoundedRectangleBorder(
                                borderRadius: BorderRadius.circular(10.0)),
                            color: Colors.green,
                            child: ListTile(
                              onTap: () {
                                //open edit profile
                              },
                              title: Text(
                                "Rate your Friendship",
                                style: TextStyle(
                                  color: Colors.white,
                                  fontWeight: FontWeight.w500,
                                ),
                              ),
                              leading: CircleAvatar(
                                backgroundImage: AssetImage("assets/images/HenriKlein.jpeg"),
                              ),
                              trailing: Icon(
                                Icons.star,
                                color: Colors.white,
                              ),
                            ),
                          ),
                          const SizedBox(height:10.0),
                          Card(
                            elevation: 4.0,
                            margin: const EdgeInsets.fromLTRB(32.0, 8.0, 32.0, 16.0),
                            shape: RoundedRectangleBorder(
                                borderRadius: BorderRadius.circular(10.0)),
                            child: Column(
                              children: <Widget>[
                                ListTile(
                                  leading: Icon(
                                    Icons.people_outline,
                                    color: Colors.lightGreen,
                                  ),
                                  title: Text("Invite to event"),
                                  trailing: Icon(Icons.keyboard_arrow_right),
                                  onTap: () {

                                  },
                                ),
                                sizedBox,
                                ListTile(
                                  leading: Icon(
                                    Icons.directions_run,
                                    color: Colors.lightGreen,
                                  ),
                                  title: Text("Challange Henri"),
                                  trailing: Icon(Icons.keyboard_arrow_right),
                                  onTap: () {},
                                ),
                                sizedBox,
                                ListTile(
                                  leading: Icon(
                                    Icons.phone_iphone,
                                    color: Colors.lightGreen,
                                  ),
                                  title: Text("Text/Call Henri"),
                                  trailing: Icon(Icons.keyboard_arrow_right),
                                  onTap: () { },
                                ),

                                sizedBox,
                                ListTile(
                                  leading: Icon(
                                    Icons.lock_outline,
                                    color: Colors.lightGreen,
                                  ),
                                  title: Text("Delete Friend"),
                                  trailing: Icon(Icons.keyboard_arrow_right),
                                  onTap: () {},
                                ),

                              ],
                            ),
                          ),
                          const SizedBox(height: 5.0),

                          Center(
                            child: Text(
                              "Friens since 09/20/2019",
                              style: TextStyle(
                                fontSize: 15.0,

                              ),
                              textAlign: TextAlign.center,
                            ),
                          ),
                          SizedBox(height: 20.0),
                          Container(
                            height: 40.0,
                            child: GestureDetector(
                              onTap: () {
                              },
                              child: Material(
                                borderRadius: BorderRadius.circular(50.0),
                                shadowColor: Colors.black,
                                color: Colors.green,
                                elevation: 7.0,
                                child: Center(
                                  child: Text(
                                    '27 mutural friends',                                                                       //Login Button
                                    style: TextStyle(
                                        color: Colors.white,
                                        fontWeight: FontWeight.bold,
                                        fontFamily: 'Montserrat'),
                                  ),
                                ),
                              ),
                            ),
                          ),
                        ],
                      ),
                    ),
                  ],
                ),

              ],
            ),
          );
        });
  }
}

</code>```

答:
You are getting the error because context is not defined in _showSearch.

You should modify the function definition and add context as a parameter as follows:

```<code>void _showSearch(BuildContext context) {
...
</code>```

And when you are calling, you must pass context of the widget from where you are calling it, as follows:

```<code>child: new IconButton(
  icon: new Icon(Icons.search),
  highlightColor: Colors.pink,
  onPressed: () {
    _showSearch(context); //here
  },
),
</code>```

Body:
I hope somebody can help me solve this error;
I used this showModalBottomSheet Widget already, and just tried to implement the structure onto a new site. The error I get and just don't understand in the BottomSheet has something to do with " context = context, " . Do I have to iplement the void funktion somwhere else or should I create a new class that is extending the Header class? Can somebody please help me?

class Home extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return Scaffold(
      resizeToAvoidBottomPadding: false,
      body: ListView(
        children: <Widget>[
          Header(),
          //SelectOption(),
          //Chats(),
          //MoodsDetector(),
          //NextUp(),
          //PostFeed(),
        ],
      ),
    );
  }
}

class Header extends StatelessWidget {
  const Header({
    Key key,
  }) : super(key: key);

  @override
  Widget build(BuildContext context) {
    return Container(
      padding: EdgeInsets.fromLTRB(25, 50, 50, 25),
      child: Row(
        mainAxisAlignment: MainAxisAlignment.spaceBetween,
        children: <Widget>[
          Column(
            crossAxisAlignment: CrossAxisAlignment.start,
            children: <Widget>[
              Text(
                'Welcome back,',
                style: TextStyle(color: secondColor, fontSize: 20),
              ),
              Text(
                'Henri',
                style: TextStyle(color: mainColor, fontSize: 30),
              ),
            ],
          ),
          Container(
            width: 50,
            height: 50,
            decoration: BoxDecoration(
              shape: BoxShape.circle,
              color: Colors.white,
              boxShadow: [
                BoxShadow(color: secondColor.withOpacity(0.5), blurRadius: 20),
              ],
            ),
            child: new IconButton(
              icon: new Icon(Icons.search),
              highlightColor: Colors.pink,
              onPressed: _showSearch,
            ),
          ),
        ],
      ),
    );
  }

  void _showSearch(){
    showModalBottomSheet(
        backgroundColor: Colors.white,
        shape: RoundedRectangleBorder(
            borderRadius: BorderRadius.only(topRight: Radius.circular(30.0),topLeft: Radius.circular(30.0))
        ),
        isScrollControlled: true,
        isDismissible: true,
        context: context,
        builder: (builder) {
          return SingleChildScrollView(
            child: Column(
              children: <Widget>[
                Stack(
                  children: <Widget>[
                    SingleChildScrollView(
                      padding: const EdgeInsets.all(15.0),
                      child: Column(
                        crossAxisAlignment: CrossAxisAlignment.start,
                        children: <Widget>[
                          Card(
                            elevation: 8.0,
                            shape: RoundedRectangleBorder(
                                borderRadius: BorderRadius.circular(10.0)),
                            color: Colors.green,
                            child: ListTile(
                              onTap: () {
                                //open edit profile
                              },
                              title: Text(
                                "Rate your Friendship",
                                style: TextStyle(
                                  color: Colors.white,
                                  fontWeight: FontWeight.w500,
                                ),
                              ),
                              leading: CircleAvatar(
                                backgroundImage: AssetImage("assets/images/HenriKlein.jpeg"),
                              ),
                              trailing: Icon(
                                Icons.star,
                                color: Colors.white,
                              ),
                            ),
                          ),
                          const SizedBox(height:10.0),
                          Card(
                            elevation: 4.0,
                            margin: const EdgeInsets.fromLTRB(32.0, 8.0, 32.0, 16.0),
                            shape: RoundedRectangleBorder(
                                borderRadius: BorderRadius.circular(10.0)),
                            child: Column(
                              children: <Widget>[
                                ListTile(
                                  leading: Icon(
                                    Icons.people_outline,
                                    color: Colors.lightGreen,
                                  ),
                                  title: Text("Invite to event"),
                                  trailing: Icon(Icons.keyboard_arrow_right),
                                  onTap: () {

                                  },
                                ),
                                sizedBox,
                                ListTile(
                                  leading: Icon(
                                    Icons.directions_run,
                                    color: Colors.lightGreen,
                                  ),
                                  title: Text("Challange Henri"),
                                  trailing: Icon(Icons.keyboard_arrow_right),
                                  onTap: () {},
                                ),
                                sizedBox,
                                ListTile(
                                  leading: Icon(
                                    Icons.phone_iphone,
                                    color: Colors.lightGreen,
                                  ),
                                  title: Text("Text/Call Henri"),
                                  trailing: Icon(Icons.keyboard_arrow_right),
                                  onTap: () { },
                                ),

                                sizedBox,
                                ListTile(
                                  leading: Icon(
                                    Icons.lock_outline,
                                    color: Colors.lightGreen,
                                  ),
                                  title: Text("Delete Friend"),
                                  trailing: Icon(Icons.keyboard_arrow_right),
                                  onTap: () {},
                                ),

                              ],
                            ),
                          ),
                          const SizedBox(height: 5.0),

                          Center(
                            child: Text(
                              "Friens since 09/20/2019",
                              style: TextStyle(
                                fontSize: 15.0,

                              ),
                              textAlign: TextAlign.center,
                            ),
                          ),
                          SizedBox(height: 20.0),
                          Container(
                            height: 40.0,
                            child: GestureDetector(
                              onTap: () {
                              },
                              child: Material(
                                borderRadius: BorderRadius.circular(50.0),
                                shadowColor: Colors.black,
                                color: Colors.green,
                                elevation: 7.0,
                                child: Center(
                                  child: Text(
                                    '27 mutural friends',                                                                       //Login Button
                                    style: TextStyle(
                                        color: Colors.white,
                                        fontWeight: FontWeight.bold,
                                        fontFamily: 'Montserrat'),
                                  ),
                                ),
                              ),
                            ),
                          ),
                        ],
                      ),
                    ),
                  ],
                ),

              ],
            ),
          );
        });
  }
}

Body:
You are getting the error because context is not defined in _showSearch.

You should modify the function definition and add context as a parameter as follows:

void _showSearch(BuildContext context) {
...

And when you are calling, you must pass context of the widget from where you are calling it, as follows:

child: new IconButton(
  icon: new Icon(Icons.search),
  highlightColor: Colors.pink,
  onPressed: () {
    _showSearch(context); //here
  },
),


问:
How to save output of for loop to list in python?
```<code>allpkts = []
for i in range(10):
        s[IP].len = i
        del s[IP].chksum
        del s[UDP].chksum
        allpkts.append(s)
print allpkts
</code>```

Here in my allpkts list I am seeing only last number output.
i want all the packets 0 to 9 in allpkts.

答:
You need to make a copy of s in each iteration. Otherwise you're repeatedly modifying the same packet, not putting different packets in the list.

```<code>allpkts = []
for i in range(10):
    stemp = s.copy()
    stemp[IP].len = i
    del stemp[IP].chksum
    del stemp[UDP].chksum
    allpkts.append(stemp)
print allpkts
</code>```

Body:
allpkts = []
for i in range(10):
        s[IP].len = i
        del s[IP].chksum
        del s[UDP].chksum
        allpkts.append(s)
print allpkts

Here in my allpkts list I am seeing only last number output.
i want all the packets 0 to 9 in allpkts.

Body:
You need to make a copy of s in each iteration. Otherwise you're repeatedly modifying the same packet, not putting different packets in the list.

allpkts = []
for i in range(10):
    stemp = s.copy()
    stemp[IP].len = i
    del stemp[IP].chksum
    del stemp[UDP].chksum
    allpkts.append(stemp)
print allpkts


问:
Variable suddenly changes for no apparent reason when function is called
The variable indexMax changes to 3 regardless of the original value of indexMax, for no apparent reason when the function fibonacciGenerator is called.

And when I try to get the size of the array it outputs 2.

```<code>int fibonacciGeneator(int arr[], int n_1, int n_2, int counter, int index){
    int x = counter;
    x--;
    int n = n_1+n_2;

    if(x > 0){
        arr[index] = n;
        return fibonacciGeneator(arr,n,n_1,x,index+1);
    }
    else{
        return arr[index] = n;
    }
}

int main()
{
    int numArr[] = {1,1};
    int indexMax = 5;

    cout << "Index: " << indexMax << endl;              // The variable indexMax changes value for no apparent reason.
    fibonacciGeneator(numArr,1,1,indexMax,2);
    cout << "Index: " << indexMax << endl;

    for(int i = 0; i < indexMax+2; i++){
        cout << numArr[i] << endl;
    }

    int arrSize = sizeof(numArr)/sizeof(numArr[0]); // Outputs 2 which might be due to the original array length of 2.
    cout << arrSize;

    return 0;
}

</code>```

答:
int numArr[] = {1,1}; creates an array of two integers (it's type is literally int[2]) and it is absolutely impossible to resize it. Writing to index [2] is writing past the end of the array, which is illegal and undefined behavior. Anything can happen. It might overwrite variables, it might work, it might crash, it might erase your personal files, and it might switch which of these it does each time it runs.

Prefer to use std::vector<int>, which is resizable, via the resize(...) method. You'll also want to pass this by reference, so that each function call modifies the same instance, instead of making copies and each modifying their own local copy.

Body:
The variable indexMax changes to 3 regardless of the original value of indexMax, for no apparent reason when the function fibonacciGenerator is called.

And when I try to get the size of the array it outputs 2.

int fibonacciGeneator(int arr[], int n_1, int n_2, int counter, int index){
    int x = counter;
    x--;
    int n = n_1+n_2;

    if(x > 0){
        arr[index] = n;
        return fibonacciGeneator(arr,n,n_1,x,index+1);
    }
    else{
        return arr[index] = n;
    }
}

int main()
{
    int numArr[] = {1,1};
    int indexMax = 5;

    cout << "Index: " << indexMax << endl;              // The variable indexMax changes value for no apparent reason.
    fibonacciGeneator(numArr,1,1,indexMax,2);
    cout << "Index: " << indexMax << endl;

    for(int i = 0; i < indexMax+2; i++){
        cout << numArr[i] << endl;
    }

    int arrSize = sizeof(numArr)/sizeof(numArr[0]); // Outputs 2 which might be due to the original array length of 2.
    cout << arrSize;

    return 0;
}


问:
how do I send (put) multiple files using nodejs ssh2-sftp-client?
If I try more then 10 files I got the warning, but the other files are not uploaded, I cannot upload more than 10 files. What am I doing wrong?

{ node:17472) MaxListenersExceededWarning: Possible EventEmitter
  memory leak detected. 11 ready listeners added. Use
  emitter.setMaxListeners() to increase limit (node:17472)
  MaxListenersExceededWarning: Possible EventEmitter memory leak
  detected. 11 error listeners added. Use emitter.setMaxListeners() to
  increase limit (node:17472) MaxListenersExceededWarning: Possible
  EventEmitter memory leak detected. 11 close listeners added. Use
  emitter.setMaxListeners() to increase limit }

```<code> let Client = require('ssh2-sftp-client');
    let sftp = new Client();
    var promises = [];
    for(var i=0; i < 12; i++) {
        promises.push(sendFile(sftp, req.body, results.romlist[i].filename));
    }
    Promise.all(promises).then(function() {
        sftp.end();
        res.send('{"message":"OK"}');
    });
      const sendFile = (sftp, config, filename) => {
console.log(filename);
return sftp.connect(config).then(() => {
    return sftp.put(filename, "/home/pi/RetroPie/roms/atari2600/" + filename.substr(filename.lastIndexOf('/')+1));
}).catch((err) => {
    console.log(err, 'catch error');
});};
</code>```

答:
This worked for me:
https://github.com/theophilusx/ssh2-sftp-client/issues/73</p>

```<code>const putFiles = (sftpConfig, fileList) => {
  const sftp = new sftpClient()
  return new Promise(function(resolve, reject) {
    sftp
    .connect(sftpConfig)
    .then(() => {
      return Promise.all(fileList.map(args => {
        return sftp.put.apply(sftp, args)
      }))
    })
    .then(() => sftp.end())
    .then(resolve)
    .catch(reject)
  });
}
</code>```

Body:
If I try more then 10 files I got the warning, but the other files are not uploaded, I cannot upload more than 10 files. What am I doing wrong?

{ node:17472) MaxListenersExceededWarning: Possible EventEmitter
  memory leak detected. 11 ready listeners added. Use
  emitter.setMaxListeners() to increase limit (node:17472)
  MaxListenersExceededWarning: Possible EventEmitter memory leak
  detected. 11 error listeners added. Use emitter.setMaxListeners() to
  increase limit (node:17472) MaxListenersExceededWarning: Possible
  EventEmitter memory leak detected. 11 close listeners added. Use
  emitter.setMaxListeners() to increase limit }

 let Client = require('ssh2-sftp-client');
    let sftp = new Client();
    var promises = [];
    for(var i=0; i < 12; i++) {
        promises.push(sendFile(sftp, req.body, results.romlist[i].filename));
    }
    Promise.all(promises).then(function() {
        sftp.end();
        res.send('{"message":"OK"}');
    });
      const sendFile = (sftp, config, filename) => {
console.log(filename);
return sftp.connect(config).then(() => {
    return sftp.put(filename, "/home/pi/RetroPie/roms/atari2600/" + filename.substr(filename.lastIndexOf('/')+1));
}).catch((err) => {
    console.log(err, 'catch error');
});};

Body:
This worked for me:
https://github.com/theophilusx/ssh2-sftp-client/issues/73

const putFiles = (sftpConfig, fileList) => {
  const sftp = new sftpClient()
  return new Promise(function(resolve, reject) {
    sftp
    .connect(sftpConfig)
    .then(() => {
      return Promise.all(fileList.map(args => {
        return sftp.put.apply(sftp, args)
      }))
    })
    .then(() => sftp.end())
    .then(resolve)
    .catch(reject)
  });
}