问:
DynamicSQL Split function to add criteria from comma delimited string not working
I'm trying to use a split function to add a range of values to a query. I'd also like to 'OR' the values together but first things first. I'm following an example I have found in a much larger query that uses the split function, so I've made a small query to try to figure out how it works. So far though, all I get is the error *"The name 'Select * from Country As sp  WHERE (sp.CountryID in (SELECT [Value] FROM dbo.Split('2,22,', ',')))' is not a valid identifier."* I'm knew to DynamicSQL and I'm not quite sure how this split function is supposed to work.

```<code>DECLARE @Countries varchar(MAX);
DECLARE @FiltersOn bit;
DECLARE @Country int;
DECLARE @Query  varchar(MAX);

Set @FiltersOn = 0;
Set @Query = 'Select * from Country As sp ';
Set @Countries ='2,22,'

        IF ( @Countries IS NOT NULL )
            BEGIN
                IF ( @FiltersOn = 1 )
                    BEGIN
                        SET @Query = @Query + ' AND '
                    END
                ELSE
                    BEGIN
                        SET @Query = @Query + ' WHERE '
                        SET @FiltersOn = 1
                    END

                SET @Query = @Query
                    + '(sp.CountryID in (SELECT [Value] FROM dbo.Split('''
                    + @Countries + ''', '','')))'
            END

            EXEC @Query
</code>```

This is the definition of the Country table:

```<code>CREATE TABLE [dbo].[Country](
    [CountryID] [int] IDENTITY(1,1) NOT NULL,
    [AgentID] [int] NULL,
    [Name] [varchar](50) NULL,
    [CountryLookupID] [int] NOT NULL
</code>```

and this is the split function code:

```<code>CREATE FUNCTION [dbo].[Split]
(
    @String varchar(8000),
    @Delimiter varchar(10)
)
RETURNS @ValueTable table ([Value] varchar(255))

BEGIN
    DECLARE @NextString varchar(4000)
    DECLARE @Pos int
    DECLARE @NextPos int
    DECLARE @DelimiterCheck varchar(1)

    -- initialise
    SET @NextString = ''
    SET @DelimiterCheck = RIGHT(@String, 1)

    -- add trailing delimiter
    IF (@DelimiterCheck <> @Delimiter)
        SET @String = @String + @Delimiter

    -- find position of first delimiter
    SET @Pos = CHARINDEX(@Delimiter, @String)
    SET @NextPos = 1

    -- loop while there is a delimiter in the string
    WHILE (@Pos <> 0)
    BEGIN
        SET @NextString = SUBSTRING(@String, 1, @Pos - 1)

        INSERT INTO @ValueTable ([Value]) VALUES (@NextString)

        SET @String = SUBSTRING(@String, @Pos + 1, LEN(@String))

        SET @NextPos = @Pos
        SET @Pos = CHARINDEX(@Delimiter, @String)
    END

    RETURN
END
</code>```

答:
You are not writing EXEC statement correctly.

use EXEC (@Query) instead of EXEC @Query

Body:
I'm trying to use a split function to add a range of values to a query. I'd also like to 'OR' the values together but first things first. I'm following an example I have found in a much larger query that uses the split function, so I've made a small query to try to figure out how it works. So far though, all I get is the error *"The name 'Select * from Country As sp  WHERE (sp.CountryID in (SELECT [Value] FROM dbo.Split('2,22,', ',')))' is not a valid identifier."* I'm knew to DynamicSQL and I'm not quite sure how this split function is supposed to work.

DECLARE @Countries varchar(MAX);
DECLARE @FiltersOn bit;
DECLARE @Country int;
DECLARE @Query  varchar(MAX);

Set @FiltersOn = 0;
Set @Query = 'Select * from Country As sp ';
Set @Countries ='2,22,'

        IF ( @Countries IS NOT NULL )
            BEGIN
                IF ( @FiltersOn = 1 )
                    BEGIN
                        SET @Query = @Query + ' AND '
                    END
                ELSE
                    BEGIN
                        SET @Query = @Query + ' WHERE '
                        SET @FiltersOn = 1
                    END

                SET @Query = @Query
                    + '(sp.CountryID in (SELECT [Value] FROM dbo.Split('''
                    + @Countries + ''', '','')))'
            END

            EXEC @Query

This is the definition of the Country table:

CREATE TABLE [dbo].[Country](
    [CountryID] [int] IDENTITY(1,1) NOT NULL,
    [AgentID] [int] NULL,
    [Name] [varchar](50) NULL,
    [CountryLookupID] [int] NOT NULL

and this is the split function code:

CREATE FUNCTION [dbo].[Split]
(
    @String varchar(8000),
    @Delimiter varchar(10)
)
RETURNS @ValueTable table ([Value] varchar(255))

BEGIN
    DECLARE @NextString varchar(4000)
    DECLARE @Pos int
    DECLARE @NextPos int
    DECLARE @DelimiterCheck varchar(1)

    -- initialise
    SET @NextString = ''
    SET @DelimiterCheck = RIGHT(@String, 1)

    -- add trailing delimiter
    IF (@DelimiterCheck <> @Delimiter)
        SET @String = @String + @Delimiter

    -- find position of first delimiter
    SET @Pos = CHARINDEX(@Delimiter, @String)
    SET @NextPos = 1

    -- loop while there is a delimiter in the string
    WHILE (@Pos <> 0)
    BEGIN
        SET @NextString = SUBSTRING(@String, 1, @Pos - 1)

        INSERT INTO @ValueTable ([Value]) VALUES (@NextString)

        SET @String = SUBSTRING(@String, @Pos + 1, LEN(@String))

        SET @NextPos = @Pos
        SET @Pos = CHARINDEX(@Delimiter, @String)
    END

    RETURN
END


来源: stackexchange

问:
Update two tables with one query
I have two tables, Dtable d and Rtable r. I want to update both tables with one query (important!) in the following order: first setting all Dtable matching row values with a value from Rtable. Then - changing the value from Rtable. In Rtable there will always be a record that matches a key, but in Dtable there can be 0,1 or many records that matches the key. I came up with the following select:

```<code>UPDATE Dtable d, Rtable r

SET
    d.value = r.value,
    r.value = 0
WHERE
    d.key = 403 AND d.value = 0 AND r.id = 403
</code>```

But the problem here is that if I have multiple records in Dtable that match the key, only first one gets updated with value from Rtable, then the value of Rtable changes, and second row from Dtable already gets updated with changed value from Rtable, which is not what I want.

Here's an example of contents of both tables before update:

```<code>Dtable             Rtable
---------------    ---------------
| key | value |    | key | value |
---------------    ---------------
| 403 |   0   |    | 403 |   105 |
---------------    ---------------
| 403 |   0   |
---------------
</code>```

And this is what i want it to look after the update:

```<code>Dtable             Rtable
---------------    ---------------
| key | value |    | key | value |
---------------    ---------------
| 403 |  105  |    | 403 |   0   |
---------------    ---------------
| 403 |  105  |
---------------
</code>```

Any suggestions? Thanks

答:
See if this gets you closer:</p>

```<code>UPDATE Dtable s, Rtable r
SET s.value = r.value,
r.value = 0
FROM Rtable r
JOIN Dtable d
ON r.key = d.key
WHERE d.key = 403;
</code>```

ContentLicense: CC BY-SA 3.0

Title: Update two tables with one query

Body:
I have two tables, Dtable d and Rtable r. I want to update both tables with one query (important!) in the following order: first setting all Dtable matching row values with a value from Rtable. Then - changing the value from Rtable. In Rtable there will always be a record that matches a key, but in Dtable there can be 0,1 or many records that matches the key. I came up with the following select:

UPDATE Dtable d, Rtable r

SET
    d.value = r.value,
    r.value = 0
WHERE
    d.key = 403 AND d.value = 0 AND r.id = 403

But the problem here is that if I have multiple records in Dtable that match the key, only first one gets updated with value from Rtable, then the value of Rtable changes, and second row from Dtable already gets updated with changed value from Rtable, which is not what I want.

Here's an example of contents of both tables before update:

Dtable             Rtable
---------------    ---------------
| key | value |    | key | value |
---------------    ---------------
| 403 |   0   |    | 403 |   105 |
---------------    ---------------
| 403 |   0   |
---------------

And this is what i want it to look after the update:

Dtable             Rtable
---------------    ---------------
| key | value |    | key | value |
---------------    ---------------
| 403 |  105  |    | 403 |   0   |
---------------    ---------------
| 403 |  105  |
---------------

Any suggestions? Thanks

Body:
See if this gets you closer:

UPDATE Dtable s, Rtable r
SET s.value = r.value,
r.value = 0
FROM Rtable r
JOIN Dtable d
ON r.key = d.key
WHERE d.key = 403;


问:
Can't get single values from tuple taken from Option[Double]
Hey I'm having difficulty with getting values from a tuple

I want to do arithmetic operations on the values of two Option[Double] if they are not equal to None. The code I have so far is this

```<code>def optionDoubleAddition(a: Option[Double], b: Option[Double]) : Option[Double] = {

  val tuple = if(a != None && b != None) (a.getOrElse(0: Double),b.getOrElse(0: Double))
  println(tuple) //prints the values correctly when passed two doubles
  None //something to make the function work
}
</code>```

It won't allow me to get the single elements from the tuple with either

```<code>println(t(0))
println(t._1)
</code>```

Also I'm a bit concerned with the getOrElse function is there any alternative to this, i've tried solving the above in different ways for example if i wanted to do the following

```<code>val example: Option[Double] = Some(5.0)
</code>```

and I want to get the value of example or None otherwise

```<code>example.getOrElse(None)
</code>```

which returns the value as Any however I need it to be a double, if i try the following I also run into errors if it is None

```<code>val doubleValue: Double = example.getOrElse(None)
</code>```

Thanks!

答:
I think this is what you're looking for, at least it is correct for the method profile.

```<code>def optionDoubleAddition(a: Option[Double], b: Option[Double]) : Option[Double] =
  for {x <- a; y <- b} yield x+y
</code>```

This unwraps each Option, adds them, and re-wraps the result, but if either or both is None then the unwrapping stops and None is returned.

Body:
Hey I'm having difficulty with getting values from a tuple

I want to do arithmetic operations on the values of two Option[Double] if they are not equal to None. The code I have so far is this

def optionDoubleAddition(a: Option[Double], b: Option[Double]) : Option[Double] = {

  val tuple = if(a != None && b != None) (a.getOrElse(0: Double),b.getOrElse(0: Double))
  println(tuple) //prints the values correctly when passed two doubles
  None //something to make the function work
}

It won't allow me to get the single elements from the tuple with either

println(t(0))
println(t._1)

Also I'm a bit concerned with the getOrElse function is there any alternative to this, i've tried solving the above in different ways for example if i wanted to do the following

val example: Option[Double] = Some(5.0)

and I want to get the value of example or None otherwise

example.getOrElse(None)

which returns the value as Any however I need it to be a double, if i try the following I also run into errors if it is None

val doubleValue: Double = example.getOrElse(None)

Thanks!

Body:
I think this is what you're looking for, at least it is correct for the method profile.

def optionDoubleAddition(a: Option[Double], b: Option[Double]) : Option[Double] =
  for {x <- a; y <- b} yield x+y

This unwraps each Option, adds them, and re-wraps the result, but if either or both is None then the unwrapping stops and None is returned.


问:
Change multiple string in a list
I have a list

```<code>task_list = ['A1.wakeup', 'A2.brush','B1.route','B2.breakfast']
</code>```

the result i want is

```<code>task_list = ['1A1.wakeup', '1A2.brush','2B1.route','2B2.breakfast']
</code>```

I use a for loop:

```<code>new_task_list = task_list[:]
for task in new_task_list:
    task.replace('A', '1A')
    task.replace('B','1B')

In [61]: new_task_list
Out[61]: ['A1.wakeup', 'A2.brush', 'B1.route', 'B2.breakfast']
</code>```

It does not change, What's the problem?

答:
The problem is that strings in python are inmutable (they can not change), that's why replace will return a new string (the original one will be the same). To do what you want you could try:

```<code>new_task_list = task_list[:]
for idx, task in enumerate(new_task_list):
    new_task_list[idx] = new_task_list[idx].replace('A', '1A')
    new_task_list[idx] = new_task_list[idx].replace('B', '2B')
</code>```

or even:

```<code>from operator import methodcaller
new_task_list = map(methodcaller('replace', 'B', '2B'),
                map(methodcaller('replace', 'A', '1A'), task_list))
</code>```

Title: Change multiple string in a list

Body:
I have a list

task_list = ['A1.wakeup', 'A2.brush','B1.route','B2.breakfast']

the result i want is

task_list = ['1A1.wakeup', '1A2.brush','2B1.route','2B2.breakfast']

I use a for loop:

new_task_list = task_list[:]
for task in new_task_list:
    task.replace('A', '1A')
    task.replace('B','1B')

In [61]: new_task_list
Out[61]: ['A1.wakeup', 'A2.brush', 'B1.route', 'B2.breakfast']

It does not change, What's the problem?

Body:
The problem is that strings in python are inmutable (they can not change), that's why replace will return a new string (the original one will be the same). To do what you want you could try:

new_task_list = task_list[:]
for idx, task in enumerate(new_task_list):
    new_task_list[idx] = new_task_list[idx].replace('A', '1A')
    new_task_list[idx] = new_task_list[idx].replace('B', '2B')

or even:

from operator import methodcaller
new_task_list = map(methodcaller('replace', 'B', '2B'),
                map(methodcaller('replace', 'A', '1A'), task_list))


问:
How to parse JSON manually in Kotlin?
I want to parse JSON response manually in Kotlin. Since I am getting complex JSON response which is having some common fields. For example I am getting below response.

```<code>{
  status: "success/false"
  apiId: 6
  message: "Error msg if any"
  .
  .
  .    // Here comes some JSON with complex structure where some fields are
  .    // missing/omitted. Sometime array is missing/response in array is
  .    // getting changed, getting lot of unwanted stuff Or whatever you can
  .    // think. And because of this I need to parse it manually.
  .
}
</code>```

Now how can I parse this type of response manually in data class of Kotlin? One more thing I would like to know, can I use any base class for common fields in the response?

答:
jackson-databind has @JsonIgnoreProperties(ignoreUnknown=true) annotation which can ignore unwanted json fields. then what you need to do is write a data class like below

```<code>@JsonIgnoreProperties(ignoreUnknown=true)
data class Response(val status: String, val apiId: Int, val message: String)
</code>```

Title: How to parse JSON manually in Kotlin?

Body:
I want to parse JSON response manually in Kotlin. Since I am getting complex JSON response which is having some common fields. For example I am getting below response.

{
  status: "success/false"
  apiId: 6
  message: "Error msg if any"
  .
  .
  .    // Here comes some JSON with complex structure where some fields are
  .    // missing/omitted. Sometime array is missing/response in array is
  .    // getting changed, getting lot of unwanted stuff Or whatever you can
  .    // think. And because of this I need to parse it manually.
  .
}

Now how can I parse this type of response manually in data class of Kotlin? One more thing I would like to know, can I use any base class for common fields in the response?

Body:
jackson-databind has @JsonIgnoreProperties(ignoreUnknown=true) annotation which can ignore unwanted json fields. then what you need to do is write a data class like below

@JsonIgnoreProperties(ignoreUnknown=true)
data class Response(val status: String, val apiId: Int, val message: String)


问:
change current TextArea value without assign a new one?
When I press "A" to add a character to a value of the TextArea, how does the value change?
does the browser do something like this:

```<code>texarea.value+="A";
//same as:
texarea.value=texarea.value+"A";
</code>```

?

I would like to change that value dynamicaly and notify the textarea about the change without assign a new one, because I think that assingment is not very perfomant if the value takes a lot of memory.
Is there a way to do this?

答:
Ok, I solved it:

at first sight this solution seems also not very performant, but it has some big advatages:
for example you could load only a specific part of a very big file from server and dynamically load it if the user scroll through the page.
you can also update the client version of the file representation (synchronized editing)

document.registerElement('text-area', class NicePanel extends HTMLElement {
  createdCallback() {
    //this.root = this.createShadowRoot();
    this.tabIndex = 1;
    this.onkeydown = function(e) {
      this.monkeydown(e);
    }
    this.onkeypress = function(e) {
      this.monkeypress(e);
    }

    this.setValue(this.innerHTML);
  }
  setValue(value) {
    var mutablestring = Array.from(value);
    this.innerHTML = "";
    var l = mutablestring.length;
    for (var i = 0; i < l; i++) {
      if (mutablestring[i] == '\n') {
        var br = document.createElement('br');
        br.onclick = this.characterClick;
        this.appendChild(br);
      } else {
        var span = document.createElement('span');
        span.onclick = this.characterClick;
        span.innerHTML = mutablestring[i];
        this.appendChild(span);
      }
    }
    this.cursor = document.createElement('span');
    this.cursor.innerHTML = "|";
    this.appendChild(this.cursor);
  }
  getValue() {
    var value = "";
    var children = this.childNodes;
    var that = this;
    children.forEach(function(child) {
      if (child.nodeName == "BR") {
        value += "\n";
        return;
      }
      if (child === that.cursor) return;
      value += child.innerHTML;
    });

    return value;
  }

  attachedCallback() {}
  monkeydown(e) {
    var KeyID = event.keyCode;
    switch (KeyID) {
      case 8:
        this.cursor.parentNode.removeChild(this.cursor.previousSibling);

        e.preventDefault();
        break;
      case 46:
        this.cursor.parentNode.removeChild(this.cursor.nextSibling);
        e.preventDefault();
        break;

      case 13:
        var br = document.createElement('br');
        br.onclick = this.characterClick;
        this.cursor.before(br);
        e.preventDefault();
        break;
      case 37: //left
        this.cursor.parentNode.insertBefore(this.cursor, this.cursor.previousSibling);
        break;
      case 38: //up
        break;
      case 39: //right
        this.cursor.parentNode.insertBefore(this.cursor, this.cursor.nextSibling.nextSibling);
        break;
      case 40: //down
        break;
      default:
        break;
    }
  }
  characterClick(e) {
    this.parentNode.cursor.parentNode.insertBefore(this.parentNode.cursor, e.target);
  }
  monkeypress(e) {
    var span = document.createElement('span');
    span.onclick = this.characterClick;

    span.innerHTML = String.fromCharCode(e.which);
    this.cursor.parentNode.insertBefore(span, this.cursor);
  }
  monclick(e) {
    var target = e.target; // Clicked element
    while (target && target.parentNode !== this) {
      target = target.parentNode; // If the clicked element isn't a direct child
      if (!target) {
        return;
      } // If element doesn't exist
    }
    if (target.tagName === 'SPAN') {
      alert(target.id); // Check if the element is a LI
    }
  }
})
var myta = document.getElementById('myta');
myta.setValue("huhu\nlala");
console.log(myta.getValue());```
<pre class="snippet-code-css lang-css prettyprint-override"><code>text-area {
  width: 100%;
  background: #fff;
  display: block;
}</code>```

<text-area id="myta" class="text">Hello World

</text-area>```

Body:
When I press "A" to add a character to a value of the TextArea, how does the value change?
does the browser do something like this:

texarea.value+="A";
//same as:
texarea.value=texarea.value+"A";

?

I would like to change that value dynamicaly and notify the textarea about the change without assign a new one, because I think that assingment is not very perfomant if the value takes a lot of memory.
Is there a way to do this?

Body:
Ok, I solved it:

at first sight this solution seems also not very performant, but it has some big advatages:
for example you could load only a specific part of a very big file from server and dynamically load it if the user scroll through the page.
you can also update the client version of the file representation (synchronized editing)

document.registerElement('text-area', class NicePanel extends HTMLElement {
  createdCallback() {
    //this.root = this.createShadowRoot();
    this.tabIndex = 1;
    this.onkeydown = function(e) {
      this.monkeydown(e);
    }
    this.onkeypress = function(e) {
      this.monkeypress(e);
    }

    this.setValue(this.innerHTML);
  }
  setValue(value) {
    var mutablestring = Array.from(value);
    this.innerHTML = "";
    var l = mutablestring.length;
    for (var i = 0; i < l; i++) {
      if (mutablestring[i] == '\n') {
        var br = document.createElement('br');
        br.onclick = this.characterClick;
        this.appendChild(br);
      } else {
        var span = document.createElement('span');
        span.onclick = this.characterClick;
        span.innerHTML = mutablestring[i];
        this.appendChild(span);
      }
    }
    this.cursor = document.createElement('span');
    this.cursor.innerHTML = "|";
    this.appendChild(this.cursor);
  }
  getValue() {
    var value = "";
    var children = this.childNodes;
    var that = this;
    children.forEach(function(child) {
      if (child.nodeName == "BR") {
        value += "\n";
        return;
      }
      if (child === that.cursor) return;
      value += child.innerHTML;
    });

    return value;
  }

  attachedCallback() {}
  monkeydown(e) {
    var KeyID = event.keyCode;
    switch (KeyID) {
      case 8:
        this.cursor.parentNode.removeChild(this.cursor.previousSibling);

        e.preventDefault();
        break;
      case 46:
        this.cursor.parentNode.removeChild(this.cursor.nextSibling);
        e.preventDefault();
        break;

      case 13:
        var br = document.createElement('br');
        br.onclick = this.characterClick;
        this.cursor.before(br);
        e.preventDefault();
        break;
      case 37: //left
        this.cursor.parentNode.insertBefore(this.cursor, this.cursor.previousSibling);
        break;
      case 38: //up
        break;
      case 39: //right
        this.cursor.parentNode.insertBefore(this.cursor, this.cursor.nextSibling.nextSibling);
        break;
      case 40: //down
        break;
      default:
        break;
    }
  }
  characterClick(e) {
    this.parentNode.cursor.parentNode.insertBefore(this.parentNode.cursor, e.target);
  }
  monkeypress(e) {
    var span = document.createElement('span');
    span.onclick = this.characterClick;

    span.innerHTML = String.fromCharCode(e.which);
    this.cursor.parentNode.insertBefore(span, this.cursor);
  }
  monclick(e) {
    var target = e.target; // Clicked element
    while (target && target.parentNode !== this) {
      target = target.parentNode; // If the clicked element isn't a direct child
      if (!target) {
        return;
      } // If element doesn't exist
    }
    if (target.tagName === 'SPAN') {
      alert(target.id); // Check if the element is a LI
    }
  }
})
var myta = document.getElementById('myta');
myta.setValue("huhu\nlala");
console.log(myta.getValue());

text-area {
  width: 100%;
  background: #fff;
  display: block;
}

<text-area id="myta" class="text">Hello World

</text-area>


问:
Get distance/displacement between two points
I need to return the distance between two points (p1 = (x1,y1) and p2 = (x2,y2)) but return the negative distance if p2's values are less then p1's.

So that this example is true:
https://i.imgur.com/ZbN8CkG.png

√((x1-x2)² + (y1-y2)²) will always return a positive value, as distance cannot be negative. But what I need is more similar to displacement.

Can anyone help?

答:
It sounds like you really want a vector. It has magnitude and direction. The magnitude is the distance between the two points. The direction is determined by drawing the vector from the start point to the end point. The choice is arbitrary.

A vector from (0,0) to (5,0) is the same length as one drawn from (5,0) to (0.0): both are length 5.  But one points in the positive x-direction; the other points in the negative x-direction.  The vector idea is more general.

In 2D rectangular coordinates, you have points p1 = (p1x, p1y) and p2 = (p2x, p2y).

The vector from p1 to p2 is:

```<code>p = (p2x-p1x)*i + (p2y-p1y)*j
</code>```

where i = unit x-vector and j = unit y-vector.

The magnitude of p is

```<code>pmag = sqrt((p2x-p1x)^2 + (p2y-p1y)^2)
</code>```

The unit vector from p1 to p2 can be had by dividing the vector p by its magnitude:

```<code>p(unit) = (p2x-p1x)*i/pmag + (p2y-p1y)*j/pmag
</code>```

punit points in the same direction as p, but it has magnitude 1 (hence the name "unit vector").

Body:
It sounds like you really want a vector. It has magnitude and direction. The magnitude is the distance between the two points. The direction is determined by drawing the vector from the start point to the end point. The choice is arbitrary.

A vector from (0,0) to (5,0) is the same length as one drawn from (5,0) to (0.0): both are length 5.  But one points in the positive x-direction; the other points in the negative x-direction.  The vector idea is more general.

In 2D rectangular coordinates, you have points p1 = (p1x, p1y) and p2 = (p2x, p2y).

The vector from p1 to p2 is:

p = (p2x-p1x)*i + (p2y-p1y)*j

where i = unit x-vector and j = unit y-vector.

The magnitude of p is

pmag = sqrt((p2x-p1x)^2 + (p2y-p1y)^2)

The unit vector from p1 to p2 can be had by dividing the vector p by its magnitude:

p(unit) = (p2x-p1x)*i/pmag + (p2y-p1y)*j/pmag

punit points in the same direction as p, but it has magnitude 1 (hence the name "unit vector").


问:
Sorting array by 2 conditions in Javascript not working
I want to sort an array of objects by both id and name. First it should be sorted by id in ascending order. Then it should be sorted by name in ascending order.

Sort function

```<code><script>
  $(document).ready(function() {
    var list = [{
      "id": "ts1",
      "name": "TS1"
    }, {
      "id": "ts10",
      "name": "TS10"
    }, {
      "id": "ts11",
      "name": "TS11"
    }, {
      "id": "ts12",
      "name": "TS12"
    }, {
      "id": "ts13",
      "name": "TS2"
    }, {
      "id": "ts13",
      "name": "TS1"
    }, {
      "id": "ts13",
      "name": "TS3"
    }, {
      "id": "ts14",
      "name": "TS14"
    }, {
      "id": "ts15",
      "name": "TS15"
    }, {
      "id": "ts16",
      "name": "TS16"
    }, {
      "id": "ts17",
      "name": "TS17"
    }, {
      "id": "ts18",
      "name": "TS18"
    }, {
      "id": "ts19",
      "name": "TS19"
    }, {
      "id": "ts2",
      "name": "TS2"
    }, {
      "id": "ts20",
      "name": "TS20"
    }, {
      "id": "ts21",
      "name": "TS21"
    }, {
      "id": "ts22",
      "name": "TS22"
    }, {
      "id": "ts3",
      "name": "TS3"
    }, {
      "id": "ts4",
      "name": "TS4"
    }, {
      "id": "ts5",
      "name": "TS5"
    }, {
      "id": "ts6",
      "name": "TS6"
    }, {
      "id": "ts7",
      "name": "TS7"
    }]

    list.sort(Sort_ID_Name);

    console.log(list);
  });

  function Sort_ID_Name(a, b) {
    try {
      var aID = a.id.toLowerCase();
      var bID = b.id.toLowerCase();
      var aName = a.name.toLowerCase();
      var bName = b.name.toLowerCase();
      return ((aID < bID) ? -1 : ((aID > bID) ? 1 : ((aName < bName) ? -1 : ((aName > bName) ? 1 : 0))));
    } catch (err) {}
  }

</script>
</code>```

Currently the sorted list shows up like this:

```<code>{id: "ts1", name: "TS1"}
{id: "ts10", name: "TS10"}
{id: "ts11", name: "TS11"}
{id: "ts12", name: "TS12"}
{id: "ts13", name: "TS1"}
{id: "ts13", name: "TS2"}
{id: "ts13", name: "TS3"}
{id: "ts14", name: "TS14"}
{id: "ts15", name: "TS15"}
{id: "ts16", name: "TS16"}
....
</code>```

The ideal state is like this

```<code>{id: "ts1", name: "TS1"}
{id: "ts2", name: "TS2"}
...
{id: "ts10", name: "TS10"}
{id: "ts11", name: "TS11"}
{id: "ts12", name: "TS12"}
{id: "ts13", name: "TS1"}
{id: "ts13", name: "TS2"}
{id: "ts13", name: "TS3"}
{id: "ts14", name: "TS14"}
{id: "ts15", name: "TS15"}
{id: "ts16", name: "TS16"}
....
</code>```

The function works only when the list is very short, but when the list is long it doesn't work well. See live demo- https://jsfiddle.net/0xLd6sms/2/

答:
You can use custom sort method using localeComapre() specifying the  numeric: true option, it will smartly recognize numbers

var list = [{ "id": "ts1", "name": "TS1" }, { "id": "ts10", "name": "TS10" }, { "id": "ts11", "name": "TS11" }, { "id": "ts12", "name": "TS13" }, { "id": "ts13", "name": "TS2" }, { "id": "ts13", "name": "TS1" }, { "id": "ts13", "name": "TS3" }, { "id":"ts14", "name": "TS14" }, { "id": "ts15", "name": "TS15" }, { "id": "ts16", "name": "TS16" }, { "id": "ts17", "name": "TS17" }, { "id": "ts18", "name": "TS18" }, { "id": "ts19", "name": "TS19" }, { "id": "ts2", "name": "TS2" }, { "id": "ts20", "name":"TS20" }, { "id": "ts21", "name": "TS21" }, { "id": "ts22", "name": "TS22" }, { "id": "ts3", "name": "TS3" }, { "id": "ts4", "name": "TS4" }, { "id": "ts5", "name": "TS5" }, { "id": "ts6", "name": "TS6" }, { "id": "ts7", "name": "TS7" }];
list.sort((a,b) => a.id.localeCompare(b.id, undefined, {numeric: true}) || a.name.localeCompare(b.name, undefined, {numeric: true}));
console.log(list);```
<pre class="snippet-code-css lang-css prettyprint-override"><code>.as-console-wrapper { max-height: 100% !important; top: 0; }</code>```

Body:
I want to sort an array of objects by both id and name. First it should be sorted by id in ascending order. Then it should be sorted by name in ascending order.

Sort function

Currently the sorted list shows up like this:

{id: "ts1", name: "TS1"}
{id: "ts10", name: "TS10"}
{id: "ts11", name: "TS11"}
{id: "ts12", name: "TS12"}
{id: "ts13", name: "TS1"}
{id: "ts13", name: "TS2"}
{id: "ts13", name: "TS3"}
{id: "ts14", name: "TS14"}
{id: "ts15", name: "TS15"}
{id: "ts16", name: "TS16"}
....

The ideal state is like this

{id: "ts1", name: "TS1"}
{id: "ts2", name: "TS2"}
...
{id: "ts10", name: "TS10"}
{id: "ts11", name: "TS11"}
{id: "ts12", name: "TS12"}
{id: "ts13", name: "TS1"}
{id: "ts13", name: "TS2"}
{id: "ts13", name: "TS3"}
{id: "ts14", name: "TS14"}
{id: "ts15", name: "TS15"}
{id: "ts16", name: "TS16"}
....

The function works only when the list is very short, but when the list is long it doesn't work well. See live demo- https://jsfiddle.net/0xLd6sms/2/

Body:
You can use custom sort method using localeComapre() specifying the  numeric: true option, it will smartly recognize numbers

var list = [{ "id": "ts1", "name": "TS1" }, { "id": "ts10", "name": "TS10" }, { "id": "ts11", "name": "TS11" }, { "id": "ts12", "name": "TS13" }, { "id": "ts13", "name": "TS2" }, { "id": "ts13", "name": "TS1" }, { "id": "ts13", "name": "TS3" }, { "id":"ts14", "name": "TS14" }, { "id": "ts15", "name": "TS15" }, { "id": "ts16", "name": "TS16" }, { "id": "ts17", "name": "TS17" }, { "id": "ts18", "name": "TS18" }, { "id": "ts19", "name": "TS19" }, { "id": "ts2", "name": "TS2" }, { "id": "ts20", "name":"TS20" }, { "id": "ts21", "name": "TS21" }, { "id": "ts22", "name": "TS22" }, { "id": "ts3", "name": "TS3" }, { "id": "ts4", "name": "TS4" }, { "id": "ts5", "name": "TS5" }, { "id": "ts6", "name": "TS6" }, { "id": "ts7", "name": "TS7" }];
list.sort((a,b) => a.id.localeCompare(b.id, undefined, {numeric: true}) || a.name.localeCompare(b.name, undefined, {numeric: true}));
console.log(list);

.as-console-wrapper { max-height: 100% !important; top: 0; }


问:
HTML Responsive image sizes
I'm really struggling with this. I'm implementing a responsive gallery (with columns) with responsive images in my very first web project, formatted for lazy loading. After 760px the gallery turns into 2 columns, at 1365px 3 columns, at 1920px or higher 4 columns.

```<code><img class="lazyload"
                  src="placeholder.jpg"
                  data-srcset="image-360w.jpg 360w,
                               image-512w.jpg 512w,
                               image-750w.jpg 750w"
                  data-src="image-750w.jpg"
                  sizes="(min-width:761px) 50vw,
                         (min-width:1366px) 33.3vw,
                         (min-width:1921px) 25vw"
                  alt="Description">
</code>```

In "sizes" I set a min-width at where the 2nd columns appears and it works. But the rest, the several min-widths for each column break point, are not working for me, it loads the biggest every time (I'm not using a Retina Display and have tested in Safari, Firefox and Chrome). Maybe I'm completely overlooking something simple, as I'm very new to this. Anyways, I was thinking if it's possible to use the column-count value to calculate what image to load. Something like calc(100vw / column-count) which doesn't work. How can I solve this? Something about min-width and max-width I'm missing? Should I go to scripts?

答:
Try to use <picture> tag in HTML

```<code><picture>
   <!-- Full HD Resolution -->
   <source srcset="https://placehold.it/1920x1080" media="(min-width: 1920px)" />
   <!-- Samsung Galaxy S7 Edge -->
   <source srcset="https://placehold.it/1442x2562" media="(min-width: 1442px)" />
   <!-- HiDPI Laptop -->
   <source srcset="https://placehold.it/1440x900" media="(min-width: 1440px)" />
   <!-- Common Resolution -->
   <source srcset="https://placehold.it/1366x768" media="(min-width: 1366px)" />
   <!-- 4:3 (Old CRT monitors) -->
   <source srcset="https://placehold.it/1280x1024" media="(min-width: 1280px)" />
   <!-- iPad Pro -->
   <source srcset="https://placehold.it/1024x1366" media="(min-width: 1024px)" />
   <!-- iPad -->
   <source srcset="https://placehold.it/768x1024" media="(min-width: 768px)" />
   <!-- iPhone 6 Plus -->
   <source srcset="https://placehold.it/414x736" media="(min-width: 414px)" />
   <!-- Google Nexus 5X -->
   <source srcset="https://placehold.it/412x732" media="(min-width: 412px)" />
   <!-- iPhone 6 -->
   <source srcset="https://placehold.it/375x667" media="(min-width: 375px)" />
   <!-- iPhone 5 -->
   <source srcset="https://placehold.it/320x568" media="(min-width: 320px)" />
   <!-- If the browser doesn't support "srcset" attribute, then load the default resolution -->
   <img src="https://placehold.it/1366x768" alt="Background"/>
 </picture>
</code>```

But it's better to make responsive images using CSS

```<code>img {
    background-image: url('path-to-image');
    background-position: 0% 0%;
    background-size: cover;
    width: 100%;
    height: auto;
  }
</code>```

Hope this helps.

Title: HTML Responsive image sizes

Body:
I'm really struggling with this. I'm implementing a responsive gallery (with columns) with responsive images in my very first web project, formatted for lazy loading. After 760px the gallery turns into 2 columns, at 1365px 3 columns, at 1920px or higher 4 columns.

In "sizes" I set a min-width at where the 2nd columns appears and it works. But the rest, the several min-widths for each column break point, are not working for me, it loads the biggest every time (I'm not using a Retina Display and have tested in Safari, Firefox and Chrome). Maybe I'm completely overlooking something simple, as I'm very new to this. Anyways, I was thinking if it's possible to use the column-count value to calculate what image to load. Something like calc(100vw / column-count) which doesn't work. How can I solve this? Something about min-width and max-width I'm missing? Should I go to scripts?

Body:
Try to use <picture> tag in HTML

<picture>
   <!-- Full HD Resolution -->
   <source srcset="https://placehold.it/1920x1080" media="(min-width: 1920px)" />
   <!-- Samsung Galaxy S7 Edge -->
   <source srcset="https://placehold.it/1442x2562" media="(min-width: 1442px)" />
   <!-- HiDPI Laptop -->
   <source srcset="https://placehold.it/1440x900" media="(min-width: 1440px)" />
   <!-- Common Resolution -->
   <source srcset="https://placehold.it/1366x768" media="(min-width: 1366px)" />
   <!-- 4:3 (Old CRT monitors) -->
   <source srcset="https://placehold.it/1280x1024" media="(min-width: 1280px)" />
   <!-- iPad Pro -->
   <source srcset="https://placehold.it/1024x1366" media="(min-width: 1024px)" />
   <!-- iPad -->
   <source srcset="https://placehold.it/768x1024" media="(min-width: 768px)" />
   <!-- iPhone 6 Plus -->
   <source srcset="https://placehold.it/414x736" media="(min-width: 414px)" />
   <!-- Google Nexus 5X -->
   <source srcset="https://placehold.it/412x732" media="(min-width: 412px)" />
   <!-- iPhone 6 -->
   <source srcset="https://placehold.it/375x667" media="(min-width: 375px)" />
   <!-- iPhone 5 -->
   <source srcset="https://placehold.it/320x568" media="(min-width: 320px)" />
   <!-- If the browser doesn't support "srcset" attribute, then load the default resolution -->
   <img src="https://placehold.it/1366x768" alt="Background"/>
 </picture>

But it's better to make responsive images using CSS

img {
    background-image: url('path-to-image');
    background-position: 0% 0%;
    background-size: cover;
    width: 100%;
    height: auto;
  }

Hope this helps.


问:
How can I put PayPal discount codes on my checkout
Just doing a simple code to apply promo code on my PayPal button. I just did like below but the validate() function did not alert.

I hope all codes are correct. Please check the Fiddle and do let me know why the functions are not working.

function validate( text1, text2 ) {

   if ( text1 == text2 ) {
    window.alert( "Nice, you get a 10% Discount!" );
   }
   if ( text1 !== text2 ) {
    window.alert( "Sorry, No Discount!" );
   }
  }

  function CalculateOrder( form ) {

   if ( form.text1.value == "GOLD10" ) {
    form.discount_rate.value = "10";
    form.discount_rate2.value = "10";
    form.on3.value = "Coupon Entered";
    form.os3.value = "GOLD10";
   }
  }```
<pre class="snippet-code-html lang-html prettyprint-override"><code><form target="_self" action="https://www.paypal.com/cgi-bin/webscr" method="post">
  <input type="hidden" name="cmd" value="_cart"/>
  <input type="hidden" name="add" value="1"/>
  <input type="hidden" name="business" value="fanciedmedia@gmail.com"/>
  <input type="hidden" name="item_name" value="Blue Kidsport Burst"/>
  <input type="hidden" name="amount" value="149.00"/>
  <input type="hidden" name="currency_code" value="USD"/>
  <input type="hidden" name="no_shipping" value="2">
  <input type="hidden" name="weight_unit" value="lbs">
  <input type="hidden" name="baseamt" value="149.00"/>
  <input type="hidden" name="item_number" value="BUONBL">
  <span id="dist"></span>

  <input type="text" name="text1">
  <input type="button" value="Check It" name="Submit" onclick=javascript:validate(text1.value, "GOLD10")>
  <br>
  <input name="submit" type="image" alt="Add to Cart" src="add_to.png" onclick=CalculateOrder(this.form)/>

 </form></code>```

答:
You missed adding simple quotes ' in the onclick attributes, and you should refer to form object in order to get text1 value:

```<code>onclick=javascript:validate(text1.value, "GOLD10")
        ^^                        ^^^                   ^^

onclick=CalculateOrder(this.form)
        ^^                       ^^
</code>```

It should be:

```<code>onclick='javascript:validate(form.text1.value, "GOLD10")'
onclick='CalculateOrder(this.form)'
</code>```

Try this code:

function validate( text1, text2 ) {

  if ( text1 == text2 ) {
    window.alert( "Nice, you get a 10% Discount!" );
  }
  if ( text1 !== text2 ) {
    window.alert( "Sorry, No Discount!" );
  }
}

function CalculateOrder( form ) {

  if ( form.text1.value == "GOLD10" ) {
    form.discount_rate.value = "10";
    form.discount_rate2.value = "10";
    form.on3.value = "Coupon Entered";
    form.os3.value = "GOLD10";
  }

  alert('submitting form');
  form.submit();
}```
<pre class="snippet-code-html lang-html prettyprint-override"><code><form target="_self" action="https://www.paypal.com/cgi-bin/webscr" method="post">
  <input type="hidden" name="cmd" value="_cart"/>
  <input type="hidden" name="add" value="1"/>
  <input type="hidden" name="business" value="fanciedmedia@gmail.com"/>
  <input type="hidden" name="item_name" value="Blue Kidsport Burst"/>
  <input type="hidden" name="amount" value="149.00"/>
  <input type="hidden" name="currency_code" value="USD"/>
  <input type="hidden" name="no_shipping" value="2">
  <input type="hidden" name="weight_unit" value="lbs">
  <input type="hidden" name="baseamt" value="149.00"/>
  <input type="hidden" name="item_number" value="BUONBL">

    <input type="hidden" name="discount_rate" value="">
    <input type="hidden" name="discount_rate2" value="">
    <input type="hidden" name="on3" value="">
    <input type="hidden" name="os3" value="">
  <span id="dist"></span>

  <input type="text" name="text1">
  <input type="button" value="Check It" name="Submit" onclick='javascript:validate(form.text1.value, "GOLD10")'>
  <br>
  <input type="button" alt="Add to Cart" src="add_to.png" value="add to cart" onclick='CalculateOrder(form)'/>

 </form></code>```

Body:
Just doing a simple code to apply promo code on my PayPal button. I just did like below but the validate() function did not alert.

I hope all codes are correct. Please check the Fiddle and do let me know why the functions are not working.

function validate( text1, text2 ) {

   if ( text1 == text2 ) {
    window.alert( "Nice, you get a 10% Discount!" );
   }
   if ( text1 !== text2 ) {
    window.alert( "Sorry, No Discount!" );
   }
  }

  function CalculateOrder( form ) {

   if ( form.text1.value == "GOLD10" ) {
    form.discount_rate.value = "10";
    form.discount_rate2.value = "10";
    form.on3.value = "Coupon Entered";
    form.os3.value = "GOLD10";
   }
  }

<form target="_self" action="https://www.paypal.com/cgi-bin/webscr" method="post">
  <input type="hidden" name="cmd" value="_cart"/>
  <input type="hidden" name="add" value="1"/>
  <input type="hidden" name="business" value="fanciedmedia@gmail.com"/>
  <input type="hidden" name="item_name" value="Blue Kidsport Burst"/>
  <input type="hidden" name="amount" value="149.00"/>
  <input type="hidden" name="currency_code" value="USD"/>
  <input type="hidden" name="no_shipping" value="2">
  <input type="hidden" name="weight_unit" value="lbs">
  <input type="hidden" name="baseamt" value="149.00"/>
  <input type="hidden" name="item_number" value="BUONBL">

  <input type="text" name="text1">
  <input type="button" value="Check It" name="Submit" onclick=javascript:validate(text1.value, "GOLD10")>

  <input name="submit" type="image" alt="Add to Cart" src="add_to.png" onclick=CalculateOrder(this.form)/>

 </form>

Body:
You missed adding simple quotes ' in the onclick attributes, and you should refer to form object in order to get text1 value:

onclick=javascript&colon;validate(text1.value, "GOLD10")
        ^^                        ^^^                   ^^

onclick=CalculateOrder(this.form)
        ^^                       ^^

It should be:

onclick='javascript&colon;validate(form.text1.value, "GOLD10")'
onclick='CalculateOrder(this.form)'

Try this code:

function validate( text1, text2 ) {

  if ( text1 == text2 ) {
    window.alert( "Nice, you get a 10% Discount!" );
  }
  if ( text1 !== text2 ) {
    window.alert( "Sorry, No Discount!" );
  }
}

function CalculateOrder( form ) {

  if ( form.text1.value == "GOLD10" ) {
    form.discount_rate.value = "10";
    form.discount_rate2.value = "10";
    form.on3.value = "Coupon Entered";
    form.os3.value = "GOLD10";
  }

  alert('submitting form');
  form.submit();
}

<form target="_self" action="https://www.paypal.com/cgi-bin/webscr" method="post">
  <input type="hidden" name="cmd" value="_cart"/>
  <input type="hidden" name="add" value="1"/>
  <input type="hidden" name="business" value="fanciedmedia@gmail.com"/>
  <input type="hidden" name="item_name" value="Blue Kidsport Burst"/>
  <input type="hidden" name="amount" value="149.00"/>
  <input type="hidden" name="currency_code" value="USD"/>
  <input type="hidden" name="no_shipping" value="2">
  <input type="hidden" name="weight_unit" value="lbs">
  <input type="hidden" name="baseamt" value="149.00"/>
  <input type="hidden" name="item_number" value="BUONBL">

    <input type="hidden" name="discount_rate" value="">
    <input type="hidden" name="discount_rate2" value="">
    <input type="hidden" name="on3" value="">
    <input type="hidden" name="os3" value="">
  <span id="dist"></span>

  <input type="text" name="text1">
  <input type="button" value="Check It" name="Submit" onclick='javascript&colon;validate(form.text1.value, "GOLD10")'>
  <br>
  <input type="button" alt="Add to Cart" src="add_to.png" value="add to cart" onclick='CalculateOrder(form)'/>

 </form>


问:
Netflix hystrix shared request caching
I'm using spring cloud based on Netflix OSS architecture. I need to cache results of one of my methods which is using Get-Set-Get pattern.

```<code> public class UserService {
    @CacheResult
    @HystrixCommand
    public User getUserById(@CacheKey String id) { // GET
        return storage.get(id);
    }

    @CacheRemove(commandKey = "getUserById")
    @HystrixCommand
    public void update(@CacheKey("id") User user) { // SET
        storage.put(user.getId(), user);
    }
}
</code>```

Now my question is pretty simple. I need to know can I have a distributed cache if I've multiple instances of this service running? If yes, can I use something like Redis if the size grows?

答:
Yes man see in docs

How to example of implementation:

```<code>public class UserService extends HystrixCommand<Boolean> {
     private final User user;

     public User getUserById(String id) {
        super(HystrixCommandGroupKey.Factory.asKey("AnyUser"));
        user = storage.get(id);
        return user;
    }

    public void update(User user) { // SET
        super(HystrixCommandGroupKey.Factory.asKey("AnyUser"));
        this.user = user;
        storage.put(user.getId(), user);
    }

    @Override
    protected Boolean run() {
        return user == null || (user != null && user.id == 0);
    }

    @Override
    protected String getCacheKey() {
        return (user != null ) ?String.valueOf(user.id):"";
    }
}
</code>```

Title: Netflix hystrix shared request caching

Body:
I'm using spring cloud based on Netflix OSS architecture. I need to cache results of one of my methods which is using Get-Set-Get pattern.

 public class UserService {
    @CacheResult
    @HystrixCommand
    public User getUserById(@CacheKey String id) { // GET
        return storage.get(id);
    }

    @CacheRemove(commandKey = "getUserById")
    @HystrixCommand
    public void update(@CacheKey("id") User user) { // SET
        storage.put(user.getId(), user);
    }
}

Now my question is pretty simple. I need to know can I have a distributed cache if I've multiple instances of this service running? If yes, can I use something like Redis if the size grows?

Body:
Yes man see in docs

How to example of implementation:

public class UserService extends HystrixCommand<Boolean> {
     private final User user;

     public User getUserById(String id) {
        super(HystrixCommandGroupKey.Factory.asKey("AnyUser"));
        user = storage.get(id);
        return user;
    }

    public void update(User user) { // SET
        super(HystrixCommandGroupKey.Factory.asKey("AnyUser"));
        this.user = user;
        storage.put(user.getId(), user);
    }

    @Override
    protected Boolean run() {
        return user == null || (user != null && user.id == 0);
    }

    @Override
    protected String getCacheKey() {
        return (user != null ) ?String.valueOf(user.id):"";
    }
}


答:
Try this - </p>

```<code>UPDATE Dtable d
INNER JOIN Rtable r
ON d.key = r.key
SET
d.value = r.value,
r.value = 0
WHERE
d.key = 403 AND d.value = 0 AND r.id = 403
</code>```

Title: Update two tables with one query

Body:
I have two tables, Dtable d and Rtable r. I want to update both tables with one query (important!) in the following order: first setting all Dtable matching row values with a value from Rtable. Then - changing the value from Rtable. In Rtable there will always be a record that matches a key, but in Dtable there can be 0,1 or many records that matches the key. I came up with the following select:

UPDATE Dtable d, Rtable r

SET
    d.value = r.value,
    r.value = 0
WHERE
    d.key = 403 AND d.value = 0 AND r.id = 403

But the problem here is that if I have multiple records in Dtable that match the key, only first one gets updated with value from Rtable, then the value of Rtable changes, and second row from Dtable already gets updated with changed value from Rtable, which is not what I want.

Here's an example of contents of both tables before update:

Dtable             Rtable
---------------    ---------------
| key | value |    | key | value |
---------------    ---------------
| 403 |   0   |    | 403 |   105 |
---------------    ---------------
| 403 |   0   |
---------------

And this is what i want it to look after the update:

Dtable             Rtable
---------------    ---------------
| key | value |    | key | value |
---------------    ---------------
| 403 |  105  |    | 403 |   0   |
---------------    ---------------
| 403 |  105  |
---------------

Any suggestions? Thanks

Body:
Try this -

UPDATE Dtable d
INNER JOIN Rtable r
ON d.key = r.key
SET
d.value = r.value,
r.value = 0
WHERE
d.key = 403 AND d.value = 0 AND r.id = 403


问:
Sorting by Subarray type value and then alphabetically
I have an array that looks something like this:

```<code>$array = [
    'field1' => [
        '#type' => 'text',
        '#label' => 'Field 11',
    ],
    'field4' => [
        '#type' => 'fieldset',
        '#label' => 'Field 4',
    ],
    'field12' => [
        '#type' => 'text',
        '#label' => 'Field 12',
    ],
    'field3' => [
        '#type' => 'fieldset',
        '#label' => 'Field 3',
    ],
    'field18' => [
        '#type' => 'text',
        '#label' => 'Field 18',
    ],
];
</code>```

I would like to sort this array in such a way where all the fields of type fieldset are at the bottom. At the same time, I would like the text fields (which are on top) to be sorted alphabetically by the #label and the fieldsets (which should be at the bottom) should also be sorted alphabetically by the label. This is what I had so far.

```<code>ksort($array);
uasort($array, function($field1) {
    if ($field1['#type'] !== 'fieldset') {
        return 0;
    }
    return 1;
});
</code>```

Sorting the array by the key value successfully sorts my entire array alphabetically. But once I add the uasort, although my fieldset's are at the bottom, the alphabetical order is no longer present.

Any ideas?

答:
I would use array_multisort.  This sorts as requested if you only have fieldset and text:

```<code>array_multisort(array_column($array, '#type'),  SORT_DESC,
                array_column($array, '#label'), SORT_ASC,
                $array);
</code>```

Extract all #type values into an array sort descending and extract all #label values into an array sort ascending, sorting the original.

Body:
I have an array that looks something like this:

$array = [
    'field1' => [
        '#type' => 'text',
        '#label' => 'Field 11',
    ],
    'field4' => [
        '#type' => 'fieldset',
        '#label' => 'Field 4',
    ],
    'field12' => [
        '#type' => 'text',
        '#label' => 'Field 12',
    ],
    'field3' => [
        '#type' => 'fieldset',
        '#label' => 'Field 3',
    ],
    'field18' => [
        '#type' => 'text',
        '#label' => 'Field 18',
    ],
];

I would like to sort this array in such a way where all the fields of type fieldset are at the bottom. At the same time, I would like the text fields (which are on top) to be sorted alphabetically by the #label and the fieldsets (which should be at the bottom) should also be sorted alphabetically by the label. This is what I had so far.

ksort($array);
uasort($array, function($field1) {
    if ($field1['#type'] !== 'fieldset') {
        return 0;
    }
    return 1;
});

Sorting the array by the key value successfully sorts my entire array alphabetically. But once I add the uasort, although my fieldset's are at the bottom, the alphabetical order is no longer present.

Any ideas?

Body:
I would use array_multisort.  This sorts as requested if you only have fieldset and text:

array_multisort(array_column($array, '#type'),  SORT_DESC,
                array_column($array, '#label'), SORT_ASC,
                $array);

Extract all #type values into an array sort descending and extract all #label values into an array sort ascending, sorting the original.


问:
Extract data after a string one each appearance R
I have a data like this (named spectra):

```<code>#Milk spectra: 1234
##XYDATA=(X++(Y..Y))
649.025085449219
667.675231457819
686.325377466418
##XYDATA=(X++(Y..Y))
723.625669483618
742.275815492218
760.925961500818
##XYDATA=(X++(Y..Y))
872.826837552417
891.476983561017
910.127129569617
928.777275578216
</code>```

In this data, each time the string ##XYDATA=(X++(Y..Y)), that is the data for each different animal.
So, I want to have the code that can help extract this sample into 3 pieces of data.

```<code>Animal 1: 3 lines after 1st '  ##XYDATA=(X++(Y..Y))'
Animal 2: 3 lines after 2nd '  ##XYDATA=(X++(Y..Y))'
</code>```

And so on.

I tried this line of code but it only help to extract line 1 of all times the string '##XYDATA=(X++(Y..Y))' appeared together. Thus, it did not meet my expect to have three lines and to have a separate pieces of data after each appearance of the string.

```<code>bo<-data.frame(spectra$V1[which(spectra$V1 == '##XYDATA=(X++(Y..Y))')+1])
</code>```

答:
You can do either of the following with split and map:

```<code>library(dplyr)
library(purrr)

df %>%
  mutate(Animal = cumsum(grepl("##XYDATA=(X++(Y..Y))", V1, fixed = TRUE))) %>%
  split(.$Animal) %>%
  map(~slice(., -1) %>% mutate(V1 = as.numeric(V1))) %>%
  '['(-1)
</code>```

This creates an indicator variable Animal, split by that indicator, remove the first row for each dataframe, convert V1 to numeric, and finally remove the first element of the list.

You can also do the following:

```<code>df %>%
  mutate(Animal = cumsum(grepl("##XYDATA=(X++(Y..Y))", V1, fixed = TRUE))) %>%
  filter(!grepl("^#.*$", V1)) %>%
  mutate(V1 = as.numeric(V1)) %>%
  split(.$Animal)
</code>```

This also creates the indicator Animal, but it intead, filters  out all rows with # signs in it and converts V1 to numeric before splitting into separate dataframes.

Result:

```<code>$`1`
# A tibble: 3 x 2
        V1 Animal
     <dbl>  <int>
1 649.0251      1
2 667.6752      1
3 686.3254      1

$`2`
# A tibble: 3 x 2
        V1 Animal
     <dbl>  <int>
1 723.6257      2
2 742.2758      2
3 760.9260      2

$`3`
# A tibble: 4 x 2
        V1 Animal
     <dbl>  <int>
1 872.8268      3
2 891.4770      3
3 910.1271      3
4 928.7773      3
</code>```

Note:

Here I assumed #Milk spectra: 1234 is also a row in your column, hence the subsetting at the end.

Data:

```<code>df = read.table(textConnection("'#Milk spectra: 1234'
                ##XYDATA=(X++(Y..Y))
                649.025085449219
                667.675231457819
                686.325377466418
                ##XYDATA=(X++(Y..Y))
                723.625669483618
                742.275815492218
                760.925961500818
                ##XYDATA=(X++(Y..Y))
                872.826837552417
                891.476983561017
                910.127129569617
                928.777275578216"),comment.char = "", stringsAsFactors = FALSE)
</code>```

Body:
I have a data like this (named spectra):

#Milk spectra: 1234
##XYDATA=(X++(Y..Y))
649.025085449219
667.675231457819
686.325377466418
##XYDATA=(X++(Y..Y))
723.625669483618
742.275815492218
760.925961500818
##XYDATA=(X++(Y..Y))
872.826837552417
891.476983561017
910.127129569617
928.777275578216

In this data, each time the string ##XYDATA=(X++(Y..Y)), that is the data for each different animal.
So, I want to have the code that can help extract this sample into 3 pieces of data.

Animal 1: 3 lines after 1st '  ##XYDATA=(X++(Y..Y))'
Animal 2: 3 lines after 2nd '  ##XYDATA=(X++(Y..Y))'

And so on.

I tried this line of code but it only help to extract line 1 of all times the string '##XYDATA=(X++(Y..Y))' appeared together. Thus, it did not meet my expect to have three lines and to have a separate pieces of data after each appearance of the string.

bo<-data.frame(spectra$V1[which(spectra$V1 == '##XYDATA=(X++(Y..Y))')+1])

Body:
You can do either of the following with split and map:

library(dplyr)
library(purrr)

df %>%
  mutate(Animal = cumsum(grepl("##XYDATA=(X++(Y..Y))", V1, fixed = TRUE))) %>%
  split(.$Animal) %>%
  map(~slice(., -1) %>% mutate(V1 = as.numeric(V1))) %>%
  '['(-1)

This creates an indicator variable Animal, split by that indicator, remove the first row for each dataframe, convert V1 to numeric, and finally remove the first element of the list.

You can also do the following:

df %>%
  mutate(Animal = cumsum(grepl("##XYDATA=(X++(Y..Y))", V1, fixed = TRUE))) %>%
  filter(!grepl("^#.*$", V1)) %>%
  mutate(V1 = as.numeric(V1)) %>%
  split(.$Animal)

This also creates the indicator Animal, but it intead, filters  out all rows with # signs in it and converts V1 to numeric before splitting into separate dataframes.

Result:

$`1`
# A tibble: 3 x 2
        V1 Animal
     <dbl>  <int>
1 649.0251      1
2 667.6752      1
3 686.3254      1

$`2`
# A tibble: 3 x 2
        V1 Animal
     <dbl>  <int>
1 723.6257      2
2 742.2758      2
3 760.9260      2

$`3`
# A tibble: 4 x 2
        V1 Animal
     <dbl>  <int>
1 872.8268      3
2 891.4770      3
3 910.1271      3
4 928.7773      3

Note:

Here I assumed #Milk spectra: 1234 is also a row in your column, hence the subsetting at the end.

Data:

df = read.table(textConnection("'#Milk spectra: 1234'
                ##XYDATA=(X++(Y..Y))
                649.025085449219
                667.675231457819
                686.325377466418
                ##XYDATA=(X++(Y..Y))
                723.625669483618
                742.275815492218
                760.925961500818
                ##XYDATA=(X++(Y..Y))
                872.826837552417
                891.476983561017
                910.127129569617
                928.777275578216"),comment.char = "", stringsAsFactors = FALSE)


问:
FFMpeg combine two separate commands
I am running 2 seperate ffmpeg commands..

```<code>ffmpeg -i video.mp4 -vf scale=1024:768 -crf 0 output_video.mp4

ffmpeg -i output_video.mp4 -s 640x360 -c:v libx264 -preset slow -b:v 650k -r 24 -x264opts keyint=48:min-keyint=48:no-scenecut -profile:v main -preset fast -movflags +faststart -c:a libfdk_aac -b:a 128k -ac 2 out-low.mp4
</code>```

Is there a way I can do both of these commands in once go?  Trying to avoid 2 encoding sessions reducing the quality

答:
Label filter outputs and refer to them in the -map option:

```<code>ffmpeg -i video.mp4 -filter_complex "[0:v]scale=1024:768[v768];[0:v]scale=640:360[v360]"
  -map "[v768]" -map 0:a -c:v libx264 -c:a copy -crf 0 output_video.mp4
  -map "[v360]" -map 0:a -c:v libx264 -preset slow -b:v 650k -r 24 -x264opts keyint=48:min-keyint=48:no-scenecut -profile:v main -preset fast -movflags +faststart -c:a libfdk_aac -b:a 128k -ac 2 out-low.mp4
</code>```

Title: FFMpeg combine two separate commands

Body:
I am running 2 seperate ffmpeg commands..

ffmpeg -i video.mp4 -vf scale=1024:768 -crf 0 output_video.mp4

ffmpeg -i output_video.mp4 -s 640x360 -c:v libx264 -preset slow -b:v 650k -r 24 -x264opts keyint=48:min-keyint=48:no-scenecut -profile:v main -preset fast -movflags +faststart -c:a libfdk_aac -b:a 128k -ac 2 out-low.mp4

Is there a way I can do both of these commands in once go?  Trying to avoid 2 encoding sessions reducing the quality

Body:
Label filter outputs and refer to them in the -map option:

ffmpeg -i video.mp4 -filter_complex "[0:v]scale=1024:768[v768];[0:v]scale=640:360[v360]"
  -map "[v768]" -map 0:a -c:v libx264 -c:a copy -crf 0 output_video.mp4
  -map "[v360]" -map 0:a -c:v libx264 -preset slow -b:v 650k -r 24 -x264opts keyint=48:min-keyint=48:no-scenecut -profile:v main -preset fast -movflags +faststart -c:a libfdk_aac -b:a 128k -ac 2 out-low.mp4


问:
Portability of binary serialization of double/float type in C++
The C++ standard does not discuss the underlying layout of float and double types, only the range of values they should represent.  (This is also true for signed types, is it two's compliment or something else)

My question is: What the are techniques used to serialize/deserialize POD types such as double and float in a portable manner? At the moment it seems the only way to do this is to have the value represented literally(as in "123.456"), The ieee754 layout for double is not standard on all architectures.

答:
I think the answer "depends" on what your particular application and it's perfomance profile is.

Let's say you have a low-latency market data environment, then using strings is frankly daft. If the information you are conveying is prices, then doubles (and binary representation of them) really are tricky to work with. Where as, if you don't really care about performance, and what you want is visibility (storage, transmission), then strings are an ideal candidate.

I would actually opt for integral mantissa/exponent representation of floats/doubles - i.e. at the earliest opportunity, convert the float/double to a pair of integers and then transmit that. You then only have to worry about the portability of integers and well, various routines (such as the hton() routines to handle conversions for you). Also store everything in your most prevalent platform's endianess (for example if you're only using linux, then what's the point of storing stuff in big endian?)

OwnerDisplayName: Matthieu N.

LastEditorDisplayName: Matthieu N.

ContentLicense: CC BY-SA 2.5


问:
Python unittest - opposite of assertRaises?
I want to write a test to establish that an Exception is not raised in a given circumstance.

It's straightforward to test if an Exception is raised ...

```<code>sInvalidPath=AlwaysSuppliesAnInvalidPath()
self.assertRaises(PathIsNotAValidOne, MyObject, sInvalidPath)
</code>```

... but how can you do the opposite.

Something like this i what I'm after ...

```<code>sValidPath=AlwaysSuppliesAValidPath()
self.assertNotRaises(PathIsNotAValidOne, MyObject, sValidPath)
</code>```

答:
I've found it useful to monkey-patch unittest as follows:

```<code>def assertMayRaise(self, exception, expr):
  if exception is None:
    try:
      expr()
    except:
      info = sys.exc_info()
      self.fail('%s raised' % repr(info[0]))
  else:
    self.assertRaises(exception, expr)

unittest.TestCase.assertMayRaise = assertMayRaise
</code>```

This clarifies intent when testing for the absence of an exception:

```<code>self.assertMayRaise(None, does_not_raise)
</code>```

This also simplifies testing in a loop, which I often find myself doing:

```<code># ValueError is raised only for op(x,x), op(y,y) and op(z,z).
for i,(a,b) in enumerate(itertools.product([x,y,z], [x,y,z])):
  self.assertMayRaise(None if i%4 else ValueError, lambda: op(a, b))
</code>```

Body:
I want to write a test to establish that an Exception is not raised in a given circumstance.

It's straightforward to test if an Exception is raised ...

sInvalidPath=AlwaysSuppliesAnInvalidPath()
self.assertRaises(PathIsNotAValidOne, MyObject, sInvalidPath)

... but how can you do the opposite.

Something like this i what I'm after ...

sValidPath=AlwaysSuppliesAValidPath()
self.assertNotRaises(PathIsNotAValidOne, MyObject, sValidPath)

Body:
I've found it useful to monkey-patch unittest as follows:

def assertMayRaise(self, exception, expr):
  if exception is None:
    try:
      expr()
    except:
      info = sys.exc_info()
      self.fail('%s raised' % repr(info[0]))
  else:
    self.assertRaises(exception, expr)

unittest.TestCase.assertMayRaise = assertMayRaise

This clarifies intent when testing for the absence of an exception:

self.assertMayRaise(None, does_not_raise)

This also simplifies testing in a loop, which I often find myself doing:

# ValueError is raised only for op(x,x), op(y,y) and op(z,z).
for i,(a,b) in enumerate(itertools.product([x,y,z], [x,y,z])):
  self.assertMayRaise(None if i%4 else ValueError, lambda: op(a, b))


问:
How to change orientation of a SCNNode to the Camera with ARKit
The code below places a SCNPlane onto the point touched, but the plane is oriented (rotated) to the position that the phone was in when the app started.  I would ideally like to orient the Node to a physical wall or to the current orientation of the camera.  How is this done with ARKit?</p>

```<code>override func touchesBegan(_ touches: Set<UITouch>, with event: UIEvent?) {
    guard let touch = touches.first else {return}
    let result = sceneView.hitTest(touch.location(in: sceneView), types: [ARHitTestResult.ResultType.featurePoint])
    guard let hitResult = result.last else {return}
    let hitTransform = SCNMatrix4.init(hitResult.worldTransform)

    let hitVector = SCNVector3Make(hitTransform.m41, hitTransform.m42, hitTransform.m43)
    createPlane(position: hitVector)
}

func createPlane(position: SCNVector3) {

    let background = SCNNode()
    background.geometry = SCNPlane.init(width: 0.12, height: 0.10) // better set its size
    background.geometry?.firstMaterial?.diffuse.contents = "odinBW2.jpeg"
    background.position = position

    sceneView.scene.rootNode.addChildNode(background)

}
</code>```

答:
1 - This is how you get the rotation of the camera first:

Pitch - rotation around the X axis

```<code>let pitch = sceneView.session.currentFrame?.camera.eulerAngles.x
</code>```

Yawn - rotation around the Y axis

```<code>let yawn = sceneView.session.currentFrame?.camera.eulerAngles.y
</code>```

Roll - rotation around the Z axis

```<code>let roll = sceneView.session.currentFrame?.camera.eulerAngles.z
</code>```

2 - And then you can create the SCNVector3 that matches the rotations you want to keep (0 if you don't want any rotation on an axis) :

```<code>let newRotation = SCNVector3Make(pitch, yawn, roll)
</code>```

3 - And then you attribute this eulerAngles to your node:

```<code>whateverNode.eulerAngles = newRotation
</code>```

Body:
The code below places a SCNPlane onto the point touched, but the plane is oriented (rotated) to the position that the phone was in when the app started.  I would ideally like to orient the Node to a physical wall or to the current orientation of the camera.  How is this done with ARKit?

override func touchesBegan(_ touches: Set<UITouch>, with event: UIEvent?) {
    guard let touch = touches.first else {return}
    let result = sceneView.hitTest(touch.location(in: sceneView), types: [ARHitTestResult.ResultType.featurePoint])
    guard let hitResult = result.last else {return}
    let hitTransform = SCNMatrix4.init(hitResult.worldTransform)

    let hitVector = SCNVector3Make(hitTransform.m41, hitTransform.m42, hitTransform.m43)
    createPlane(position: hitVector)
}

func createPlane(position: SCNVector3) {

    let background = SCNNode()
    background.geometry = SCNPlane.init(width: 0.12, height: 0.10) // better set its size
    background.geometry?.firstMaterial?.diffuse.contents = "odinBW2.jpeg"
    background.position = position

    sceneView.scene.rootNode.addChildNode(background)

}

Body:
1 - This is how you get the rotation of the camera first:

Pitch - rotation around the X axis

let pitch = sceneView.session.currentFrame?.camera.eulerAngles.x

Yawn - rotation around the Y axis

let yawn = sceneView.session.currentFrame?.camera.eulerAngles.y

Roll - rotation around the Z axis

let roll = sceneView.session.currentFrame?.camera.eulerAngles.z

2 - And then you can create the SCNVector3 that matches the rotations you want to keep (0 if you don't want any rotation on an axis) :

let newRotation = SCNVector3Make(pitch, yawn, roll)

3 - And then you attribute this eulerAngles to your node:

whateverNode.eulerAngles = newRotation


问:
Using sed transliterate command in python
So there is this sed command that allows you to transform the quality code in ASCII into bar symbols:

```<code>sed -e 'n;n;n;y/!"#$%&'\''()*+,-.\/0123456789:;<=>?@ABCDEFGHIJKL/▁▁▁▁▁▁▁▁▂▂▂▂▂▃▃▃▃▃▄▄▄▄▄▅▅▅▅▅▆▆▆▆▆▇▇▇▇▇██████/' myfile.fastq
</code>```

I have been checking ways to do the same in python, but I have not found a solution I can use. Maybe pysed or re.sub, but I do not even know how to write the ASCII code in a string without python getting mixed up the characters.

答:
So, you want to transliterate characters in the 3rd line of your FASTQ file?

You can use str.translate on translation table built with str.maketrans:

```<code>#!/usr/bin/env python3
lut = str.maketrans('''!"#$%&'()*+,-./0123456789:;<=>?@ABCDEFGHIJKL''',
                    '''▁▁▁▁▁▁▁▁▂▂▂▂▂▃▃▃▃▃▄▄▄▄▄▅▅▅▅▅▆▆▆▆▆▇▇▇▇▇██████''')

with open('/path/to/fastq') as f:
    line3 = f.readlines()[3].strip()

print(line3.translate(lut))
</code>```

For a sample file from Wikipedia:

```<code>@SEQ_ID
GATTTGGGGTTCAAAGCAGTATCGATCAAATAGTAAATCCATTTGTTCAACTCACAGTTT
+
!''*((((***+))%%%++)(%%%%).1***-+*''))**55CCF>>>>>>CCCCCCC65
</code>```

the Python script above will produce:

```<code>▁▁▁▂▁▁▁▁▂▂▂▂▂▂▁▁▁▂▂▂▁▁▁▁▁▂▃▃▂▂▂▂▂▂▁▁▂▂▂▂▄▄▇▇▇▆▆▆▆▆▆▇▇▇▇▇▇▇▄▄
</code>```

However, note that according to FASTQ format description on Wikipedia, your translation table is incorrect. The character ! represents the lowest quality while ~ is the highest (not L as you have).

Also note that quality value characters directly map the ASCII character range !-~ to the quality value. In other words, we can build the translation table programmatically:

```<code>span = ord('█') - ord('▁') + 1
src = ''.join(chr(c) for c in range(ord('!'), ord('~')+1))
dst = ''.join(chr(ord('▁') + span*(ord(c)-ord('!'))//len(src)) for c in src)
lut = str.maketrans(src, dst)
</code>```

Body:
So there is this sed command that allows you to transform the quality code in ASCII into bar symbols:

sed -e 'n;n;n;y/!"#$%&'\''()*+,-.\/0123456789:;<=>?@ABCDEFGHIJKL/▁▁▁▁▁▁▁▁▂▂▂▂▂▃▃▃▃▃▄▄▄▄▄▅▅▅▅▅▆▆▆▆▆▇▇▇▇▇██████/' myfile.fastq

I have been checking ways to do the same in python, but I have not found a solution I can use. Maybe pysed or re.sub, but I do not even know how to write the ASCII code in a string without python getting mixed up the characters.

Body:
So, you want to transliterate characters in the 3rd line of your FASTQ file?

You can use str.translate on translation table built with str.maketrans:

#!/usr/bin/env python3
lut = str.maketrans('''!"#$%&'()*+,-./0123456789:;<=>?@ABCDEFGHIJKL''',
                    '''▁▁▁▁▁▁▁▁▂▂▂▂▂▃▃▃▃▃▄▄▄▄▄▅▅▅▅▅▆▆▆▆▆▇▇▇▇▇██████''')

with open('/path/to/fastq') as f:
    line3 = f.readlines()[3].strip()

print(line3.translate(lut))

For a sample file from Wikipedia:

@SEQ_ID
GATTTGGGGTTCAAAGCAGTATCGATCAAATAGTAAATCCATTTGTTCAACTCACAGTTT
+
!''*((((***+))%%%++)(%%%%).1***-+*''))**55CCF>>>>>>CCCCCCC65

the Python script above will produce:

▁▁▁▂▁▁▁▁▂▂▂▂▂▂▁▁▁▂▂▂▁▁▁▁▁▂▃▃▂▂▂▂▂▂▁▁▂▂▂▂▄▄▇▇▇▆▆▆▆▆▆▇▇▇▇▇▇▇▄▄

However, note that according to FASTQ format description on Wikipedia, your translation table is incorrect. The character ! represents the lowest quality while ~ is the highest (not L as you have).

Also note that quality value characters directly map the ASCII character range !-~ to the quality value. In other words, we can build the translation table programmatically:

span = ord('█') - ord('▁') + 1
src = ''.join(chr(c) for c in range(ord('!'), ord('~')+1))
dst = ''.join(chr(ord('▁') + span*(ord(c)-ord('!'))//len(src)) for c in src)
lut = str.maketrans(src, dst)


问:
WPF Rotate line with angle from center point
I am trying to draw lines using WPF and c# and Facing the below problem.

Imaging I have to draw  a line with fixed length, I need to rotate this line with the given angle. suppose 45 degree.
But the condition is I should rotate this from center point.
I am attaching the image for clean understanding.

Can any one please help me to write a C# program.

答:
To rotate the line by a custom angle, apply a RotateTransform to it. You can set RenderTransformOrigin property to 0.5 0.5 to rotate around center point.

```<code><Grid Width="200" Height="200">
    <Line X1="0" Y1="0" X2="1" Y2="0" Stretch="Uniform" Stroke="Blue" StrokeThickness="2" RenderTransformOrigin="0.5 0.5">
        <Line.RenderTransform>
            <RotateTransform Angle="45" />
        </Line.RenderTransform>
    </Line>
</Grid>
</code>```

If the angle is fixed (e.g. always the same), you can calculate coordinates of the start and end points, and draw a diagonal line without using transform:

```<code><Line X1="0" Y1="0" X2="200" Y2="200" Stroke="Blue" StrokeThickness="2" />
</code>```

Body:
To rotate the line by a custom angle, apply a RotateTransform to it. You can set RenderTransformOrigin property to 0.5 0.5 to rotate around center point.

<Grid Width="200" Height="200">
    <Line X1="0" Y1="0" X2="1" Y2="0" Stretch="Uniform" Stroke="Blue" StrokeThickness="2" RenderTransformOrigin="0.5 0.5">
        <Line.RenderTransform>
            <RotateTransform Angle="45" />
        </Line.RenderTransform>
    </Line>
</Grid>

If the angle is fixed (e.g. always the same), you can calculate coordinates of the start and end points, and draw a diagonal line without using transform:

<Line X1="0" Y1="0" X2="200" Y2="200" Stroke="Blue" StrokeThickness="2" />


问:
Keras categorical model
I'm trying to create a Keras deep learning algorithm to identify coniferous and leafed trees from a false-colour orthophoto. I have extracted around 4 500 training/validation images which are considered to be correct, such as here and here. The pixel size in real-world is 0,5 meters so these are not really high-res images. All images are fixed-size 31x31 px. The following model is a product of googling, especially Keras' own documentation site.

```<code>from keras.preprocessing.image import ImageDataGenerator
from keras.models import Sequential
from keras.layers import Conv2D, MaxPooling2D
from keras.layers import Activation, Dropout, Flatten, Dense
from keras import backend as K

# dimensions of our images.
img_width, img_height = 30, 30

train_data_dir = 'treedata/train'
validation_data_dir = 'treedata/validation'
nb_train_samples = 4000
nb_validation_samples = 533
epochs = 50
batch_size = 16

if K.image_data_format() == 'channels_first':
    input_shape = (3, img_width, img_height)
else:
    input_shape = (img_width, img_height, 3)

model = Sequential()

model.add(Conv2D(32, (3, 3), input_shape=input_shape))
model.add(Activation('relu'))
model.add(MaxPooling2D(pool_size=(2, 2)))

model.add(Flatten())
model.add(Dense(64))
model.add(Dropout(0.5))

model.add(Activation('relu'))
model.add(Dense(2)) # number of classes
model.add(Activation('softmax'))

model.compile(loss='categorical_crossentropy',
          optimizer='rmsprop',
          metrics=['accuracy'])

# this is the augmentation configuration we will use for training
train_datagen = ImageDataGenerator(
    rescale=1. / 255,
    shear_range=0.2,
    zoom_range=0.2,
    horizontal_flip=True)

# this is the augmentation configuration we will use for testing:
# only rescaling
test_datagen = ImageDataGenerator(rescale=1. / 255)

train_generator = train_datagen.flow_from_directory(
    train_data_dir,
    target_size=(img_width, img_height),
    batch_size=batch_size,
    class_mode='categorical')

validation_generator = test_datagen.flow_from_directory(
    validation_data_dir,
    target_size=(img_width, img_height),
    batch_size=batch_size,
    class_mode='categorical')

model.fit_generator(
    train_generator,
    steps_per_epoch=nb_train_samples // batch_size,
    epochs=epochs,
    validation_data=validation_generator,
    validation_steps=nb_validation_samples // batch_size)

model.save('treetypes.h5')
</code>```

From epoch 2 onwards, the accuracy claims to be > 0.99 and loss < 0.02, which I find odd. After creating the model, I try to go through an orthophoto and decide if one 30x30 px sub-image contains a tree of given type.

```<code>import numpy as np
import cv2
from keras.models import load_model
from keras.preprocessing import image

model = load_model('treetypes.h5')
roi = cv2.imread('roi.jpg')
sy, sx = img.shape[:2]
px_apart = 10 # start sub-images 10 px apart
s = 30 # sub-image size

for starty in range(1, sy-img_height, px_apart):

    for startx in range(1, sx-img_width, px_apart):

        subimg = img[starty:starty+s, startx:startx+s]
        x = image.img_to_array(subimg)
        x = np.expand_dims(x, axis=0)
        is_tree = model.predict(x, batch_size=1, verbose=0) # predict classes
</code>```

This is where I get lost. First and foremost, there seems not to be a choice that a sub-image is neither a coniferous nor leafed tree (all sub-images get predicted either is_tree = [[0, 1]] or is_tree = [[1, 0]]). There are not for example predictions [[0.1, 0.02]], which would suggest that this sub-image is not a tree at all. Thus, two main questions:

1) Have I understood correctly that the model should output probabilities for belonging to class 1 (coniferous) and class 2 (leafed)? Why it does give only "binary" results? I read somewhere that softmax scales sum of probabilities to 1.

2) Is my model anywhere near usable? Or is it even viable to use NN for this, given coarse sample resolution? I suspect some overfitting for my model...

Thanks in advance if anyone has time to take on this!

答:
If you use softmax, the sum of the two classes will be 1. That means you will never get a "no tree" result.

But if you change the activation to "sigmoid", then you can have both zeros (and also both 1). You might, if your model or your data is not that good, end up with "yes to coniferous" and "yes to leafed".

You may also try an approach of creating three classes instead, and go back to softmax. Class1 = coniferous; Class2 = leafed; Class3 = None.

About your model.

Well, this is an art. Only testing a lot and reading success cases you will find the best model for the task.

Title: Keras categorical model

Body:
I'm trying to create a Keras deep learning algorithm to identify coniferous and leafed trees from a false-colour orthophoto. I have extracted around 4 500 training/validation images which are considered to be correct, such as here and here. The pixel size in real-world is 0,5 meters so these are not really high-res images. All images are fixed-size 31x31 px. The following model is a product of googling, especially Keras' own documentation site.

from keras.preprocessing.image import ImageDataGenerator
from keras.models import Sequential
from keras.layers import Conv2D, MaxPooling2D
from keras.layers import Activation, Dropout, Flatten, Dense
from keras import backend as K

# dimensions of our images.
img_width, img_height = 30, 30

train_data_dir = 'treedata/train'
validation_data_dir = 'treedata/validation'
nb_train_samples = 4000
nb_validation_samples = 533
epochs = 50
batch_size = 16

if K.image_data_format() == 'channels_first':
    input_shape = (3, img_width, img_height)
else:
    input_shape = (img_width, img_height, 3)

model = Sequential()

model.add(Conv2D(32, (3, 3), input_shape=input_shape))
model.add(Activation('relu'))
model.add(MaxPooling2D(pool_size=(2, 2)))

model.add(Flatten())
model.add(Dense(64))
model.add(Dropout(0.5))

model.add(Activation('relu'))
model.add(Dense(2)) # number of classes
model.add(Activation('softmax'))

model.compile(loss='categorical_crossentropy',
          optimizer='rmsprop',
          metrics=['accuracy'])

# this is the augmentation configuration we will use for training
train_datagen = ImageDataGenerator(
    rescale=1. / 255,
    shear_range=0.2,
    zoom_range=0.2,
    horizontal_flip=True)

# this is the augmentation configuration we will use for testing:
# only rescaling
test_datagen = ImageDataGenerator(rescale=1. / 255)

train_generator = train_datagen.flow_from_directory(
    train_data_dir,
    target_size=(img_width, img_height),
    batch_size=batch_size,
    class_mode='categorical')

validation_generator = test_datagen.flow_from_directory(
    validation_data_dir,
    target_size=(img_width, img_height),
    batch_size=batch_size,
    class_mode='categorical')

model.fit_generator(
    train_generator,
    steps_per_epoch=nb_train_samples // batch_size,
    epochs=epochs,
    validation_data=validation_generator,
    validation_steps=nb_validation_samples // batch_size)

model.save('treetypes.h5')

From epoch 2 onwards, the accuracy claims to be > 0.99 and loss < 0.02, which I find odd. After creating the model, I try to go through an orthophoto and decide if one 30x30 px sub-image contains a tree of given type.

import numpy as np
import cv2
from keras.models import load_model
from keras.preprocessing import image

model = load_model('treetypes.h5')
roi = cv2.imread('roi.jpg')
sy, sx = img.shape[:2]
px_apart = 10 # start sub-images 10 px apart
s = 30 # sub-image size

for starty in range(1, sy-img_height, px_apart):

    for startx in range(1, sx-img_width, px_apart):

        subimg = img[starty:starty+s, startx:startx+s]
        x = image.img_to_array(subimg)
        x = np.expand_dims(x, axis=0)
        is_tree = model.predict(x, batch_size=1, verbose=0) # predict classes

This is where I get lost. First and foremost, there seems not to be a choice that a sub-image is neither a coniferous nor leafed tree (all sub-images get predicted either is_tree = [[0, 1]] or is_tree = [[1, 0]]). There are not for example predictions [[0.1, 0.02]], which would suggest that this sub-image is not a tree at all. Thus, two main questions:

1) Have I understood correctly that the model should output probabilities for belonging to class 1 (coniferous) and class 2 (leafed)? Why it does give only "binary" results? I read somewhere that softmax scales sum of probabilities to 1.

2) Is my model anywhere near usable? Or is it even viable to use NN for this, given coarse sample resolution? I suspect some overfitting for my model...

Thanks in advance if anyone has time to take on this!


问:
Execute button's command after the animation
In my application i have added a frame-by-frame animation to my button's selector. So, when I press the button the application is started and another activity is launched. The problem is that if I press the button very quickly the application reaches only to the second frame. I would like to launch the next activity after the animation is ended. Is that possible?</p>

答: You may use handler.postDelayed(Runnable); with your delay;

ContentLicense: CC BY-SA 4.0


问:
React Native: setState() does not re-render FlatList child component
In short, I have been following a tutorial found here.

It makes sense and it works, however, I have trouble understanding why the FlatList component needs to be assigned a prop to which a state is associated in order to re-render it when the state changes. If I omit the extraData prop as per the example, the FlatList doesn't get re-rendered. I thought setState() was supposed to re-render a component and all its children, but it doesn't in this instance: am I missing something here?

Thank you.

答: After reading more attentively the documentation for the FlatList component (thanks, @Lucas Reppe Welander), it has emerged that a FlatList is not a regular component, but it's actually a PureComponent. That means that even if the parent component's state changes, the FlatList's "prop comparison will not show any changes", because PureComponent "implements shouldComponentUpdate() with a shallow prop and state comparison". I'm not entirely sure about all the intricacies this entails, but it's enough for me to understand why I need to use the extraData prop in this instance.


答:
You're doing >/< comparisons with strings. Those work on unicode point values, which is rarely what you want. Change this:

```<code>  var aID = a.id.toLowerCase();
  var bID = b.id.toLowerCase();
  var aName = a.name.toLowerCase();
  var bName = b.name.toLowerCase();
</code>```

To this:

```<code>  var reg = /\d+/; // matches 1 or more number characters
  var aID = +a.id.match(reg)[0]; // unary + coerces to number
  var bID = +b.id.match(reg)[0];
  var aName = +a.name.match(reg)[0];
  var bName = +b.name.match(reg)[0];
</code>```

Now you're comparisons will be on the actual number values in the strings.

Title: Sorting array by 2 conditions in Javascript not working

Body:
I want to sort an array of objects by both id and name. First it should be sorted by id in ascending order. Then it should be sorted by name in ascending order.

Sort function

Currently the sorted list shows up like this:

{id: "ts1", name: "TS1"}
{id: "ts10", name: "TS10"}
{id: "ts11", name: "TS11"}
{id: "ts12", name: "TS12"}
{id: "ts13", name: "TS1"}
{id: "ts13", name: "TS2"}
{id: "ts13", name: "TS3"}
{id: "ts14", name: "TS14"}
{id: "ts15", name: "TS15"}
{id: "ts16", name: "TS16"}
....

The ideal state is like this

{id: "ts1", name: "TS1"}
{id: "ts2", name: "TS2"}
...
{id: "ts10", name: "TS10"}
{id: "ts11", name: "TS11"}
{id: "ts12", name: "TS12"}
{id: "ts13", name: "TS1"}
{id: "ts13", name: "TS2"}
{id: "ts13", name: "TS3"}
{id: "ts14", name: "TS14"}
{id: "ts15", name: "TS15"}
{id: "ts16", name: "TS16"}
....

The function works only when the list is very short, but when the list is long it doesn't work well. See live demo- https://jsfiddle.net/0xLd6sms/2/

Body:
You're doing >/< comparisons with strings. Those work on unicode point values, which is rarely what you want. Change this:

  var aID = a.id.toLowerCase();
  var bID = b.id.toLowerCase();
  var aName = a.name.toLowerCase();
  var bName = b.name.toLowerCase();

To this:

  var reg = /\d+/; // matches 1 or more number characters
  var aID = +a.id.match(reg)[0]; // unary + coerces to number
  var bID = +b.id.match(reg)[0];
  var aName = +a.name.match(reg)[0];
  var bName = +b.name.match(reg)[0];

Now you're comparisons will be on the actual number values in the strings.


问:
Marklogic Optic API
I've been testing migrating one of our systems to Marklogic 9 and using the Optics API.

One of our functions involves grouping claims by member_id, member_name and getting the sums and counts, so I did something like this:

```<code>var results = op.fromView('test', 'claims')
  .groupBy(['member_id', 'member_name'], [
         op.count('num_claims', 'claim_no'),
         op.sum('total_amount', 'claim_amount')
         ])
  .orderBy(op.desc('total_amount'))
  .limit(200)
  .result()
  .toArray();
</code>```

Above works fine. The results are of the form

```<code>[
  {
    member_id: 1,
    member_name: 'Bob',
    num_claims: 10,
    total_amount: 500
  },
  ...
]
</code>```

However, we also have a field "company", where each claim is filed under a different company. Basically the relevant view columns are claim_no, member_id, member_name, company, claim_amount

I would like to be able to show a column that list the different companies for which the member_id/member_name has filed claims, and how many claims for each company.

i.e. I want my results to be something like:

```<code>[
  {
    member_id: 1,
    member_name: 'Bob',
    num_claims: 10,
    total_amount: 500,
    companies: [
      {
        company: 'Ajax Co',
        num_claims: 8
      },
      {
        company: 'Side Gig',
        num_claims: 2
      }
    ]
  },
  ...
]
</code>```

I tried something like this:

```<code>results = results.map((member, index, array) => {
  var companies = op.fromView('test', 'claims')
    .where(op.eq(op.col('member_id'), member.member_id))
    .groupBy('company', [
      op.count('num_claims', 'claim_no')
    ])
    .result()
    .toArray();
  member.companies = companies;
  return member;
});
</code>```

And the output seems correct, but it also executes quite slowly - almost a minute (total number of claim documents is around 120k)

In our previous ML8 implementation, we were pre-generating summary documents for each member - so retrieval was reasonably fast with the downside that whenever we got a bunch of new data, all of the summary documents had to be re-generated. I was hoping that ML9's optic API would make it easier to do the retrieval/grouping/aggregates on the fly so we wouldn't have to do that.

In theory, I could just add company to the groupBy fields, then merge the rows in the result query as needed. But the problem with that approach is that I can't guarantee I'll get the top 200 by total amount (as was my original query)

So, the question is: Is there a better way of doing this with a reasonable execution time? Or should I just stick to pre-generating the summary documents?

答:
If I'm understanding correctly, you should be able to implement that with a single Optic query that groups twice.

The first group should aggregate to the company level

The second group should aggregate to the member level, collecting the detail with the array aggregate

The query would probably look something like the following:

```<code>const results =
  op.fromView('test', 'claims')
    .groupBy(['member_id', 'company'], [
        'member_name',
        op.count('company_claims', 'claim_no'),
        op.sum('company_amount', 'claim_amount')
        ])
    .select(['member_id',
        'member_name',
        'company_claims',
        'company_amount',
        op.as('company_desc', op.jsonObject([
                op.prop('company',    op.col('company')),
                op.prop('num_claims', op.col('company_claims'))
                ]))
        ])
    .groupBy(['member_id'], [
        'member_name',
        op.sum('num_claims',   'company_claims'),
        op.sum('total_amount', 'company_amount'),
        op.arrayAggregate('companies', 'company_desc')
        ])
    .orderBy(op.desc('total_amount'))
    .limit(200)
    .result()
    .toArray();
</code>```

By the way, if you specify a column in the aggregates list, it is sampled.  Where the column has the same value for the entire group (which I presume is the case with "member_name"), you can sample it instead of specifying it as an additional grouping key.

Also, in modern JavaScript var is usually avoided in favor of const or let.

Hoping that helps,

Title: Marklogic Optic API

Body:
I've been testing migrating one of our systems to Marklogic 9 and using the Optics API.

One of our functions involves grouping claims by member_id, member_name and getting the sums and counts, so I did something like this:

var results = op.fromView('test', 'claims')
  .groupBy(['member_id', 'member_name'], [
         op.count('num_claims', 'claim_no'),
         op.sum('total_amount', 'claim_amount')
         ])
  .orderBy(op.desc('total_amount'))
  .limit(200)
  .result()
  .toArray();

Above works fine. The results are of the form

[
  {
    member_id: 1,
    member_name: 'Bob',
    num_claims: 10,
    total_amount: 500
  },
  ...
]

However, we also have a field "company", where each claim is filed under a different company. Basically the relevant view columns are claim_no, member_id, member_name, company, claim_amount

I would like to be able to show a column that list the different companies for which the member_id/member_name has filed claims, and how many claims for each company.

i.e. I want my results to be something like:

[
  {
    member_id: 1,
    member_name: 'Bob',
    num_claims: 10,
    total_amount: 500,
    companies: [
      {
        company: 'Ajax Co',
        num_claims: 8
      },
      {
        company: 'Side Gig',
        num_claims: 2
      }
    ]
  },
  ...
]

I tried something like this:

results = results.map((member, index, array) => {
  var companies = op.fromView('test', 'claims')
    .where(op.eq(op.col('member_id'), member.member_id))
    .groupBy('company', [
      op.count('num_claims', 'claim_no')
    ])
    .result()
    .toArray();
  member.companies = companies;
  return member;
});

And the output seems correct, but it also executes quite slowly - almost a minute (total number of claim documents is around 120k)

In our previous ML8 implementation, we were pre-generating summary documents for each member - so retrieval was reasonably fast with the downside that whenever we got a bunch of new data, all of the summary documents had to be re-generated. I was hoping that ML9's optic API would make it easier to do the retrieval/grouping/aggregates on the fly so we wouldn't have to do that.

In theory, I could just add company to the groupBy fields, then merge the rows in the result query as needed. But the problem with that approach is that I can't guarantee I'll get the top 200 by total amount (as was my original query)

So, the question is: Is there a better way of doing this with a reasonable execution time? Or should I just stick to pre-generating the summary documents?

Body:
If I'm understanding correctly, you should be able to implement that with a single Optic query that groups twice.

The first group should aggregate to the company level

The second group should aggregate to the member level, collecting the detail with the array aggregate

The query would probably look something like the following:

const results =
  op.fromView('test', 'claims')
    .groupBy(['member_id', 'company'], [
        'member_name',
        op.count('company_claims', 'claim_no'),
        op.sum('company_amount', 'claim_amount')
        ])
    .select(['member_id',
        'member_name',
        'company_claims',
        'company_amount',
        op.as('company_desc', op.jsonObject([
                op.prop('company',    op.col('company')),
                op.prop('num_claims', op.col('company_claims'))
                ]))
        ])
    .groupBy(['member_id'], [
        'member_name',
        op.sum('num_claims',   'company_claims'),
        op.sum('total_amount', 'company_amount'),
        op.arrayAggregate('companies', 'company_desc')
        ])
    .orderBy(op.desc('total_amount'))
    .limit(200)
    .result()
    .toArray();

By the way, if you specify a column in the aggregates list, it is sampled.  Where the column has the same value for the entire group (which I presume is the case with "member_name"), you can sample it instead of specifying it as an additional grouping key.

Also, in modern JavaScript var is usually avoided in favor of const or let.

Hoping that helps,