问:
One row per group with multiple column sorting
Would like to return one row per group, where the one is selected by multiple sort columns. Treading lightly here in the land of greatest-n-per-group to avoid a duplicate question.

SCHEMA:

```<code>CREATE TABLE logs (
  id INT NOT NULL,
  ip_address INT NOT NULL,
  status INT NOT NULL,
  PRIMARY KEY id
);
</code>```

DATA:

```<code>INSERT INTO logs (id, ip_address, status)
VALUES ('1', 19216800, 1),
       ('2', 19216801, 2),
       ('3', 19216800, 2),
       ('4', 19216803, 0),
       ('5', 19216804, 0),
       ('6', 19216803, 0),
       ('7', 19216804, 1);
</code>```

CURRENT QUERY:

```<code>SELECT *
  FROM logs
 ORDER BY ip_address, status=1 DESC, id DESC
</code>```

Note: sorting by status=1 effectively turns the status column into a boolean. The tie breaker after status=1 is id. This query currently returns the correct row for each ip_address first and then a bunch of other rows I don't want for that ip_address.

CURRENT OUTPUT:

```<code>1, 19216800, 1
3, 19216800, 2
2, 19216801, 2
6, 19216803, 0
4, 19216803, 0
7, 19216804, 1
5, 19216804, 0
</code>```

WANTED OUTPUT:

```<code>1, 19216800, 1
2, 19216801, 2
6, 19216803, 0
7, 19216804, 1
</code>```

Today my workaround is to filter in PHP with if ($lastIP == $row['ip_address']) continue;. But I would like to move this logic to MySQL.

答:
Try this:</p>

```<code>SELECT
l.`ip_address` , l.`status`
FROM
  `logs` l
GROUP BY l.`ip_address`
ORDER BY l.`status` = 1 DESC
</code>```

Body:
Would like to return one row per group, where the one is selected by multiple sort columns. Treading lightly here in the land of greatest-n-per-group to avoid a duplicate question.

SCHEMA:

CREATE TABLE logs (
  id INT NOT NULL,
  ip_address INT NOT NULL,
  status INT NOT NULL,
  PRIMARY KEY id
);

DATA:

INSERT INTO logs (id, ip_address, status)
VALUES ('1', 19216800, 1),
       ('2', 19216801, 2),
       ('3', 19216800, 2),
       ('4', 19216803, 0),
       ('5', 19216804, 0),
       ('6', 19216803, 0),
       ('7', 19216804, 1);

CURRENT QUERY:

SELECT *
  FROM logs
 ORDER BY ip_address, status=1 DESC, id DESC

Note: sorting by status=1 effectively turns the status column into a boolean. The tie breaker after status=1 is id. This query currently returns the correct row for each ip_address first and then a bunch of other rows I don't want for that ip_address.

CURRENT OUTPUT:

1, 19216800, 1
3, 19216800, 2
2, 19216801, 2
6, 19216803, 0
4, 19216803, 0
7, 19216804, 1
5, 19216804, 0

WANTED OUTPUT:

1, 19216800, 1
2, 19216801, 2
6, 19216803, 0
7, 19216804, 1

Today my workaround is to filter in PHP with if ($lastIP == $row['ip_address']) continue;. But I would like to move this logic to MySQL.

Body:
Try this:

SELECT
l.`ip_address` , l.`status`
FROM
  `logs` l
GROUP BY l.`ip_address`
ORDER BY l.`status` = 1 DESC


来源: stackexchange

问:
Add-AzureRmServiceFabricClusterCertificate ends with error 'Certificates cannot be added and removed at the same time.'
I try to rollover the cluster-certificate of a service fabric cluster. So I tried to inject a new self-signed secondary certificate with this command:

```<code>Add-AzureRmServiceFabricClusterCertificate -ResourceGroupName $configuration.ResourceGroupName -Name $clusterName -SecretIdentifier $certificateVaultUrl_Secondary
</code>```

ErrorDetails

```<code>"error": {
   "code": "AddAndRemoveCertificateNotAllowed",
   "message": "Certificates cannot be added and removed at the same time.",
   "details": []
}
</code>```

Environment

AzureRM 5.0.1

Powershell 5.0.10586.117

Service Fabric 6.0.232.9494

答:
When using the ARM deployment, the same error message appears.

At the moment (Nov 2017), modifying the cluster certificate thumbprints is not possible. Working workflow:

Delete the existing secondary thumbprint using the portal (triggers a cluster upgrade)

Use the ARM deployment to specify the location and thumbprint of the new secondary certificate (triggers a cluster upgrade)

swap the secondary certificate with the primary using portal (triggers a cluster upgrade)

delete the secondary thumbprint using the portal -> this will delete the old primary certificate (triggers a cluster upgrade)

That's the only workflow we found to provide a new certificate to the cluster.

ContentLicense: CC BY-SA 3.0

Body:
I try to rollover the cluster-certificate of a service fabric cluster. So I tried to inject a new self-signed secondary certificate with this command:

Add-AzureRmServiceFabricClusterCertificate -ResourceGroupName $configuration.ResourceGroupName -Name $clusterName -SecretIdentifier $certificateVaultUrl_Secondary

ErrorDetails

"error": {
   "code": "AddAndRemoveCertificateNotAllowed",
   "message": "Certificates cannot be added and removed at the same time.",
   "details": []
}

Environment

AzureRM 5.0.1

Powershell 5.0.10586.117

Service Fabric 6.0.232.9494


问:
Does python's Pool() for parallelization prevent writing to global variables?
In python 2.7 I am trying to distribute the computation of a two-dimensional array on all of the cores.

For that I have two arrays associated with a variable at the global scope, one to read from and one to write to.

```<code>import itertools as it
import multiprocessing as mp

temp_env = 20
c = 0.25
a = 0.02
arr = np.ones((100,100))
x = arr.shape[0]
y = arr.shape[1]
new_arr = np.zeros((x,y))

def calc_inside(idx):
    new_arr[idx[0],idx[1]] = (       arr[idx[0],  idx[1]  ]
                             + c * ( arr[idx[0]+1,idx[1]  ]
                                   + arr[idx[0]-1,idx[1]  ]
                                   + arr[idx[0],  idx[1]+1]
                                   + arr[idx[0],  idx[1]-1]
                                   - arr[idx[0],  idx[1]  ]*4
                                     )
                             - 2 * a
                                 * ( arr[idx[0],  idx[1]  ]
                                   - temp_env
                                     )
                               )

inputs = it.product( range( 1, x-1 ),
                     range( 1, y-1 )
                     )
p = mp.Pool()
p.map( calc_inside, inputs )

#for i in inputs:
#    calc_inside(i)

#plot arrays as surface plot to check values
</code>```

Assume there is some additional initialization for the array arr with some different values other than that exemplary 1-s, so that the computation ( an iterative calculation of the temperature ) actually makes a sense.

When I use the commented out for-loop, instead of the Pool.map() method, everything works fine and the array actually contains values. When using the Pool() function, the variable new_array just stays in its initialized state ( meaning it contains only the zeros, as it was originally initialised with ).

Q1 : Does that mean that Pool() prevents writing to global variables?

Q2 : Is there any other way to tackle this problem with parallelization?

答:
A1 :

your code actually does not use any variable declared using a syntax of global <variable>. Nevertheless, do not try to go into trying to use them, the less in going into distributed processing.

A2 :

Yes, going parallelised is possible, but better get a thorough sense of the costs of doing so, before spending ( well, wasting ) efforts, that never justify costs for doing so.

Why starting about costs?

Will you pay your bank clerk an amount of $2.00 to receive just a $1.00 banknote in exchange?

Guess no one would ever do.

The same is with trying to go parallel.

Syntax is "free" and "promising",
Syntax costs of the actual execution of a simple and nicely-looking syntax-constructor is not. Expect rather shocking surprises instead of receiving any dinner for free.

What are the actual costs? Benchmark. Benchmark. Benchmark!

The useful work

Your code actually does just a few memory accesses and a few floating point operations "inside" the block and exits. These FLOP-s take less than a few tens of [ns] max a few units of [us] on recent CPU frequencies ~ 2.6 ~ 3.4 [GHz]. Do benchmark it:

```<code>from zmq import Stopwatch; aClk = Stopwatch()

temp_env = 20
c        =  0.25
a        =  0.02

aClk.start()
_ = ( 1.0
    + c * ( 1.0
          + 1.0
          + 1.0
          + 1.0
          - 1.0 * 4
            )
    - 2 * a
        * ( 1.0
          - temp_env
            )
      )
T = aClk.stop()
</code>```

So, a pure [SERIAL]-process execution, on a Quad-core CPU, will not be worse than about a T+T+T+T ( having been executed one after another ).

```<code>         +-+-+-+--------------------------------- on CpuCore[0]
         : : : :
<start>| : : : :
       |T| : : :
       . |T| : :
       .   |T| :
       .     |T|
       .       |<stop>
       |<----->|
        = 4.T in a pure [SERIAL]-process schedule on CpuCore[0]
</code>```

What will happen, if the same amount of usefull work will be enforced to happen inside some form of the now [CONCURRENT]-process execution ( using multiprocessing.Pool's methods ), potentially using more CPU-cores for the same purpose?

The actual compute-phase, will not last less than T again, right? Why ever would it be? Yes, never.

```<code>                               A.......................B...............C.D Cpu[0]
<start>|                       :                       :               : :
       |<setup a subprocess[A]>|                       :               :
       .                       |                       :
       .                       |<setup a subprocess[B]>|
       .                       | +............+........................... Cpu[!0]
       .                       | :            :        |
       .                       |T|            :        |
       .                         |<ret val(s) |        | +............+... Cpu[!0]
       .                         |   [A]->main|        | :            :
       .                                               |T|            :
       .                                                 |<ret val(s) |
       .                                                 |   [B]->main|
       .
       .
       .                                                           ..   |<stop>
       |<--------------------------------------------------------- .. ->|
           i.e. >> 4.T ( while simplified, yet the message is clear )
</code>```

The overheads i.e. the Costs you will always pay per-call ( and that is indeed many times )

Subprocess setup + termination costs ( benchmark it to learn the scales of these cost ). Memory access costs ( latency, where zero cache-re-use happens to help, as you exit ).

Epilogue

Hope the visual message is clear enough to ALWAYS start accounting the accrued costs before deciding about any achievable benefits from going into re-engineering code into a distributed process-flow, having a multi-core or even many-core [CONCURRENT] fabric available.

Body:
In python 2.7 I am trying to distribute the computation of a two-dimensional array on all of the cores.

For that I have two arrays associated with a variable at the global scope, one to read from and one to write to.

import itertools as it
import multiprocessing as mp

temp_env = 20
c = 0.25
a = 0.02
arr = np.ones((100,100))
x = arr.shape[0]
y = arr.shape[1]
new_arr = np.zeros((x,y))

def calc_inside(idx):
    new_arr[idx[0],idx[1]] = (       arr[idx[0],  idx[1]  ]
                             + c * ( arr[idx[0]+1,idx[1]  ]
                                   + arr[idx[0]-1,idx[1]  ]
                                   + arr[idx[0],  idx[1]+1]
                                   + arr[idx[0],  idx[1]-1]
                                   - arr[idx[0],  idx[1]  ]*4
                                     )
                             - 2 * a
                                 * ( arr[idx[0],  idx[1]  ]
                                   - temp_env
                                     )
                               )

inputs = it.product( range( 1, x-1 ),
                     range( 1, y-1 )
                     )
p = mp.Pool()
p.map( calc_inside, inputs )

#for i in inputs:
#    calc_inside(i)

#plot arrays as surface plot to check values

Assume there is some additional initialization for the array arr with some different values other than that exemplary 1-s, so that the computation ( an iterative calculation of the temperature ) actually makes a sense.

When I use the commented out for-loop, instead of the Pool.map() method, everything works fine and the array actually contains values. When using the Pool() function, the variable new_array just stays in its initialized state ( meaning it contains only the zeros, as it was originally initialised with ).

Q1 : Does that mean that Pool() prevents writing to global variables?

Q2 : Is there any other way to tackle this problem with parallelization?

Body:
A1 :

your code actually does not use any variable declared using a syntax of global <variable>. Nevertheless, do not try to go into trying to use them, the less in going into distributed processing.

A2 :

Yes, going parallelised is possible, but better get a thorough sense of the costs of doing so, before spending ( well, wasting ) efforts, that never justify costs for doing so.

Why starting about costs?

Will you pay your bank clerk an amount of $2.00 to receive just a $1.00 banknote in exchange?

Guess no one would ever do.

The same is with trying to go parallel.

Syntax is "free" and "promising",
Syntax costs of the actual execution of a simple and nicely-looking syntax-constructor is not. Expect rather shocking surprises instead of receiving any dinner for free.

What are the actual costs? Benchmark. Benchmark. Benchmark!

The useful work

Your code actually does just a few memory accesses and a few floating point operations "inside" the block and exits. These FLOP-s take less than a few tens of [ns] max a few units of [us] on recent CPU frequencies ~ 2.6 ~ 3.4 [GHz]. Do benchmark it:

from zmq import Stopwatch; aClk = Stopwatch()

temp_env = 20
c        =  0.25
a        =  0.02

aClk.start()
_ = ( 1.0
    + c * ( 1.0
          + 1.0
          + 1.0
          + 1.0
          - 1.0 * 4
            )
    - 2 * a
        * ( 1.0
          - temp_env
            )
      )
T = aClk.stop()

So, a pure [SERIAL]-process execution, on a Quad-core CPU, will not be worse than about a T+T+T+T ( having been executed one after another ).

         +-+-+-+--------------------------------- on CpuCore[0]
         : : : :
<start>| : : : :
       |T| : : :
       . |T| : :
       .   |T| :
       .     |T|
       .       |<stop>
       |<----->|
        = 4.T in a pure [SERIAL]-process schedule on CpuCore[0]

What will happen, if the same amount of usefull work will be enforced to happen inside some form of the now [CONCURRENT]-process execution ( using multiprocessing.Pool's methods ), potentially using more CPU-cores for the same purpose?

The actual compute-phase, will not last less than T again, right? Why ever would it be? Yes, never.

                               A.......................B...............C.D Cpu[0]
<start>|                       :                       :               : :
       |<setup a subprocess[A]>|                       :               :
       .                       |                       :
       .                       |<setup a subprocess[B]>|
       .                       | +............+........................... Cpu[!0]
       .                       | :            :        |
       .                       |T|            :        |
       .                         |<ret val(s) |        | +............+... Cpu[!0]
       .                         |   [A]->main|        | :            :
       .                                               |T|            :
       .                                                 |<ret val(s) |
       .                                                 |   [B]->main|
       .
       .
       .                                                           ..   |<stop>
       |<--------------------------------------------------------- .. ->|
           i.e. >> 4.T ( while simplified, yet the message is clear )

The overheads i.e. the Costs you will always pay per-call ( and that is indeed many times )

Subprocess setup + termination costs ( benchmark it to learn the scales of these cost ). Memory access costs ( latency, where zero cache-re-use happens to help, as you exit ).

Epilogue

Hope the visual message is clear enough to ALWAYS start accounting the accrued costs before deciding about any achievable benefits from going into re-engineering code into a distributed process-flow, having a multi-core or even many-core [CONCURRENT] fabric available.

ContentLicense: CC BY-SA 4.0


问:
Tipfy: How to display blob in template?
Given is on gae using tipfy (python) the following model:

```<code>greeting.avatar = db.Blob(avatar)
</code>```

What is the template-tag to display a blob (here image)?

答:
There isn't a built-in template tag for displaying arbitrary data like that.  I can think of two approaches:

Write a request handler for serving avatars as images.  Based on your example, request handler would just need to look up the greeting to get the image data, send an appropriate Content-Type: image/jpeg (or image/png or whatever) header and then write the blob data to the response stream.

Then, in your template, you'd display the image like this:

```<code><img src="/show-avatar/{{ greeting.key().id() }}">
</code>```

Write a custom template tag/template filter that takes the blob data and generates an appropiate data URL, which would encode the image data directly in the HTML document you're generating.

Then, in your template, you'd display the image something like this:

```<code><img src="{{ greeting.avatar|dataurl }}">
</code>```

which would result in output along these lines in the template:

```<code><img src="data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAoAAAAKCAYAAACNMs+9AAAABGdBTUEAALGPC/xhBQAAAAlwSFlzAAALEwAACxMBAJqcGAAAAAd0SU1FB9YGARc5KB0XV+IAAAAddEVYdENvbW1lbnQAQ3JlYXRlZCB3aXRoIFRoZSBHSU1Q72QlbgAAAF1JREFUGNO9zL0NglAAxPEfdLTs4BZM4DIO4C7OwQg2JoQ9LE1exdlYvBBeZ7jqch9//q1uH4TLzw4d6+ErXMMcXuHWxId3KOETnnXXV6MJpcq2MLaI97CER3N0vr4MkhoXe0rZigAAAABJRU5ErkJggg==" />
</code>```

ContentLicense: CC BY-SA 2.5

Title: Tipfy: How to display blob in template?

Body:
Given is on gae using tipfy (python) the following model:

greeting.avatar = db.Blob(avatar)

What is the template-tag to display a blob (here image)?

Body:
There isn't a built-in template tag for displaying arbitrary data like that.  I can think of two approaches:

Write a request handler for serving avatars as images.  Based on your example, request handler would just need to look up the greeting to get the image data, send an appropriate Content-Type: image/jpeg (or image/png or whatever) header and then write the blob data to the response stream.

Then, in your template, you'd display the image like this:

<img src="/show-avatar/{{ greeting.key().id() }}">

Write a custom template tag/template filter that takes the blob data and generates an appropiate data URL, which would encode the image data directly in the HTML document you're generating.

Then, in your template, you'd display the image something like this:

<img src="{{ greeting.avatar|dataurl }}">

which would result in output along these lines in the template:

<img src="data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAoAAAAKCAYAAACNMs+9AAAABGdBTUEAALGPC/xhBQAAAAlwSFlzAAALEwAACxMBAJqcGAAAAAd0SU1FB9YGARc5KB0XV+IAAAAddEVYdENvbW1lbnQAQ3JlYXRlZCB3aXRoIFRoZSBHSU1Q72QlbgAAAF1JREFUGNO9zL0NglAAxPEfdLTs4BZM4DIO4C7OwQg2JoQ9LE1exdlYvBBeZ7jqch9//q1uH4TLzw4d6+ErXMMcXuHWxId3KOETnnXXV6MJpcq2MLaI97CER3N0vr4MkhoXe0rZigAAAABJRU5ErkJggg==" />


问:
How to set X axis labels in MP Android Chart (Bar Graph)?
This is with reference to the article : https://github.com/PhilJay/MPAndroidChart/wiki/Setting-Data  under the heading Bar Graph.In the given code below:

```<code>@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {

    View view = inflater.inflate(R.layout.fragment_graph_test, container, false);

    BarChart chart = view.findViewById(R.id.bar_Chart_test);

    List<BarEntry> entries = new ArrayList<>();
    entries.add(new BarEntry(0f, 30f));
    entries.add(new BarEntry(1f, 80f));
    entries.add(new BarEntry(2f, 60f));
    entries.add(new BarEntry(3f, 50f));
    // gap of 2f
    entries.add(new BarEntry(5f, 70f));
    entries.add(new BarEntry(6f, 60f));

    BarDataSet set = new BarDataSet(entries, "BarDataSet");
    BarData data = new BarData(set);
    data.setBarWidth(0.9f); // set custom bar width
    chart.setData(data);
    chart.setFitBars(true); // make the x-axis fit exactly all bars
    chart.invalidate(); // refresh

    return view;
}
</code>```

the output was:

Here the X values are not displayed.Click here for the ScreenShot

how to set the X-axis values as months(1st Jan,2nd Jan,3rd Jan.....) as displayed in the article.

答:
You just make a simple list of string like this :

```<code>final ArrayList<String> xAxisLabel = new ArrayList<>();
    xAxisLabel.add("Mon");
    xAxisLabel.add("Tue");
    xAxisLabel.add("Wed");
    xAxisLabel.add("Thu");
    xAxisLabel.add("Fri");
    xAxisLabel.add("Sat");
    xAxisLabel.add("Sun");
</code>```

Then you do this :

```<code>    XAxis xAxis = chart.getXAxis();
    xAxis.setValueFormatter(new ValueFormatter() {
        @Override
        public String getFormattedValue(float value, AxisBase axis) {
            return xAxisLabel.get((int) value);

        }
    });
</code>```

Hope this helps.

Body:
This is with reference to the article : https://github.com/PhilJay/MPAndroidChart/wiki/Setting-Data  under the heading Bar Graph.In the given code below:

@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {

    View view = inflater.inflate(R.layout.fragment_graph_test, container, false);

    BarChart chart = view.findViewById(R.id.bar_Chart_test);

    List<BarEntry> entries = new ArrayList<>();
    entries.add(new BarEntry(0f, 30f));
    entries.add(new BarEntry(1f, 80f));
    entries.add(new BarEntry(2f, 60f));
    entries.add(new BarEntry(3f, 50f));
    // gap of 2f
    entries.add(new BarEntry(5f, 70f));
    entries.add(new BarEntry(6f, 60f));

    BarDataSet set = new BarDataSet(entries, "BarDataSet");
    BarData data = new BarData(set);
    data.setBarWidth(0.9f); // set custom bar width
    chart.setData(data);
    chart.setFitBars(true); // make the x-axis fit exactly all bars
    chart.invalidate(); // refresh

    return view;
}

the output was:

Here the X values are not displayed.Click here for the ScreenShot

how to set the X-axis values as months(1st Jan,2nd Jan,3rd Jan.....) as displayed in the article.

Body:
You just make a simple list of string like this :

final ArrayList<String> xAxisLabel = new ArrayList<>();
    xAxisLabel.add("Mon");
    xAxisLabel.add("Tue");
    xAxisLabel.add("Wed");
    xAxisLabel.add("Thu");
    xAxisLabel.add("Fri");
    xAxisLabel.add("Sat");
    xAxisLabel.add("Sun");

Then you do this :

    XAxis xAxis = chart.getXAxis();
    xAxis.setValueFormatter(new ValueFormatter() {
        @Override
        public String getFormattedValue(float value, AxisBase axis) {
            return xAxisLabel.get((int) value);

        }
    });

Hope this helps.


问:
How to change the hint's text color of PlaceAutocompleteFragment?
I don't see any methods that I can use to change the text color of hint in PlaceAutocompleteFragment.

答:
```<code>EditText etPlace = (EditText)autocompleteFragment.getView().findViewById(R.id.place_autocomplete_search_input);
        etPlace.setHint("Type your address");
        etPlace.setHintTextColor(R.color.primary_text_material_dark);
</code>```


问:
Quaternions act like euler
What is wrong with my implementation of quaternions? I think they still act like euler with gimbal locks and everything.

```<code>Quaternionf rotations = makeQuaternion(new Vector3f(1, 0, 0), angles.x);
            rotations.mul(makeQuaternion(new Vector3f(0, 1, 0), angles.y));
            rotations.mul(makeQuaternion(new Vector3f(0, 0, 1), angles.z));

Matrix4f matrix = new Matrix4f();

matrix.translate(position);
matrix.rotate(rotations);
matrix.scale(scale);
</code>```

The angles contains euler angles. People always tell me that I shouldn't use them at all but I have no idea how I would change the value of quaternion. And I think the Quaternionf rotations is correct. Eg. with angles 0, 90, 0 the quaternion contains 0.00, 0.707, 0.00, 0.707 (x,y,z,w). Which is correct right?

So where is the problem? I have read like everything I have found about this subject but I clearly still don't get it.

EDIT:

```<code>private static Quaternionf makeQuaternion(Vector3f n, float a) {

    float w, x, y, z;

    a = a / 360 * (float) Math.PI * 2;

    w = (float) Math.cos(a / 2);

    x = (float) (n.x * Math.sin(a / 2));
    y = (float) (n.y * Math.sin(a / 2));
    z = (float) (n.z * Math.sin(a / 2));

    Quaternionf quaternion = new Quaternionf(x, y, z, w);

    return quaternion;

}
</code>```

答:
Quaternions seem very deceptive and it is very, very hard to get a solid feel for them.

First, a few resources you may have already read. The Wikipedia page for quaternions is a great resource for the equations: https://en.wikipedia.org/wiki/Conversion_between_quaternions_and_Euler_angles
https://en.wikipedia.org/wiki/Quaternions_and_spatial_rotation

I also have a blog post on the basics about quaternions and what helped me get a feel for them:
https://blog.mide.com/quaternions-for-orientation

There are a few things that look weird in makeQuaternion, and it is unclear if you are using things incorrectly, or just applying pieces in different places.

The equation you're implementing is:

Here, A is the total angle of rotation, which is the rotation you would apply if you did the total rotation around a single axis, and Bx, By, Bz are direction angles. The sum of the square of the cosines of the direction angles needs to be 1 (ie cos^2 Bx + cos^2 By + cos^2 Bz = 1), because it represents a vector pointing from the origin.

You use n.x, n.y, n.z, and that will work as long as you make sure the sum of the squares = 1, ie they need to be points on a unit sphere. There is a similar relationship between A and the direction angles, but the easiest way to verify that is to make sure the sum of the squares of the quaternion = 1.

Title: Quaternions act like euler

Body:
What is wrong with my implementation of quaternions? I think they still act like euler with gimbal locks and everything.

Quaternionf rotations = makeQuaternion(new Vector3f(1, 0, 0), angles.x);
            rotations.mul(makeQuaternion(new Vector3f(0, 1, 0), angles.y));
            rotations.mul(makeQuaternion(new Vector3f(0, 0, 1), angles.z));

Matrix4f matrix = new Matrix4f();

matrix.translate(position);
matrix.rotate(rotations);
matrix.scale(scale);

The angles contains euler angles. People always tell me that I shouldn't use them at all but I have no idea how I would change the value of quaternion. And I think the Quaternionf rotations is correct. Eg. with angles 0, 90, 0 the quaternion contains 0.00, 0.707, 0.00, 0.707 (x,y,z,w). Which is correct right?

So where is the problem? I have read like everything I have found about this subject but I clearly still don't get it.

EDIT:

private static Quaternionf makeQuaternion(Vector3f n, float a) {

    float w, x, y, z;

    a = a / 360 * (float) Math.PI * 2;

    w = (float) Math.cos(a / 2);

    x = (float) (n.x * Math.sin(a / 2));
    y = (float) (n.y * Math.sin(a / 2));
    z = (float) (n.z * Math.sin(a / 2));

    Quaternionf quaternion = new Quaternionf(x, y, z, w);

    return quaternion;

}


问:
How to return promise from a method
I am using knex, a library that returns a promise for PostgreSQL. I am hoping to use it like the pg library. My issue is that I do not see a way to return a promise from a method similar to how I can with pg as follows

```<code>var newObj = {

    getAllRows: function(callback) {
        return pg.query("select * from table",callback);
    },
};
</code>```

which returns all of the rows with all data when calling newObj.getAllRows.

I have tried the same for knex, but it does not return...

```<code>var knexObj = {

    getAllRows: function(callback) {
        return knex('table').select("*")
               .then((data) {
                     return data;
             }
    },
</code>```

答:
You have different options here. Considder looking in the documentation of promises: https://developer.mozilla.org/de/docs/Web/JavaScript/Reference/Global_Objects/Promise

I would advise to append your callback in the then queue of the returned promise like so:

var knexObj = {

    getAllRows: function() {
        return Promise.resolve('MY DATA!')// stub for: knex('table').select("*") ....
    },
}

knexObj.getAllRows().then((data)=>{ // your callback!
  console.log("got the data:", data);
})```
</div>
</div>
</p>

<p>The benefit of this is, that you can chain the then statements together and don't have to pass callbacks forth and back.</p>

<p>Also you can catch all errors raised in one of the chain parts and try to resolve them by returning another promise.</p>

<p><div class="snippet" data-lang="js" data-hide="false" data-console="true" data-babel="false">
<div class="snippet-code">
<pre class="snippet-code-js lang-js prettyprint-override"><code>var knexObj = {

    getAllRows: function() {
        return Promise.reject('ERROR')// stub for: knex('table').select("*") ....
    },
}

knexObj.getAllRows()
  .catch(()=>{
    console.log("something went wrong but I can resolve this!");
    return Promise.resolve('Default Data!')
  })
  .then((data)=>{ // your callback!
    console.log('part result:', data);
    return Promise.resolve(data.split(' '))
  })
  .then((splitData)=>{
    for(let data of splitData){
      console.log('final data part:', data);
    }
  })
  .catch(()=>{
    console.log("something went wrong and there is nothing I can do about it!");
  })</code>```

Title: How to return promise from a method

Body:
I am using knex, a library that returns a promise for PostgreSQL. I am hoping to use it like the pg library. My issue is that I do not see a way to return a promise from a method similar to how I can with pg as follows

var newObj = {

    getAllRows: function(callback) {
        return pg.query("select * from table",callback);
    },
};

which returns all of the rows with all data when calling newObj.getAllRows.

I have tried the same for knex, but it does not return...

var knexObj = {

    getAllRows: function(callback) {
        return knex('table').select("*")
               .then((data) {
                     return data;
             }
    },

Body:
You have different options here. Considder looking in the documentation of promises: https://developer.mozilla.org/de/docs/Web/JavaScript/Reference/Global_Objects/Promise

I would advise to append your callback in the then queue of the returned promise like so:

var knexObj = {

    getAllRows: function() {
        return Promise.resolve('MY DATA!')// stub for: knex('table').select("*") ....
    },
}

knexObj.getAllRows().then((data)=>{ // your callback!
  console.log("got the data:", data);
})

The benefit of this is, that you can chain the then statements together and don't have to pass callbacks forth and back.

Also you can catch all errors raised in one of the chain parts and try to resolve them by returning another promise.

var knexObj = {

    getAllRows: function() {
        return Promise.reject('ERROR')// stub for: knex('table').select("*") ....
    },
}

knexObj.getAllRows()
  .catch(()=>{
    console.log("something went wrong but I can resolve this!");
    return Promise.resolve('Default Data!')
  })
  .then((data)=>{ // your callback!
    console.log('part result:', data);
    return Promise.resolve(data.split(' '))
  })
  .then((splitData)=>{
    for(let data of splitData){
      console.log('final data part:', data);
    }
  })
  .catch(()=>{
    console.log("something went wrong and there is nothing I can do about it!");
  })


问:
Cannot Install SQL Server 2008 R2
I am trying to install SQL Server 2008 R2 on a Windows XP machine.

I am just trying to install Database engine services only, I get am getting an access denied error. Here are the key lines from detail.txt file. I don't know what this means or how to fix it,

```<code>2011-01-21 14:44:47 Slp: Configuration action failed for feature SQL_Engine_Core_Inst during timing ConfigRC and scenario ConfigRC.
2011-01-21 14:44:47 Slp: Access is denied
2011-01-21 14:44:47 Slp: The configuration failure category of current exception is ConfigurationFailure
2011-01-21 14:44:47 Slp: Configuration action failed for feature SQL_Engine_Core_Inst during timing ConfigRC and scenario ConfigRC.
2011-01-21 14:44:47 Slp: System.ComponentModel.Win32Exception: Access is denied
2011-01-21 14:44:47 Slp:    at System.Diagnostics.ProcessManager.OpenProcess(Int32 processId, Int32 access, Boolean throwIfExited)
2011-01-21 14:44:47 Slp:    at System.Diagnostics.Process.GetProcessHandle(Int32 access, Boolean throwIfExited)
2011-01-21 14:44:47 Slp:    at System.Diagnostics.Process.OpenProcessHandle()
2011-01-21 14:44:47 Slp:    at System.Diagnostics.Process.get_Handle()
2011-01-21 14:44:47 Slp:    at Microsoft.SqlServer.Configuration.SqlEngine.SqlServerServiceBase.WaitSqlServerStart(Process processSql)
2011-01-21 14:44:47 Slp:    at Microsoft.SqlServer.Configuration.SqlEngine.SqlServerServiceSCM.StartSqlServer(String[] parameters)
2011-01-21 14:44:47 Slp:    at Microsoft.SqlServer.Configuration.SqlEngine.SqlServerStartup.StartSQLServerForInstall(String sqlCollation, String masterFullPath, Boolean isConfiguringTemplateDBs, Boolean isSlipstreamRunning)
2011-01-21 14:44:47 Slp:    at Microsoft.SqlServer.Configuration.SqlEngine.SqlEngineDBStartConfig.ConfigSQLServerSystemDatabases(EffectiveProperties properties, Boolean isConfiguringTemplateDBs, Boolean useInstallInputs)
2011-01-21 14:44:47 Slp:    at Microsoft.SqlServer.Configuration.SqlEngine.SqlEngineDBStartConfig.DoCommonDBStartConfig(ConfigActionTiming timing)
2011-01-21 14:44:47 Slp:    at Microsoft.SqlServer.Configuration.SqlEngine.SqlEngineDBStartConfig.Install(ConfigActionTiming timing, Dictionary`2 actionData, PublicConfigurationBase spcb)
2011-01-21 14:44:47 Slp:    at Microsoft.SqlServer.Configuration.SqlConfigBase.PrivateConfigurationBase.Execute(ConfigActionScenario scenario, ConfigActionTiming timing, ConfigBaseAction action, Dictionary`2 actionData, PublicConfigurationBase spcbCurrent)
2011-01-21 14:44:47 Slp:    at Microsoft.SqlServer.Configuration.SqlConfigBase.SqlFeatureConfigBase.Execute(ConfigActionScenario scenario, ConfigActionTiming timing, ConfigBaseAction action, Dictionary`2 actionData, PublicConfigurationBase spcbCurrent)
2011-01-21 14:44:47 Slp:    at Microsoft.SqlServer.Configuration.SqlConfigBase.SlpConfigAction.ExecuteAction(String actionId)
2011-01-21 14:44:47 Slp:    at Microsoft.SqlServer.Configuration.SqlConfigBase.SlpConfigAction.Execute(String actionId, TextWriter errorStream)
2011-01-21 14:44:47 Slp: Exception: System.ComponentModel.Win32Exception.
2011-01-21 14:44:47 Slp: Source: System.
2011-01-21 14:44:47 Slp: Message: Access is denied.
2011-01-21 14:44:47 Slp: Watson Bucket 1
 Original Parameter Values
</code>```

Thanks in advance.

Bob

答:
It's a security problem. The Bottom-most error "Access is denied" tells you that. Barring getting lucky with a Google search, you'll need to put Process Monitor on it and capture the actual Access is Denied to see what access is being denied to.

You'll have a raft of data, but my guess is it's probably trying to access a registry key it doesn't have permissions for.

Title: Cannot Install SQL Server 2008 R2

Body:
I am trying to install SQL Server 2008 R2 on a Windows XP machine.

I am just trying to install Database engine services only, I get am getting an access denied error. Here are the key lines from detail.txt file. I don't know what this means or how to fix it,

2011-01-21 14:44:47 Slp: Configuration action failed for feature SQL_Engine_Core_Inst during timing ConfigRC and scenario ConfigRC.
2011-01-21 14:44:47 Slp: Access is denied
2011-01-21 14:44:47 Slp: The configuration failure category of current exception is ConfigurationFailure
2011-01-21 14:44:47 Slp: Configuration action failed for feature SQL_Engine_Core_Inst during timing ConfigRC and scenario ConfigRC.
2011-01-21 14:44:47 Slp: System.ComponentModel.Win32Exception: Access is denied
2011-01-21 14:44:47 Slp:    at System.Diagnostics.ProcessManager.OpenProcess(Int32 processId, Int32 access, Boolean throwIfExited)
2011-01-21 14:44:47 Slp:    at System.Diagnostics.Process.GetProcessHandle(Int32 access, Boolean throwIfExited)
2011-01-21 14:44:47 Slp:    at System.Diagnostics.Process.OpenProcessHandle()
2011-01-21 14:44:47 Slp:    at System.Diagnostics.Process.get_Handle()
2011-01-21 14:44:47 Slp:    at Microsoft.SqlServer.Configuration.SqlEngine.SqlServerServiceBase.WaitSqlServerStart(Process processSql)
2011-01-21 14:44:47 Slp:    at Microsoft.SqlServer.Configuration.SqlEngine.SqlServerServiceSCM.StartSqlServer(String[] parameters)
2011-01-21 14:44:47 Slp:    at Microsoft.SqlServer.Configuration.SqlEngine.SqlServerStartup.StartSQLServerForInstall(String sqlCollation, String masterFullPath, Boolean isConfiguringTemplateDBs, Boolean isSlipstreamRunning)
2011-01-21 14:44:47 Slp:    at Microsoft.SqlServer.Configuration.SqlEngine.SqlEngineDBStartConfig.ConfigSQLServerSystemDatabases(EffectiveProperties properties, Boolean isConfiguringTemplateDBs, Boolean useInstallInputs)
2011-01-21 14:44:47 Slp:    at Microsoft.SqlServer.Configuration.SqlEngine.SqlEngineDBStartConfig.DoCommonDBStartConfig(ConfigActionTiming timing)
2011-01-21 14:44:47 Slp:    at Microsoft.SqlServer.Configuration.SqlEngine.SqlEngineDBStartConfig.Install(ConfigActionTiming timing, Dictionary`2 actionData, PublicConfigurationBase spcb)
2011-01-21 14:44:47 Slp:    at Microsoft.SqlServer.Configuration.SqlConfigBase.PrivateConfigurationBase.Execute(ConfigActionScenario scenario, ConfigActionTiming timing, ConfigBaseAction action, Dictionary`2 actionData, PublicConfigurationBase spcbCurrent)
2011-01-21 14:44:47 Slp:    at Microsoft.SqlServer.Configuration.SqlConfigBase.SqlFeatureConfigBase.Execute(ConfigActionScenario scenario, ConfigActionTiming timing, ConfigBaseAction action, Dictionary`2 actionData, PublicConfigurationBase spcbCurrent)
2011-01-21 14:44:47 Slp:    at Microsoft.SqlServer.Configuration.SqlConfigBase.SlpConfigAction.ExecuteAction(String actionId)
2011-01-21 14:44:47 Slp:    at Microsoft.SqlServer.Configuration.SqlConfigBase.SlpConfigAction.Execute(String actionId, TextWriter errorStream)
2011-01-21 14:44:47 Slp: Exception: System.ComponentModel.Win32Exception.
2011-01-21 14:44:47 Slp: Source: System.
2011-01-21 14:44:47 Slp: Message: Access is denied.
2011-01-21 14:44:47 Slp: Watson Bucket 1
 Original Parameter Values

Thanks in advance.

Bob


问:
How can I make OpenCV the default library for my qt projects?
Please suppose that I want to link OpenCV libraries in Qt-creator, in common, I will add headers usingINCLUDEPATH and link libraries using the LIBS variable, which is used in the qmake file but if we use OpenCV in most of our projects then we have to include OpenCV library every time, so is there any way to add opencv libraries automatically at the time of creating a project.
I use the below command to add OpenCV libraries for my projects every time.

```<code>INCLUDEPATH += -I/usr/local/include/opencv
LIBS += -L/usr/local/lib -lopencv_stitching -lopencv_superres ...and etc.
</code>```

UPDATE

I will use the following headers for OpenCV4:

```<code>INCLUDEPATH += /usr/local/include/opencv4
</code>```

答:
1) You can create a .prf (project feature) file in your mkspecs/features directory:

/usr/share/qt5/mkspecs/features/opencv.prf

```<code>INCLUDEPATH += -I/usr/local/include/opencv
LIBS += -L/usr/local/lib -lopencv_stitching -lopencv_superres ...and another libraries
</code>```

Now simply add CONFIG += opencv to your .pro file to have it working. Or you can even auto-enable this feature by editing mkspecs/qconfig.pri:

/usr/share/qt5/mkspecs/qconfig.pri

```<code>...
CONFIG += ... opencv
...
</code>```

BTW. qconfig.pri is a part of qt_config, which is loaded by all QMake's machine-dependent specs, so it should always work. However, it's also possible to patch only a specific spec (for example, /usr/share/qt5/mkspecs/linux-g++/qmake.conf, or whatever is appropriate for your configuration). Of course, it's even possible to add all these INCLUDEPATH+=... and LIBS+=... straight into that qmake.conf and get rid of the .prf file completely.

2) Alternatively, if you don't want to pollute Qt installation, you can use manual include:

opencv.pri

```<code>INCLUDEPATH += -I/usr/local/include/opencv
LIBS += -L/usr/local/lib -lopencv_stitching -lopencv_superres ...and another libraries
</code>```

myprogram.pro

```<code>include(path/to/opencv.pri)
...
</code>```

Body:
Please suppose that I want to link OpenCV libraries in Qt-creator, in common, I will add headers usingINCLUDEPATH and link libraries using the LIBS variable, which is used in the qmake file but if we use OpenCV in most of our projects then we have to include OpenCV library every time, so is there any way to add opencv libraries automatically at the time of creating a project.
I use the below command to add OpenCV libraries for my projects every time.

INCLUDEPATH += -I/usr/local/include/opencv
LIBS += -L/usr/local/lib -lopencv_stitching -lopencv_superres ...and etc.

UPDATE

I will use the following headers for OpenCV4:

INCLUDEPATH += /usr/local/include/opencv4

Body:
1) You can create a .prf (project feature) file in your mkspecs/features directory:

/usr/share/qt5/mkspecs/features/opencv.prf

INCLUDEPATH += -I/usr/local/include/opencv
LIBS += -L/usr/local/lib -lopencv_stitching -lopencv_superres ...and another libraries

Now simply add CONFIG += opencv to your .pro file to have it working. Or you can even auto-enable this feature by editing mkspecs/qconfig.pri:

/usr/share/qt5/mkspecs/qconfig.pri

...
CONFIG += ... opencv
...

BTW. qconfig.pri is a part of qt_config, which is loaded by all QMake's machine-dependent specs, so it should always work. However, it's also possible to patch only a specific spec (for example, /usr/share/qt5/mkspecs/linux-g++/qmake.conf, or whatever is appropriate for your configuration). Of course, it's even possible to add all these INCLUDEPATH+=... and LIBS+=... straight into that qmake.conf and get rid of the .prf file completely.

2) Alternatively, if you don't want to pollute Qt installation, you can use manual include:

opencv.pri

INCLUDEPATH += -I/usr/local/include/opencv
LIBS += -L/usr/local/lib -lopencv_stitching -lopencv_superres ...and another libraries

myprogram.pro

include(path/to/opencv.pri)
...


问:
Explicit constructors and nested initializer lists
The following code successfully compiles with most modern C++11 compatible compilers (GCC >= 5.x, Clang, ICC, MSVC).

```<code>#include <string>

struct A
{
        explicit A(const char *) {}
        A(std::string) {}
};

struct B
{
        B(A) {}
        B(B &) = delete;
};

int main( void )
{
        B b1({{{"test"}}});
}
</code>```

But why does it compile in the first place, and how are the listed compilers interpreting that code?

Why is MSVC able to compile this without B(B &) = delete;, but the other 3 compilers all need it?

And why does it fail in all compilers except MSVC when I delete a different signature of the copy constructor, e.g. B(const B &) = delete;?

Are the compilers even all choosing the same constructors?

Why does Clang emit the following warning?

```<code>17 : <source>:17:16: warning: braces around scalar initializer [-Wbraced-scalar-init]
        B b1({{{"test"}}});
</code>```

答:
B b1({{{"test"}}}); is like B b1(A{std::string{const char*[1]{"test"}}});

16.3.3.1.5 List-initialization sequence [over.ics.list]

4 Otherwise, if the parameter type is a character array 133 and the initializer list has a single element that is an appropriately-typed string literal (11.6.2), the implicit conversion sequence is the identity conversion.

And the compiler tries all possible implicit conversions. For example if we have class C with the following constructors:

```<code>#include <string>

struct C
{
    template<typename T, size_t N>     C(const T* (&&) [N]) {}
    template<typename T, size_t N>     C(const T  (&&) [N]) {}
    template<typename T=char>         C(const T* (&&)) {}
    template<typename T=char>          C(std::initializer_list<char>&&) {}
};

struct A
{
    explicit A(const char *) {}

    A(C ) {}
};

struct B
{
    B(A) {}
    B(B &) = delete;
};

int main( void )
{
    const char* p{"test"};
    const char p2[5]{"test"};

    B b1({{{"test"}}});
}
</code>```

The clang 5.0.0 compiler could not decide which to use and fails with:

```<code>29 : <source>:29:11: error: call to constructor of 'C' is ambiguous
    B b1({{{"test"}}});
          ^~~~~~~~~~
5 : <source>:5:40: note: candidate constructor [with T = char, N = 1]
    template<typename T, size_t N>     C(const T* (&&) [N]) {}
                                       ^
6 : <source>:6:40: note: candidate constructor [with T = const char *, N = 1]
    template<typename T, size_t N>     C(const T  (&&) [N]) {}
                                       ^
7 : <source>:7:39: note: candidate constructor [with T = char]
    template<typename T=char>         C(const T* (&&)) {}
                                      ^
15 : <source>:15:9: note: passing argument to parameter here
    A(C ) {}
        ^
</code>```

But if we leave only one of the non-initializer-list constructors the code compiles fine.

GCC 7.2 just picks the  C(const T* (&&)) {} and compiles. If it's not available it takes C(const T* (&&) [N]).

MSVC just fails with:

```<code>29 : <source>(29): error C2664: 'B::B(B &)': cannot convert argument 1 from 'initializer list' to 'A'
</code>```

Body:
The following code successfully compiles with most modern C++11 compatible compilers (GCC >= 5.x, Clang, ICC, MSVC).

#include <string>

struct A
{
        explicit A(const char *) {}
        A(std::string) {}
};

struct B
{
        B(A) {}
        B(B &) = delete;
};

int main( void )
{
        B b1({{{"test"}}});
}

But why does it compile in the first place, and how are the listed compilers interpreting that code?

Why is MSVC able to compile this without B(B &) = delete;, but the other 3 compilers all need it?

And why does it fail in all compilers except MSVC when I delete a different signature of the copy constructor, e.g. B(const B &) = delete;?

Are the compilers even all choosing the same constructors?

Why does Clang emit the following warning?

17 : <source>:17:16: warning: braces around scalar initializer [-Wbraced-scalar-init]
        B b1({{{"test"}}});

Body:
B b1({{{"test"}}}); is like B b1(A{std::string{const char*[1]{"test"}}});

16.3.3.1.5 List-initialization sequence [over.ics.list]

4 Otherwise, if the parameter type is a character array 133 and the initializer list has a single element that is an appropriately-typed string literal (11.6.2), the implicit conversion sequence is the identity conversion.

And the compiler tries all possible implicit conversions. For example if we have class C with the following constructors:

#include <string>

struct C
{
    template<typename T, size_t N>     C(const T* (&&) [N]) {}
    template<typename T, size_t N>     C(const T  (&&) [N]) {}
    template<typename T=char>         C(const T* (&&)) {}
    template<typename T=char>          C(std::initializer_list<char>&&) {}
};

struct A
{
    explicit A(const char *) {}

    A(C ) {}
};

struct B
{
    B(A) {}
    B(B &) = delete;
};

int main( void )
{
    const char* p{"test"};
    const char p2[5]{"test"};

    B b1({{{"test"}}});
}

The clang 5.0.0 compiler could not decide which to use and fails with:

29 : <source>:29:11: error: call to constructor of 'C' is ambiguous
    B b1({{{"test"}}});
          ^~~~~~~~~~
5 : <source>:5:40: note: candidate constructor [with T = char, N = 1]
    template<typename T, size_t N>     C(const T* (&&) [N]) {}
                                       ^
6 : <source>:6:40: note: candidate constructor [with T = const char *, N = 1]
    template<typename T, size_t N>     C(const T  (&&) [N]) {}
                                       ^
7 : <source>:7:39: note: candidate constructor [with T = char]
    template<typename T=char>         C(const T* (&&)) {}
                                      ^
15 : <source>:15:9: note: passing argument to parameter here
    A(C ) {}
        ^

But if we leave only one of the non-initializer-list constructors the code compiles fine.

GCC 7.2 just picks the  C(const T* (&&)) {} and compiles. If it's not available it takes C(const T* (&&) [N]).

MSVC just fails with:

29 : <source>(29): error C2664: 'B::B(B &)': cannot convert argument 1 from 'initializer list' to 'A'


问:
Angular debug context error Cannot read property ngDebugContext
I updated my version of angular from 2 to 4 and now I am getting this exception when executing a service:

```<code>ERROR TypeError: Cannot read property 'ngDebugContext' of undefined
at getDebugContext (core.es5.js:994)
at isViewDebugError (core.es5.js:8451)
at callWithDebugContext (core.es5.js:13474)
at Object.debugCheckAndUpdateView [as checkAndUpdateView] (core.es5.js:13007)
at ViewRef_.detectChanges (core.es5.js:10174)
at core.es5.js:4812
at Array.forEach (<anonymous>)
at ApplicationRef_.tick (core.es5.js:4812)
at core.es5.js:4684
at ZoneDelegate.invoke (zone.js:392)
</code>```

This error was injected . when I changed from hot to cold observables.

答:
I found the answer in this article. Turns out I wasn't returning the observable correctly in Angular.

https://blog.thoughtram.io/angular/2016/06/16/cold-vs-hot-observables.html#making-cold-observables-hot

Body:
I updated my version of angular from 2 to 4 and now I am getting this exception when executing a service:

ERROR TypeError: Cannot read property 'ngDebugContext' of undefined
at getDebugContext (core.es5.js:994)
at isViewDebugError (core.es5.js:8451)
at callWithDebugContext (core.es5.js:13474)
at Object.debugCheckAndUpdateView [as checkAndUpdateView] (core.es5.js:13007)
at ViewRef_.detectChanges (core.es5.js:10174)
at core.es5.js:4812
at Array.forEach (<anonymous>)
at ApplicationRef_.tick (core.es5.js:4812)
at core.es5.js:4684
at ZoneDelegate.invoke (zone.js:392)

This error was injected . when I changed from hot to cold observables.


问:
Java preprocess phase
I'm writing a Java application that needs a lot of static data that is stored in many enum types. Since I would like an user-friendly way to customize this data using for example xml or json files but I'm not allowed to do it directly with enums I was looking for a way to elegantly do it.

Maybe a good solution would be to have a separate java program that reads the xml files and produces the java sources that are then compiled with the remaining part of the sources. My doubs is how to automatize this process in a stand alone way (eg ant?) and how to integrate it seamlessly with eclipse so that it is autOmatically done when I'm working with the project.. Does anything similar to what I'm looking already exists? Any suggestion to solve my problem?

Thanks!

答: If the items and the overall structure are somehow fixed (and what varies most is the values of the attributes), you could consider defining the enum with one entry for each of your items and let the enum populate its own constants with data read from an external source (XML / JSON) -- at load time or on demand.</p>

Title: Java preprocess phase


问:
Reverse all words, set "." and do the same for the next sentences
I´m trying to program for so long now and it won´t work. I need a program, which does following:

User Input: I´m looking for some food. I love food.
System Print: Food some for looking I´m. Food love I.

Reverse the words, UpperWord the first word, start with next sentence a keep the "." at it´s place.

```<code>package finaledition;

public class finaledition {
    public static void main(String[] args) {
        StringBuilder outputString= new StringBuilder();
        String satz;
        String wort;

        System.out.print("Bitte geben Sie einen String ein: ");
        String text = Input.readString();

        while (text.indexOf('.') > 0) {
            satz = text.substring(0, text.indexOf('.'));
            text = text.substring(text.indexOf('.') + 1);

            while (satz.lastIndexOf(' ') > 0) {
                wort = satz.substring(satz.lastIndexOf(' ') + 1);
                outputString.append(wort);
                satz = satz.substring(0, satz.lastIndexOf(' '));
            }
            System.out.print(outputString);
        }
    }
}
</code>```

The actual result is:

```<code>foodsomeforlookingfoodsomeforlookingfoodlove
</code>```

答:
First, you need to split your hole text into sentences:

```<code>String[] sentences = text.split(". ");
</code>```

Then you need to make an arrays with the words:

```<code>String[] words = sentences[anIndex].split(" ");
</code>```

Then, reverse the words array:

```<code>String[] reverseSentence = new String[words.length];
for(int a=0; a<words.length; a++){
    reverseSentence[a] = words[words.length - a -1];
}
</code>```

And then add all the reversed sentences together and add a '.'.

Body:
I´m trying to program for so long now and it won´t work. I need a program, which does following:

User Input: I´m looking for some food. I love food.
System Print: Food some for looking I´m. Food love I.

Reverse the words, UpperWord the first word, start with next sentence a keep the "." at it´s place.

package finaledition;

public class finaledition {
    public static void main(String[] args) {
        StringBuilder outputString= new StringBuilder();
        String satz;
        String wort;

        System.out.print("Bitte geben Sie einen String ein: ");
        String text = Input.readString();

        while (text.indexOf('.') > 0) {
            satz = text.substring(0, text.indexOf('.'));
            text = text.substring(text.indexOf('.') + 1);

            while (satz.lastIndexOf(' ') > 0) {
                wort = satz.substring(satz.lastIndexOf(' ') + 1);
                outputString.append(wort);
                satz = satz.substring(0, satz.lastIndexOf(' '));
            }
            System.out.print(outputString);
        }
    }
}

The actual result is:

foodsomeforlookingfoodsomeforlookingfoodlove

Body:
First, you need to split your hole text into sentences:

String[] sentences = text.split(". ");

Then you need to make an arrays with the words:

String[] words = sentences[anIndex].split(" ");

Then, reverse the words array:

String[] reverseSentence = new String[words.length];
for(int a=0; a<words.length; a++){
    reverseSentence[a] = words[words.length - a -1];
}

And then add all the reversed sentences together and add a '.'.


问:
Disable buttons during ajax requests
I've seen many ways in jquery and Angular 1 on how to disable a submit button whilst an ajax request is being processed, but not for Angular 2.

So far on the template I have:

```<code><button type="submit" [disabled]="requestSent">Submit</button>
</code>```

and the following to toggle it's disabled state in the Typescript:

```<code>requestSent: boolean = false;

this.httpService.addNewAgent(object)
            .subscribe(
            data => {

                this.requestSent = false;

            },
            error => {

                console.log(error.error);

            }
            );
</code>```

But this is rather long winded to do on every single component. Is there a more universal way of dealing with this? Perhaps with interceptors?

答:
There are several cases to resolve this problem:
First approach:

```<code>this.httpService.addNewAgent(object)
        .do(() => this.isLoading = true)
        .finally(() => this.isLoading = false)
        .subscribe()
</code>```

Second approach is creating service with Subject:

```<code> @Injectable()
 class LoadingService {
     isLoading: BehaviorSubject<boolean> = new BehaviourSubject(false);
  }
</code>```

In your intenceptor you will set sometihn like this:

```<code>  this.service.isLoading(currentState);
</code>```

In your component:

```<code>this.service.isLoading.subscribe((state) => this.isLoading = state)
</code>```

Title: Disable buttons during ajax requests

Body:
I've seen many ways in jquery and Angular 1 on how to disable a submit button whilst an ajax request is being processed, but not for Angular 2.

So far on the template I have:

<button type="submit" [disabled]="requestSent">Submit</button>

and the following to toggle it's disabled state in the Typescript:

requestSent: boolean = false;

this.httpService.addNewAgent(object)
            .subscribe(
            data => {

                this.requestSent = false;

            },
            error => {

                console.log(error.error);

            }
            );

But this is rather long winded to do on every single component. Is there a more universal way of dealing with this? Perhaps with interceptors?

Body:
There are several cases to resolve this problem:
First approach:

this.httpService.addNewAgent(object)
        .do(() => this.isLoading = true)
        .finally(() => this.isLoading = false)
        .subscribe()

Second approach is creating service with Subject:

 @Injectable()
 class LoadingService {
     isLoading: BehaviorSubject<boolean> = new BehaviourSubject(false);
  }

In your intenceptor you will set sometihn like this:

  this.service.isLoading(currentState);

In your component:

this.service.isLoading.subscribe((state) => this.isLoading = state)


问:
Mediaplayer - All songs are playing at the same time - Other song is not getting stopped
I am trying to play music ( from url /server) in my app.I listed 2 songs there. Everything is working fine. Except one problem. All songs are playing at the same time...I want to play one song only a time. I repeat all songs are playing simultaneously .

Here is a screenshot of that app

```<code>import android.media.MediaPlayer;
import android.support.v7.app.AppCompatActivity;
import android.os.Bundle;
import android.support.v7.widget.DividerItemDecoration;
import android.support.v7.widget.LinearLayoutManager;
import android.support.v7.widget.RecyclerView;
import android.view.View;
import android.widget.Button;
import android.widget.SeekBar;

import java.io.IOException;
import java.util.ArrayList;

public class MainActivity2 extends AppCompatActivity {

    private ArrayList<SongInfo> _songs = new ArrayList<SongInfo>();
    RecyclerView recyclerView;
    SeekBar seekBar;
    SongAdapter songAdapter;
    MediaPlayer mediaPlayer;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main2);
        recyclerView = (RecyclerView) findViewById(R.id.recyclerView);
        seekBar = (SeekBar) findViewById(R.id.seekBar);

        SongInfo s = new SongInfo("Cheap Thrills", "sia", "http://176.126.236.250/33Mmt/music/hindi/movies/new/oh_my_god/Go-Go-Govinda_(webmusic.in).mp3");
        _songs.add(s);

        s = new SongInfo("Cheap Thrills", "sia", "http://176.126.236.250/33Mmt/music/hindi/movies/new/oh_my_god/Go-Go-Govinda_(webmusic.in).mp3");
        _songs.add(s);

        songAdapter = new SongAdapter(this, _songs);
        recyclerView.setAdapter(songAdapter);
        LinearLayoutManager linearLayoutManager = new LinearLayoutManager(this);
        DividerItemDecoration dividerItemDecoration = new DividerItemDecoration(recyclerView.getContext(),
                linearLayoutManager.getOrientation());
        recyclerView.addItemDecoration(dividerItemDecoration);
        recyclerView.setLayoutManager(linearLayoutManager);
        recyclerView.setAdapter(songAdapter);

        songAdapter.setOnItemClickListener(new SongAdapter.OnItemClickListener() {
            @Override
            public void onItemClick(final Button b, View view, SongInfo obj, int position) {
                try {
                    if (b.getText().toString().equals("stop")) {
                        b.setText("Play");
                        mediaPlayer.stop();
                        mediaPlayer.reset();
                        mediaPlayer.release();
                        mediaPlayer = null;
                    }else {
                        mediaPlayer = new MediaPlayer();
                        mediaPlayer.setDataSource(obj.getSongUrl());
                        mediaPlayer.prepareAsync();
                        mediaPlayer.setOnPreparedListener(new MediaPlayer.OnPreparedListener() {
                            @Override
                            public void onPrepared(MediaPlayer mp) {
                                mp.start();
                                b.setText("stop");
                            }
                        });
                    }

                } catch (IOException e) {
                }
            }
        });

    }

}
</code>```

this is my song adapter code -:

```<code>package com.a03.dip.kaliprasadbengalisongs;

import android.content.Context;
import android.support.v7.widget.RecyclerView;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.Button;
import android.widget.TextView;

import java.util.ArrayList;

public class SongAdapter extends RecyclerView.Adapter<SongAdapter.SongHolder> {

    ArrayList<SongInfo> _songs;
    Context context;

    OnItemClickListener mOnItemClickListener;

    SongAdapter(Context context, ArrayList<SongInfo> songs) {
        this.context = context;
        this._songs = songs;
    }

    public interface OnItemClickListener {
        void onItemClick(Button b ,View view, SongInfo obj, int position);
    }

    public void setOnItemClickListener(final OnItemClickListener mItemClickListener) {
        this.mOnItemClickListener = mItemClickListener;
    }

    @Override
    public SongHolder onCreateViewHolder(ViewGroup viewGroup, int i) {

        View myView = LayoutInflater.from(context).inflate(R.layout.row_song,viewGroup,false);
        return new SongHolder(myView);
    }

    @Override
    public void onBindViewHolder(final SongHolder songHolder, final int i) {
        final SongInfo c = _songs.get(i);
        songHolder.songName.setText(_songs.get(i).songName());
        songHolder.artistName.setText(_songs.get(i).artistName());
        songHolder.btnAction.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                if (mOnItemClickListener != null) {
                    mOnItemClickListener.onItemClick(songHolder.btnAction,v, c, i);
                }
            }
        });
    }

    @Override
    public int getItemCount() {

        return _songs.size();
    }

    public class SongHolder extends RecyclerView.ViewHolder {
        TextView songName,artistName;
        Button btnAction;

        public SongHolder(View itemView) {
            super(itemView);
            songName = (TextView) itemView.findViewById(R.id.tvSongName);
            artistName = (TextView) itemView.findViewById(R.id.tvArtistName);
            btnAction = (Button) itemView.findViewById(R.id.btnPlay);

        }
    }
}
</code>```

and here is songInfo class -----

```<code>package com.a03.dip.kaliprasadbengalisongs;

import android.media.MediaPlayer;

public class SongInfo {
        public String songName ,artistName,songUrl;

    public SongInfo() {
    }

    public SongInfo(String songName, String artistName, String songUrl) {
        this.songName = songName;
        this.artistName = artistName;
        this.songUrl = songUrl;
    }

    public String songName() {
        return songName;
    }

    public String artistName() {
        return artistName;
    }

    public String getSongUrl() {
        return songUrl;
    }

}
</code>```

答:
Yes ! This is my question ,still i want to answer this question. After doing Lots of research I found the solution, and I think I should share it  through the answer.

So , the first thing you have to do is that....

Delete all codes in main - activity which you have added. Also , don't forget to delete other 2 classes ( songadapter and songInfo)

Now add this simple code to play audio from url...

public class PlayaudioActivity extends Activity {

```<code>private MediaPlayer mp;

/** Called when the activity is first created. */
@Override
public void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.main);
    Button b = (Button) findViewById(R.id.button1);
    Button b2 = (Button) findViewById(R.id.button2);

    b.setOnClickListener(new View.OnClickListener() {

        @Override
        public void onClick(View v) {
            stopPlaying();
           mp.setDataSource("http://q.freesfx.co.uk/rx2/mp3s/9/10183_1367780535.mp3");
          // mediaPlayer.prepare();
            mp.start();

if (mediaPlayer.isPlaying()) {
        bPlay.setText(“Stop”);
        mediaPlayer.pause();
    }
    else {
        bPlay.setText(“Stop”);
        mediaPlayer.start();
    }

        }

    });
</code>```

By this way you can add more song and play them without having any problems. Hope this will help you.

Body:
I am trying to play music ( from url /server) in my app.I listed 2 songs there. Everything is working fine. Except one problem. All songs are playing at the same time...I want to play one song only a time. I repeat all songs are playing simultaneously .

Here is a screenshot of that app

import android.media.MediaPlayer;
import android.support.v7.app.AppCompatActivity;
import android.os.Bundle;
import android.support.v7.widget.DividerItemDecoration;
import android.support.v7.widget.LinearLayoutManager;
import android.support.v7.widget.RecyclerView;
import android.view.View;
import android.widget.Button;
import android.widget.SeekBar;

import java.io.IOException;
import java.util.ArrayList;

public class MainActivity2 extends AppCompatActivity {

    private ArrayList<SongInfo> _songs = new ArrayList<SongInfo>();
    RecyclerView recyclerView;
    SeekBar seekBar;
    SongAdapter songAdapter;
    MediaPlayer mediaPlayer;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main2);
        recyclerView = (RecyclerView) findViewById(R.id.recyclerView);
        seekBar = (SeekBar) findViewById(R.id.seekBar);

        SongInfo s = new SongInfo("Cheap Thrills", "sia", "http://176.126.236.250/33Mmt/music/hindi/movies/new/oh_my_god/Go-Go-Govinda_(webmusic.in).mp3");
        _songs.add(s);

        s = new SongInfo("Cheap Thrills", "sia", "http://176.126.236.250/33Mmt/music/hindi/movies/new/oh_my_god/Go-Go-Govinda_(webmusic.in).mp3");
        _songs.add(s);

        songAdapter = new SongAdapter(this, _songs);
        recyclerView.setAdapter(songAdapter);
        LinearLayoutManager linearLayoutManager = new LinearLayoutManager(this);
        DividerItemDecoration dividerItemDecoration = new DividerItemDecoration(recyclerView.getContext(),
                linearLayoutManager.getOrientation());
        recyclerView.addItemDecoration(dividerItemDecoration);
        recyclerView.setLayoutManager(linearLayoutManager);
        recyclerView.setAdapter(songAdapter);

        songAdapter.setOnItemClickListener(new SongAdapter.OnItemClickListener() {
            @Override
            public void onItemClick(final Button b, View view, SongInfo obj, int position) {
                try {
                    if (b.getText().toString().equals("stop")) {
                        b.setText("Play");
                        mediaPlayer.stop();
                        mediaPlayer.reset();
                        mediaPlayer.release();
                        mediaPlayer = null;
                    }else {
                        mediaPlayer = new MediaPlayer();
                        mediaPlayer.setDataSource(obj.getSongUrl());
                        mediaPlayer.prepareAsync();
                        mediaPlayer.setOnPreparedListener(new MediaPlayer.OnPreparedListener() {
                            @Override
                            public void onPrepared(MediaPlayer mp) {
                                mp.start();
                                b.setText("stop");
                            }
                        });
                    }

                } catch (IOException e) {
                }
            }
        });

    }

}

this is my song adapter code -:

package com.a03.dip.kaliprasadbengalisongs;

import android.content.Context;
import android.support.v7.widget.RecyclerView;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.Button;
import android.widget.TextView;

import java.util.ArrayList;

public class SongAdapter extends RecyclerView.Adapter<SongAdapter.SongHolder> {

    ArrayList<SongInfo> _songs;
    Context context;

    OnItemClickListener mOnItemClickListener;

    SongAdapter(Context context, ArrayList<SongInfo> songs) {
        this.context = context;
        this._songs = songs;
    }

    public interface OnItemClickListener {
        void onItemClick(Button b ,View view, SongInfo obj, int position);
    }

    public void setOnItemClickListener(final OnItemClickListener mItemClickListener) {
        this.mOnItemClickListener = mItemClickListener;
    }

    @Override
    public SongHolder onCreateViewHolder(ViewGroup viewGroup, int i) {

        View myView = LayoutInflater.from(context).inflate(R.layout.row_song,viewGroup,false);
        return new SongHolder(myView);
    }

    @Override
    public void onBindViewHolder(final SongHolder songHolder, final int i) {
        final SongInfo c = _songs.get(i);
        songHolder.songName.setText(_songs.get(i).songName());
        songHolder.artistName.setText(_songs.get(i).artistName());
        songHolder.btnAction.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                if (mOnItemClickListener != null) {
                    mOnItemClickListener.onItemClick(songHolder.btnAction,v, c, i);
                }
            }
        });
    }

    @Override
    public int getItemCount() {

        return _songs.size();
    }

    public class SongHolder extends RecyclerView.ViewHolder {
        TextView songName,artistName;
        Button btnAction;

        public SongHolder(View itemView) {
            super(itemView);
            songName = (TextView) itemView.findViewById(R.id.tvSongName);
            artistName = (TextView) itemView.findViewById(R.id.tvArtistName);
            btnAction = (Button) itemView.findViewById(R.id.btnPlay);

        }
    }
}

and here is songInfo class -----

package com.a03.dip.kaliprasadbengalisongs;

import android.media.MediaPlayer;

public class SongInfo {
        public String songName ,artistName,songUrl;

    public SongInfo() {
    }

    public SongInfo(String songName, String artistName, String songUrl) {
        this.songName = songName;
        this.artistName = artistName;
        this.songUrl = songUrl;
    }

    public String songName() {
        return songName;
    }

    public String artistName() {
        return artistName;
    }

    public String getSongUrl() {
        return songUrl;
    }

}

Body:
Yes ! This is my question ,still i want to answer this question. After doing Lots of research I found the solution, and I think I should share it  through the answer.

So , the first thing you have to do is that....

Delete all codes in main - activity which you have added. Also , don't forget to delete other 2 classes ( songadapter and songInfo)

Now add this simple code to play audio from url...

public class PlayaudioActivity extends Activity {

private MediaPlayer mp;

/** Called when the activity is first created. */
@Override
public void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.main);
    Button b = (Button) findViewById(R.id.button1);
    Button b2 = (Button) findViewById(R.id.button2);

    b.setOnClickListener(new View.OnClickListener() {

        @Override
        public void onClick(View v) {
            stopPlaying();
           mp.setDataSource("http://q.freesfx.co.uk/rx2/mp3s/9/10183_1367780535.mp3");
          // mediaPlayer.prepare();
            mp.start();

if (mediaPlayer.isPlaying()) {
        bPlay.setText(“Stop”);
        mediaPlayer.pause();
    }
    else {
        bPlay.setText(“Stop”);
        mediaPlayer.start();
    }

        }

    });

By this way you can add more song and play them without having any problems. Hope this will help you.


答:
```<code>var knexObj = {
  getAllRows: function() {
    return knex('table').select("*");
  }
}

knexObj.getAllRows().then(function (data) {
  console.log(data);
});
</code>```

Title: How to return promise from a method


问:
Java Scanner unable to read file
I'm doing a very simple text-parsing program, using files given to me by a friend.
However, when I open the file using a Scanner like so,

```<code>Scanner scan = new Scanner(new File(path));
System.err.println(scan.hasNext());
while(scan.hasNextLine())
    System.err.println(scan.nextLine());
System.err.println(scan.next());
</code>```

result:

```<code>false
Exception in thread "main" java.util.NoSuchElementException
at java.util.Scanner.throwFor(Scanner.java:855)
at java.util.Scanner.next(Scanner.java:1364)
at Test.main(Test.java:18)
</code>```

the scanner treats the file(which is some 1400 lines long) as empty.

Can anyone think of any reason a scanner might not be able to see a file? I suspect the fact that the file was imported from a Windows machine to a Linux machine may have something to do with it, but my mind is open to other possibilities

edited for formatting and code errors

答:
it maybe occurred for this problems:

1-your file maybe isn't created.

2-your file is in use for other programs.

3-the path address is false.

Title: Java Scanner unable to read file

Body:
I'm doing a very simple text-parsing program, using files given to me by a friend.
However, when I open the file using a Scanner like so,

Scanner scan = new Scanner(new File(path));
System.err.println(scan.hasNext());
while(scan.hasNextLine())
    System.err.println(scan.nextLine());
System.err.println(scan.next());

result:

false
Exception in thread "main" java.util.NoSuchElementException
at java.util.Scanner.throwFor(Scanner.java:855)
at java.util.Scanner.next(Scanner.java:1364)
at Test.main(Test.java:18)

the scanner treats the file(which is some 1400 lines long) as empty.

Can anyone think of any reason a scanner might not be able to see a file? I suspect the fact that the file was imported from a Windows machine to a Linux machine may have something to do with it, but my mind is open to other possibilities

edited for formatting and code errors


问:
Python - Shift/Delete Values in a 2-Dimensional Array
I need help with shifting and deleting elements in a 2-dimensional array.

If the value in a list is negative and their is a list above it with positive values in the same location. It should shift everything down, causing the negative values to disappear.

If there isn't any list above it or the corresponding values in the list above are just 0. It will replace the negative values with 0.

Scenario 1, 3, and 4 are working! But Scenario 2 doesn't work. (I hope I covered all possible scenarios in my examples)

Note: The positive values should never disappear, they can only move down when needed. Only the negative values (below -100) disappear.

These examples should explain it better:

Scenario 1: # This Works

DATA

```<code>[[   0,    0,    0, 0, 0],
 [   0,    0,    0, 0, 0],
 [   1,    3,    1, 0, 0],
 [-102, -102, -102, 0, 0],
 [   3,    1,    3, 0, 0]]
</code>```

EXPECT

```<code>[[0, 0, 0, 0, 0],
 [0, 0, 0, 0, 0],
 [0, 0, 0, 0, 0],
 [1, 3, 1, 0, 0],
 [3, 1, 3, 0, 0]]
</code>```

Scenario 2: # Doesn't Work

DATA

```<code>[[   0,    0,    0, 0, 0],
 [   0,    0,    0, 0, 0],
 [   1,    2,    1, 0, 0],
 [   2,    1,    2, 0, 0],
 [-103, -103, -103, 0, 0]]
</code>```

EXPECT

```<code>[[0, 0, 0, 0, 0],
 [0, 0, 0, 0, 0],
 [0, 0, 0, 0, 0],
 [1, 2, 1, 0, 0],
 [2, 1, 2, 0, 0]]
</code>```

The Current Output (Incorrect):

```<code>[[0, 0, 0, 0, 0],
 [0, 0, 0, 0, 0],
 [1, 2, 1, 0, 0],
 [2, 1, 2, 0, 0],
 [0, 0, 0, 0, 0]]
</code>```

Scenario 3: # This Works

DATA

```<code>[[0, 0,    0,    0,    0],
 [0, 0,    0,    0,    0],
 [0, 2, -101, -101, -101],
 [0, 1,    2,    3,    2],
 [0, 3,    3,    2,    3]]
</code>```

EXPECT

```<code>[[0, 0, 0, 0, 0],
 [0, 0, 0, 0, 0],
 [0, 2, 0, 0, 0],
 [0, 1, 2, 3, 2],
 [0, 3, 3, 2, 3]]
</code>```

Scenario 4: # This Works

DATA

```<code>[[ 0, 0, 0, 0, 0],
 [ 0, 0, 0, 0, 0],
 [-101, 2, 2, 3, 4],
 [-101, 1, 2, 3, 2],
 [-101, 3, 3, 2, 3]]
</code>```

EXPECT

```<code>[[0, 0, 0, 0, 0],
 [0, 0, 0, 0, 0],
 [0, 2, 2, 3, 4],
 [0, 1, 2, 3, 2],
 [0, 3, 3, 2, 3]]
</code>```

Here is my code - It's definitely overcomplicated for what I am trying to achieve but I have been stuck on this and can't figure out any alternative. (I can't import any outside function...so no numpy)

```<code>def move(data):

    # PART 1
    '''
    Creates a list that contains a tuple (row, coll) of the location where a negative value (> -100) appears on the list.
    '''

    rows = len(data)

    c_count = 4

    row_list = []

    while c_count >= 0:
        for x in range(rows):
            if data[x][c_count] < -100:
                row_list.append((x, c_count))

        c_count -=1

    # PART 2
    '''
    Iterates through the list of values that contain negative value (> -100) and performs the actions listed below.
    '''

    for x in row_list:
        row = x[0]
        col = x[1]

        try: # If there isn't anything above the negative value (except for 0), make all negative value (>-100) == 0. EXAMPLE (DATA 3)

            if data[row-1][col] == 0:
                 data[row][col] = 0

        except(IndexError):
            pass

        try: # If a row of negative values is between a row on top and bottom that contains possitive values, then merge the values above with the negative values below it. EXAMPLE (DATA 1)

            if data[row-1][col] > 0 and data[row+1][col] > 0:

                c_count = 4
                while c_count >= 0:

                    count = len(data) - 1
                    prev = count - 1

                    while count > 0 and prev >= 0:
                        if data[count][c_count] < -100:

                            while prev >= 0 and data[prev][c_count] == 0:
                                prev -= 1

                            data[count][c_count] = data[prev][c_count]
                            data[prev][c_count]= 0

                        count -= 1
                        prev -= 1

                    c_count -= 1
                return data

        except(IndexError):
            pass

        try: # If a row of negative values has nothing underneath it (at the bottom) of the list. Then push everything on the top down replacing the negative value. This isn't working!

**SCENARIO 2 Should Have Worked Here**

            if data[row-1][col] > 0:
                data[row][col] = 0

                rows = len(data)

                c_count = 4
                while c_count >= 0:

                    for x in range(rows):
                        if data[x][c_count] > 0:
                            rows = x
                            break

                    last = rows-1

                    if data[last][c_count] == 0:
                        while last > 0:
                            data[last][c_count] = data[last-1][c_count]
                            last -= 1
                        data[0][c_count] = 0

                    c_count -= 1

        except(IndexError):
            pass

    return data

print('Data 1') # This Works
data1 = [[0, 0, 0, 0, 0],
         [0, 0, 0, 0, 0],
         [1, 3, 1, 0, 0],
         [-102, -102, -102, 0, 0],
         [3, 1, 3, 0, 0]]

print(data1, 'org')
x = move(data1)

expect1 = [[0, 0, 0, 0, 0],
           [0, 0, 0, 0, 0],
           [0, 0, 0, 0, 0],
           [1, 3, 1, 0, 0],
           [3, 1, 3, 0, 0]]

print(x, 'sol')
print(expect1, 'expect')
print(data1 == expect1)

print()

print('Data 2') # Doesn't Work

data2 = [[0, 0, 0, 0, 0],
         [0, 0, 0, 0, 0],
         [1, 2, 1, 0, 0],
         [2, 1, 2, 0, 0],
         [-103, -103, -103, 0, 0]]

print(data2, 'org')
y = move(data2)

expect2 = [[0, 0, 0, 0, 0],
           [0, 0, 0, 0, 0],
           [0, 0, 0, 0, 0],
           [1, 2, 1, 0, 0],
           [2, 1, 2, 0, 0]]

print(y,'sol')
print(expect2, 'expect')
print(data2 == expect2)

print()

print('Data 3') # This Works

data3 = [[0, 0, 0, 0, 0],
         [0, 0, 0, 0, 0],
         [0, 2, -101, -101, -101],
         [0, 1, 2, 3, 2],
         [0, 3, 3, 2, 3]]
print(data3, 'org')
z = move(data3)

expect3 = [[0, 0, 0, 0, 0],
           [0, 0, 0, 0, 0],
           [0, 2, 0, 0, 0],
           [0, 1, 2, 3, 2],
           [0, 3, 3, 2, 3]]

print(z,'sol')
print(expect3, 'expect')
print(data3 == expect3)

print()

print('Data 4') # This Works

data4 = [[0, 0, 0, 0, 0],
         [0, 0, 0, 0, 0],
         [-101, 2, 2, 3, 4],
         [-101, 1, 2, 3, 2],
         [-101, 3, 3, 2, 3]]

print(data4, 'org')
a = move(data4)

expect4 = [[0, 0, 0, 0, 0],
           [0, 0, 0, 0, 0],
           [0, 2, 2, 3, 4],
           [0, 1, 2, 3, 2],
           [0, 3, 3, 2, 3]]

print(a,'sol')
print(expect4, 'expect')
print(data4 == expect4)
</code>```

答:
I use code from previous question
Python - Shift/Delete Elements in a 2-Dimensional Array

and it gives correct results:

I work with columns separately, not with full rows.

search in column from bottom to top

find negative value

find positive value (bigger then zero) above

if not found then put zero in place of negative

if found then move down all value above
(move above to row, above-1 to row-1, above-2 to row-2, etc.)

.

```<code>def move(data):

    # work in column, not with full rows
    for col in range(len(data)):

        # move from bottom to top
        for row in range(len(data[0])-1, -1, -1):

            # check if negative value
            if data[row][col] < 0:
                print('debug: negative:', data[row][col])

                # find positive value above
                above = row-1
                while above > -1 and data[above][col] <= 0:
                    above -= 1

                # check if found positive value
                if above == -1:
                    # put zero if not found value above
                    print('debug: put zero')
                    data[row][col] = 0
                else:
                    # move down all values above
                    print('debug: move down', above+1, 'element(s)')
                    while above > -1:
                        data[row][col] = data[above][col]
                        data[above][col] = 0
                        row -= 1
                        above -= 1

    return data

# --- function to run one scenario, display data and check result ---

def run(data, expect):

        print('data:')
        print('\n'.join(str(row) for row in data))
        print()
        result = move(data)
        print()
        print('result:')
        print(result)
        print('expect:')
        print(expect)
        print('expect == result:', expect == result)
        print('---')

# --- scenarios ---

def scenario_B1():

    DATA = [
        [   0,    0,    0, 0, 0],
        [   0,    0,    0, 0, 0],
        [   1,    3,    1, 0, 0],
        [-102, -102, -102, 0, 0],
        [   3,    1,    3, 0, 0]
    ]

    EXPECT =    [
        [0, 0, 0, 0, 0],
        [0, 0, 0, 0, 0],
        [0, 0, 0, 0, 0],
        [1, 3, 1, 0, 0],
        [3, 1, 3, 0, 0]
    ]

    run(DATA, EXPECT)

def scenario_B2():

    DATA = [
        [   0,    0,    0, 0, 0],
        [   0,    0,    0, 0, 0],
        [   1,    2,    1, 0, 0],
        [   2,    1,    2, 0, 0],
        [-103, -103, -103, 0, 0]
    ]

    EXPECT = [
        [0, 0, 0, 0, 0],
        [0, 0, 0, 0, 0],
        [0, 0, 0, 0, 0],
        [1, 2, 1, 0, 0],
        [2, 1, 2, 0, 0]
    ]

    run(DATA, EXPECT)

def scenario_B3():

    DATA = [
        [0, 0,    0,    0,    0],
        [0, 0,    0,    0,    0],
        [0, 2, -101, -101, -101],
        [0, 1,    2,    3,    2],
        [0, 3,    3,    2,    3]
    ]

    EXPECT = [
        [0, 0, 0, 0, 0],
        [0, 0, 0, 0, 0],
        [0, 2, 0, 0, 0],
        [0, 1, 2, 3, 2],
        [0, 3, 3, 2, 3]
    ]

    run(DATA, EXPECT)

def scenario_B4():

    DATA = [
        [ 0, 0, 0, 0, 0],
        [ 0, 0, 0, 0, 0],
        [-101, 2, 2, 3, 4],
        [-101, 1, 2, 3, 2],
        [-101, 3, 3, 2, 3]
    ]

    EXPECT = [
        [0, 0, 0, 0, 0],
        [0, 0, 0, 0, 0],
        [0, 2, 2, 3, 4],
        [0, 1, 2, 3, 2],
        [0, 3, 3, 2, 3]
    ]

    run(DATA, EXPECT)

# --- start scenarios ---

scenario_B1()
scenario_B2()
scenario_B3()
scenario_B4()
</code>```

Results:

```<code>data:
[0, 0, 0, 0, 0]
[0, 0, 0, 0, 0]
[1, 3, 1, 0, 0]
[-102, -102, -102, 0, 0]
[3, 1, 3, 0, 0]

debug: negative: -102
debug: move down 3 element(s)
debug: negative: -102
debug: move down 3 element(s)
debug: negative: -102
debug: move down 3 element(s)

result:
[[0, 0, 0, 0, 0], [0, 0, 0, 0, 0], [0, 0, 0, 0, 0], [1, 3, 1, 0, 0], [3, 1, 3, 0, 0]]
expect:
[[0, 0, 0, 0, 0], [0, 0, 0, 0, 0], [0, 0, 0, 0, 0], [1, 3, 1, 0, 0], [3, 1, 3, 0, 0]]
expect == result: True
---
data:
[0, 0, 0, 0, 0]
[0, 0, 0, 0, 0]
[1, 2, 1, 0, 0]
[2, 1, 2, 0, 0]
[-103, -103, -103, 0, 0]

debug: negative: -103
debug: move down 4 element(s)
debug: negative: -103
debug: move down 4 element(s)
debug: negative: -103
debug: move down 4 element(s)

result:
[[0, 0, 0, 0, 0], [0, 0, 0, 0, 0], [0, 0, 0, 0, 0], [1, 2, 1, 0, 0], [2, 1, 2, 0, 0]]
expect:
[[0, 0, 0, 0, 0], [0, 0, 0, 0, 0], [0, 0, 0, 0, 0], [1, 2, 1, 0, 0], [2, 1, 2, 0, 0]]
expect == result: True
---
data:
[0, 0, 0, 0, 0]
[0, 0, 0, 0, 0]
[0, 2, -101, -101, -101]
[0, 1, 2, 3, 2]
[0, 3, 3, 2, 3]

debug: negative: -101
debug: put zero
debug: negative: -101
debug: put zero
debug: negative: -101
debug: put zero

result:
[[0, 0, 0, 0, 0], [0, 0, 0, 0, 0], [0, 2, 0, 0, 0], [0, 1, 2, 3, 2], [0, 3, 3, 2, 3]]
expect:
[[0, 0, 0, 0, 0], [0, 0, 0, 0, 0], [0, 2, 0, 0, 0], [0, 1, 2, 3, 2], [0, 3, 3, 2, 3]]
expect == result: True
---
data:
[0, 0, 0, 0, 0]
[0, 0, 0, 0, 0]
[-101, 2, 2, 3, 4]
[-101, 1, 2, 3, 2]
[-101, 3, 3, 2, 3]

debug: negative: -101
debug: put zero
debug: negative: -101
debug: put zero
debug: negative: -101
debug: put zero

result:
[[0, 0, 0, 0, 0], [0, 0, 0, 0, 0], [0, 2, 2, 3, 4], [0, 1, 2, 3, 2], [0, 3, 3, 2, 3]]
expect:
[[0, 0, 0, 0, 0], [0, 0, 0, 0, 0], [0, 2, 2, 3, 4], [0, 1, 2, 3, 2], [0, 3, 3, 2, 3]]
expect == result: True
---
</code>```

Body:
I need help with shifting and deleting elements in a 2-dimensional array.

If the value in a list is negative and their is a list above it with positive values in the same location. It should shift everything down, causing the negative values to disappear.

If there isn't any list above it or the corresponding values in the list above are just 0. It will replace the negative values with 0.

Scenario 1, 3, and 4 are working! But Scenario 2 doesn't work. (I hope I covered all possible scenarios in my examples)

Note: The positive values should never disappear, they can only move down when needed. Only the negative values (below -100) disappear.

These examples should explain it better:

Scenario 1: # This Works

DATA

[[   0,    0,    0, 0, 0],
 [   0,    0,    0, 0, 0],
 [   1,    3,    1, 0, 0],
 [-102, -102, -102, 0, 0],
 [   3,    1,    3, 0, 0]]

EXPECT

[[0, 0, 0, 0, 0],
 [0, 0, 0, 0, 0],
 [0, 0, 0, 0, 0],
 [1, 3, 1, 0, 0],
 [3, 1, 3, 0, 0]]

Scenario 2: # Doesn't Work

DATA

[[   0,    0,    0, 0, 0],
 [   0,    0,    0, 0, 0],
 [   1,    2,    1, 0, 0],
 [   2,    1,    2, 0, 0],
 [-103, -103, -103, 0, 0]]

EXPECT

[[0, 0, 0, 0, 0],
 [0, 0, 0, 0, 0],
 [0, 0, 0, 0, 0],
 [1, 2, 1, 0, 0],
 [2, 1, 2, 0, 0]]

The Current Output (Incorrect):

[[0, 0, 0, 0, 0],
 [0, 0, 0, 0, 0],
 [1, 2, 1, 0, 0],
 [2, 1, 2, 0, 0],
 [0, 0, 0, 0, 0]]

Scenario 3: # This Works

DATA

[[0, 0,    0,    0,    0],
 [0, 0,    0,    0,    0],
 [0, 2, -101, -101, -101],
 [0, 1,    2,    3,    2],
 [0, 3,    3,    2,    3]]

EXPECT

[[0, 0, 0, 0, 0],
 [0, 0, 0, 0, 0],
 [0, 2, 0, 0, 0],
 [0, 1, 2, 3, 2],
 [0, 3, 3, 2, 3]]

Scenario 4: # This Works

DATA

[[ 0, 0, 0, 0, 0],
 [ 0, 0, 0, 0, 0],
 [-101, 2, 2, 3, 4],
 [-101, 1, 2, 3, 2],
 [-101, 3, 3, 2, 3]]

EXPECT

[[0, 0, 0, 0, 0],
 [0, 0, 0, 0, 0],
 [0, 2, 2, 3, 4],
 [0, 1, 2, 3, 2],
 [0, 3, 3, 2, 3]]

Here is my code - It's definitely overcomplicated for what I am trying to achieve but I have been stuck on this and can't figure out any alternative. (I can't import any outside function...so no numpy)

def move(data):

    # PART 1
    '''
    Creates a list that contains a tuple (row, coll) of the location where a negative value (> -100) appears on the list.
    '''

    rows = len(data)

    c_count = 4

    row_list = []

    while c_count >= 0:
        for x in range(rows):
            if data[x][c_count] < -100:
                row_list.append((x, c_count))

        c_count -=1

    # PART 2
    '''
    Iterates through the list of values that contain negative value (> -100) and performs the actions listed below.
    '''

    for x in row_list:
        row = x[0]
        col = x[1]

        try: # If there isn't anything above the negative value (except for 0), make all negative value (>-100) == 0. EXAMPLE (DATA 3)

            if data[row-1][col] == 0:
                 data[row][col] = 0

        except(IndexError):
            pass

        try: # If a row of negative values is between a row on top and bottom that contains possitive values, then merge the values above with the negative values below it. EXAMPLE (DATA 1)

            if data[row-1][col] > 0 and data[row+1][col] > 0:

                c_count = 4
                while c_count >= 0:

                    count = len(data) - 1
                    prev = count - 1

                    while count > 0 and prev >= 0:
                        if data[count][c_count] < -100:

                            while prev >= 0 and data[prev][c_count] == 0:
                                prev -= 1

                            data[count][c_count] = data[prev][c_count]
                            data[prev][c_count]= 0

                        count -= 1
                        prev -= 1

                    c_count -= 1
                return data

        except(IndexError):
            pass

        try: # If a row of negative values has nothing underneath it (at the bottom) of the list. Then push everything on the top down replacing the negative value. This isn't working!

**SCENARIO 2 Should Have Worked Here**

            if data[row-1][col] > 0:
                data[row][col] = 0

                rows = len(data)

                c_count = 4
                while c_count >= 0:

                    for x in range(rows):
                        if data[x][c_count] > 0:
                            rows = x
                            break

                    last = rows-1

                    if data[last][c_count] == 0:
                        while last > 0:
                            data[last][c_count] = data[last-1][c_count]
                            last -= 1
                        data[0][c_count] = 0

                    c_count -= 1

        except(IndexError):
            pass

    return data

print('Data 1') # This Works
data1 = [[0, 0, 0, 0, 0],
         [0, 0, 0, 0, 0],
         [1, 3, 1, 0, 0],
         [-102, -102, -102, 0, 0],
         [3, 1, 3, 0, 0]]

print(data1, 'org')
x = move(data1)

expect1 = [[0, 0, 0, 0, 0],
           [0, 0, 0, 0, 0],
           [0, 0, 0, 0, 0],
           [1, 3, 1, 0, 0],
           [3, 1, 3, 0, 0]]

print(x, 'sol')
print(expect1, 'expect')
print(data1 == expect1)

print()

print('Data 2') # Doesn't Work

data2 = [[0, 0, 0, 0, 0],
         [0, 0, 0, 0, 0],
         [1, 2, 1, 0, 0],
         [2, 1, 2, 0, 0],
         [-103, -103, -103, 0, 0]]

print(data2, 'org')
y = move(data2)

expect2 = [[0, 0, 0, 0, 0],
           [0, 0, 0, 0, 0],
           [0, 0, 0, 0, 0],
           [1, 2, 1, 0, 0],
           [2, 1, 2, 0, 0]]

print(y,'sol')
print(expect2, 'expect')
print(data2 == expect2)

print()

print('Data 3') # This Works

data3 = [[0, 0, 0, 0, 0],
         [0, 0, 0, 0, 0],
         [0, 2, -101, -101, -101],
         [0, 1, 2, 3, 2],
         [0, 3, 3, 2, 3]]
print(data3, 'org')
z = move(data3)

expect3 = [[0, 0, 0, 0, 0],
           [0, 0, 0, 0, 0],
           [0, 2, 0, 0, 0],
           [0, 1, 2, 3, 2],
           [0, 3, 3, 2, 3]]

print(z,'sol')
print(expect3, 'expect')
print(data3 == expect3)

print()

print('Data 4') # This Works

data4 = [[0, 0, 0, 0, 0],
         [0, 0, 0, 0, 0],
         [-101, 2, 2, 3, 4],
         [-101, 1, 2, 3, 2],
         [-101, 3, 3, 2, 3]]

print(data4, 'org')
a = move(data4)

expect4 = [[0, 0, 0, 0, 0],
           [0, 0, 0, 0, 0],
           [0, 2, 2, 3, 4],
           [0, 1, 2, 3, 2],
           [0, 3, 3, 2, 3]]

print(a,'sol')
print(expect4, 'expect')
print(data4 == expect4)

Body:
I use code from previous question
Python - Shift/Delete Elements in a 2-Dimensional Array

and it gives correct results:

I work with columns separately, not with full rows.

search in column from bottom to top

find negative value

find positive value (bigger then zero) above

if not found then put zero in place of negative

if found then move down all value above
(move above to row, above-1 to row-1, above-2 to row-2, etc.)

.

def move(data):

    # work in column, not with full rows
    for col in range(len(data)):

        # move from bottom to top
        for row in range(len(data[0])-1, -1, -1):

            # check if negative value
            if data[row][col] < 0:
                print('debug: negative:', data[row][col])

                # find positive value above
                above = row-1
                while above > -1 and data[above][col] <= 0:
                    above -= 1

                # check if found positive value
                if above == -1:
                    # put zero if not found value above
                    print('debug: put zero')
                    data[row][col] = 0
                else:
                    # move down all values above
                    print('debug: move down', above+1, 'element(s)')
                    while above > -1:
                        data[row][col] = data[above][col]
                        data[above][col] = 0
                        row -= 1
                        above -= 1

    return data

# --- function to run one scenario, display data and check result ---

def run(data, expect):

        print('data:')
        print('\n'.join(str(row) for row in data))
        print()
        result = move(data)
        print()
        print('result:')
        print(result)
        print('expect:')
        print(expect)
        print('expect == result:', expect == result)
        print('---')

# --- scenarios ---

def scenario_B1():

    DATA = [
        [   0,    0,    0, 0, 0],
        [   0,    0,    0, 0, 0],
        [   1,    3,    1, 0, 0],
        [-102, -102, -102, 0, 0],
        [   3,    1,    3, 0, 0]
    ]

    EXPECT =    [
        [0, 0, 0, 0, 0],
        [0, 0, 0, 0, 0],
        [0, 0, 0, 0, 0],
        [1, 3, 1, 0, 0],
        [3, 1, 3, 0, 0]
    ]

    run(DATA, EXPECT)

def scenario_B2():

    DATA = [
        [   0,    0,    0, 0, 0],
        [   0,    0,    0, 0, 0],
        [   1,    2,    1, 0, 0],
        [   2,    1,    2, 0, 0],
        [-103, -103, -103, 0, 0]
    ]

    EXPECT = [
        [0, 0, 0, 0, 0],
        [0, 0, 0, 0, 0],
        [0, 0, 0, 0, 0],
        [1, 2, 1, 0, 0],
        [2, 1, 2, 0, 0]
    ]

    run(DATA, EXPECT)

def scenario_B3():

    DATA = [
        [0, 0,    0,    0,    0],
        [0, 0,    0,    0,    0],
        [0, 2, -101, -101, -101],
        [0, 1,    2,    3,    2],
        [0, 3,    3,    2,    3]
    ]

    EXPECT = [
        [0, 0, 0, 0, 0],
        [0, 0, 0, 0, 0],
        [0, 2, 0, 0, 0],
        [0, 1, 2, 3, 2],
        [0, 3, 3, 2, 3]
    ]

    run(DATA, EXPECT)

def scenario_B4():

    DATA = [
        [ 0, 0, 0, 0, 0],
        [ 0, 0, 0, 0, 0],
        [-101, 2, 2, 3, 4],
        [-101, 1, 2, 3, 2],
        [-101, 3, 3, 2, 3]
    ]

    EXPECT = [
        [0, 0, 0, 0, 0],
        [0, 0, 0, 0, 0],
        [0, 2, 2, 3, 4],
        [0, 1, 2, 3, 2],
        [0, 3, 3, 2, 3]
    ]

    run(DATA, EXPECT)

# --- start scenarios ---

scenario_B1()
scenario_B2()
scenario_B3()
scenario_B4()

Results:

data:
[0, 0, 0, 0, 0]
[0, 0, 0, 0, 0]
[1, 3, 1, 0, 0]
[-102, -102, -102, 0, 0]
[3, 1, 3, 0, 0]

debug: negative: -102
debug: move down 3 element(s)
debug: negative: -102
debug: move down 3 element(s)
debug: negative: -102
debug: move down 3 element(s)

result:
[[0, 0, 0, 0, 0], [0, 0, 0, 0, 0], [0, 0, 0, 0, 0], [1, 3, 1, 0, 0], [3, 1, 3, 0, 0]]
expect:
[[0, 0, 0, 0, 0], [0, 0, 0, 0, 0], [0, 0, 0, 0, 0], [1, 3, 1, 0, 0], [3, 1, 3, 0, 0]]
expect == result: True
---
data:
[0, 0, 0, 0, 0]
[0, 0, 0, 0, 0]
[1, 2, 1, 0, 0]
[2, 1, 2, 0, 0]
[-103, -103, -103, 0, 0]

debug: negative: -103
debug: move down 4 element(s)
debug: negative: -103
debug: move down 4 element(s)
debug: negative: -103
debug: move down 4 element(s)

result:
[[0, 0, 0, 0, 0], [0, 0, 0, 0, 0], [0, 0, 0, 0, 0], [1, 2, 1, 0, 0], [2, 1, 2, 0, 0]]
expect:
[[0, 0, 0, 0, 0], [0, 0, 0, 0, 0], [0, 0, 0, 0, 0], [1, 2, 1, 0, 0], [2, 1, 2, 0, 0]]
expect == result: True
---
data:
[0, 0, 0, 0, 0]
[0, 0, 0, 0, 0]
[0, 2, -101, -101, -101]
[0, 1, 2, 3, 2]
[0, 3, 3, 2, 3]

debug: negative: -101
debug: put zero
debug: negative: -101
debug: put zero
debug: negative: -101
debug: put zero

result:
[[0, 0, 0, 0, 0], [0, 0, 0, 0, 0], [0, 2, 0, 0, 0], [0, 1, 2, 3, 2], [0, 3, 3, 2, 3]]
expect:
[[0, 0, 0, 0, 0], [0, 0, 0, 0, 0], [0, 2, 0, 0, 0], [0, 1, 2, 3, 2], [0, 3, 3, 2, 3]]
expect == result: True
---
data:
[0, 0, 0, 0, 0]
[0, 0, 0, 0, 0]
[-101, 2, 2, 3, 4]
[-101, 1, 2, 3, 2]
[-101, 3, 3, 2, 3]

debug: negative: -101
debug: put zero
debug: negative: -101
debug: put zero
debug: negative: -101
debug: put zero

result:
[[0, 0, 0, 0, 0], [0, 0, 0, 0, 0], [0, 2, 2, 3, 4], [0, 1, 2, 3, 2], [0, 3, 3, 2, 3]]
expect:
[[0, 0, 0, 0, 0], [0, 0, 0, 0, 0], [0, 2, 2, 3, 4], [0, 1, 2, 3, 2], [0, 3, 3, 2, 3]]
expect == result: True
---


问:
Is it possible to use ActiveX in a Xamarin app
After researching for a few days I can't seem to find a definite answer  to this question anywhere on the web. Does anyone have any experience in this area?</p>

答:
ActiveX is an old Windows only technology. You can't use it on anything but windows, consequently you can't use it in Xamarin which has to run Android and iOS.

Generally ActiveX should be avoided as it is being phased out in newer versions of Windows . (Dropped from Windows Store Apps & Internet Explorer in Windows 10