问:
How do you actually perform relationships in Entity Framework 4 Code-First CTP 5?
I would like to have a short example on how do you actually perform relationships in Entity Framework 4 Code-First CTP 5 ?

Would love an example for these kind of relations :

```<code>* one-to-many
* many-to-many
</code>```

Thanks a lots!

答:
One to One

```<code>public class One
{
  public int Id {get;set;}
  public virtual Two RelationTwo {get;set;}
}

public class Two
{
 public int Id {get;set;}
 public virtual One RelationOne {get;set;}
}
</code>```

Things to note, it has to be virtual

One to Many

```<code>public class One
{
  public int Id {get;set;}
  public virtual ICollection<Two> RelationTwo {get;set;}
}

public class Two
{
 public int Id {get;set;}
 public virtual One RelationOne {get;set;}
}
</code>```

Many to Many

```<code>public class One
{
  public int Id {get;set;}
  public virtual ICollection<Two> RelationTwo {get;set;}
}

public class Two
{
 public int Id {get;set;}
 public virtual ICollection<One> RelationOne {get;set;}
}
</code>```

note that it needs to be ICollection

Following links maybe helpful, click and click

Hope this helps.

EDIT

Updated to include one to many.

EDIT #2

Updated to include a potential for doing the Invoice <-> Product scenario which was requested by comment.

note: this is untested, but should put you in the right direction

```<code>public class Invoice
{
    public int Id {get;set;}
    //.. etc. other details on invoice, linking to shipping address etc.

    public virtual ICollection<InvoiceProduct> Items {get;set;}
}

public class InvoiceProduct
{
    public int Id {get;set;}
    public int Quantity {get;set;}
    public decimal Price {get;set;} // possibly calculated
    //.. other details such as discounts maybe

    public virtual Product Product {get;set;}
    public virtual Invoice Order {get;set;} // maybe but not required
}

public class Product
{
    public int Id {get;set;}
    //.. other details about product
}
</code>```

Using this you could then iterate through all the items on the invoice and then foreach be able to show the invoice details about each item as well as a description from the product itself.

Body:
I would like to have a short example on how do you actually perform relationships in Entity Framework 4 Code-First CTP 5 ?

Would love an example for these kind of relations :

* one-to-many
* many-to-many

Thanks a lots!

Body:
One to One

public class One
{
  public int Id {get;set;}
  public virtual Two RelationTwo {get;set;}
}

public class Two
{
 public int Id {get;set;}
 public virtual One RelationOne {get;set;}
}

Things to note, it has to be virtual

One to Many

public class One
{
  public int Id {get;set;}
  public virtual ICollection<Two> RelationTwo {get;set;}
}

public class Two
{
 public int Id {get;set;}
 public virtual One RelationOne {get;set;}
}

Many to Many

public class One
{
  public int Id {get;set;}
  public virtual ICollection<Two> RelationTwo {get;set;}
}

public class Two
{
 public int Id {get;set;}
 public virtual ICollection<One> RelationOne {get;set;}
}

note that it needs to be ICollection

Following links maybe helpful, click and click

Hope this helps.

EDIT

Updated to include one to many.

EDIT #2

Updated to include a potential for doing the Invoice <-> Product scenario which was requested by comment.

note: this is untested, but should put you in the right direction

public class Invoice
{
    public int Id {get;set;}
    //.. etc. other details on invoice, linking to shipping address etc.

    public virtual ICollection<InvoiceProduct> Items {get;set;}
}

public class InvoiceProduct
{
    public int Id {get;set;}
    public int Quantity {get;set;}
    public decimal Price {get;set;} // possibly calculated
    //.. other details such as discounts maybe

    public virtual Product Product {get;set;}
    public virtual Invoice Order {get;set;} // maybe but not required
}

public class Product
{
    public int Id {get;set;}
    //.. other details about product
}

Using this you could then iterate through all the items on the invoice and then foreach be able to show the invoice details about each item as well as a description from the product itself.


来源: stackexchange

问:
.matplotlib config location when installing matplotlib into virtualenv

TL;DR

Why does matplotlib's config end up inside $HOME when, installed inside virtualenv, should be scoped to the virtualenv's own site-packages?

Working on Tensorflow project, I

created virtualenv

activated virtualenv

then installed packages like Tensorflow, matplotlib, et al. [note: I do not have these packages installed globally]

In debugging matplotlib error, noticed comment about matplotlib from this answer [https://stackoverflow.com/a/21789908]

why is there a folder .matplotlib in my root folder instead of in the
  virtual environment where I installed it?

Per matplotlib docs [https://matplotlib.org/faq/troubleshooting_faq.html#matplotlib-configuration-and-cache-directory-locations]:

On unix-like systems, this directory is generally located in your HOME
  directory under the .config/ directory

using this simple script run from inside virtualenv , I confirm directory location on MacOS [10.10.5]

```<code>import matplotlib as mpl

print(mpl.get_cachedir())
# output is '$HOME/.matplotlib'
</code>```

The docs, however, do not answer the question: why, when virtualenv installs should be scoped to the virtualenv's own site-packages, does matplotlib's config end up inside $HOME?

答:
Because they implemented a lot of other means.

matplotlib looks for matplotlibrc in four locations, in the following order:

matplotlibrc in the current working directory, usually used for specific customizations that you do not want to apply elsewhere.

$MATPLOTLIBRC if it is a file, else $MATPLOTLIBRC/matplotlibrc.

It next looks in a user-specific place, depending on your platform:

On Linux and FreeBSD, it looks in .config/matplotlib/matplotlibrc (or $XDG_CONFIG_HOME/matplotlib/matplotlibrc) if you’ve customized your environment.

On other platforms, it looks in .matplotlib/matplotlibrc.

Put your matplotlibrc in the current directory (or run your programs in a directory with matplotlibrc). Or define MATPLOTLIBRC environment variable. In a virtual environment you can set and clear it automatically with preactivate/postdeactivate hooks.

ContentLicense: CC BY-SA 3.0

Body:
TL;DR

Why does matplotlib's config end up inside $HOME when, installed inside virtualenv, should be scoped to the virtualenv's own site-packages?

Working on Tensorflow project, I

created virtualenv

activated virtualenv

then installed packages like Tensorflow, matplotlib, et al. [note: I do not have these packages installed globally]

In debugging matplotlib error, noticed comment about matplotlib from this answer [https://stackoverflow.com/a/21789908]

why is there a folder .matplotlib in my root folder instead of in the
  virtual environment where I installed it?

Per matplotlib docs [https://matplotlib.org/faq/troubleshooting_faq.html#matplotlib-configuration-and-cache-directory-locations]:

On unix-like systems, this directory is generally located in your HOME
  directory under the .config/ directory

using this simple script run from inside virtualenv , I confirm directory location on MacOS [10.10.5]

import matplotlib as mpl

print(mpl.get_cachedir())
# output is '$HOME/.matplotlib'

The docs, however, do not answer the question: why, when virtualenv installs should be scoped to the virtualenv's own site-packages, does matplotlib's config end up inside $HOME?


问:
Getting biography summary from lastfm: TypeError: string indices must be integers
Im getting the top artists from a specify country using last fm api and I want to save the name, url and the biograpgy for each top artist. The name and url is working fine, but the biography is not working.

Im doing like this to get the name and url of the top artists:

```<code>import requests

api_key = ""
ID = 0
artists = {}

for i in range(1, 3):
    artists_response = requests.get('http://ws.audioscrobbler.com/2.0/?method=geo.gettopartists&country=spain&format=json&page=' + str(i) + '&api_key=' + api_key)
    artists_data = artists_response.json()

    #print(artists_data)

    for artist in artists_data["topartists"]["artist"]:
        name = artist["name"]
        url = artist["url"]

        image = artist["image"]

        artists[ID] = {}
        artists[ID]['ID'] = ID
        artists[ID]['name'] = name
        artists[ID]['url'] = url
        artists[ID]['image'] = image
        ID += 1

#print(artists)
</code>```

At this point is working fine. But now I want to get the biography summary for each topartist, but it is appearing the error "TypeError: string indices must be integers", on " print(artist["summary"])":

```<code>for i,v in artists.items():
    chosen = artists[i]['name'].replace(" ", "+")
    artist_response = requests.get('http://ws.audioscrobbler.com/2.0/?method=artist.getinfo&format=json&artist='+chosen+'&api_key='+api_key)
    artist_data = artist_response.json()

    #print(artist_data)

    for artist in artist_data['artist']['bio']:
       print(artist["summary"])
       bio = artist["summary"]
       artists[ID]['bio'] = bio

   # print(artist_response)
</code>```

答:
From your example data, it is clear that artist_data["artist"]["bio"] is a dictionary, so that the loop assigns the keys of that dictionary (which are strings) to artist.

As you have not provided an example of artist_data["top_artists"], I cannot speak to why that did not produce the same error.

Body:
Im getting the top artists from a specify country using last fm api and I want to save the name, url and the biograpgy for each top artist. The name and url is working fine, but the biography is not working.

Im doing like this to get the name and url of the top artists:

import requests

api_key = ""
ID = 0
artists = {}

for i in range(1, 3):
    artists_response = requests.get('http://ws.audioscrobbler.com/2.0/?method=geo.gettopartists&country=spain&format=json&page=' + str(i) + '&api_key=' + api_key)
    artists_data = artists_response.json()

    #print(artists_data)

    for artist in artists_data["topartists"]["artist"]:
        name = artist["name"]
        url = artist["url"]

        image = artist["image"]

        artists[ID] = {}
        artists[ID]['ID'] = ID
        artists[ID]['name'] = name
        artists[ID]['url'] = url
        artists[ID]['image'] = image
        ID += 1

#print(artists)

At this point is working fine. But now I want to get the biography summary for each topartist, but it is appearing the error "TypeError: string indices must be integers", on " print(artist["summary"])":

for i,v in artists.items():
    chosen = artists[i]['name'].replace(" ", "+")
    artist_response = requests.get('http://ws.audioscrobbler.com/2.0/?method=artist.getinfo&format=json&artist='+chosen+'&api_key='+api_key)
    artist_data = artist_response.json()

    #print(artist_data)

    for artist in artist_data['artist']['bio']:
       print(artist["summary"])
       bio = artist["summary"]
       artists[ID]['bio'] = bio

   # print(artist_response)


问:
Cache, loops and performance
Some time ago I wrote a little piece of code to ask about on interviews and see how people understand concepts of cache and memory:

```<code>#include "stdafx.h"
#include <stdlib.h>
#include <windows.h>
#include <iostream>

#define TOTAL 0x20000000

using namespace std;

__int64 count(int INNER, int OUTER)
{
    int a = 0;
    int* arr = (int*) HeapAlloc(GetProcessHeap(), 0, INNER * sizeof(int));
    if (!arr) {
        cerr << "HeapAlloc failed\n";
        return 1;
    }
    LARGE_INTEGER freq;
    LARGE_INTEGER startTime, endTime;
    __int64 elapsedTime, elapsedMilliseconds;
    QueryPerformanceFrequency(&freq);
    QueryPerformanceCounter(&startTime);

    /* Начало работы */

    for (int i = 0; i < OUTER; i++) {
        for (int j = 0; j < INNER; j++) {
            a |= i;
            arr[j] = a;
        }
    }

    /* Конец работы */

    QueryPerformanceCounter(&endTime);
    elapsedTime = endTime.QuadPart - startTime.QuadPart;
    elapsedMilliseconds = (1000 * elapsedTime) / freq.QuadPart;
    HeapFree(GetProcessHeap(), 0, arr);
    return elapsedMilliseconds;
}

int _tmain(int argc, _TCHAR* argv[])
{
    __int64 time;
    for (int INNER = 0x10; INNER <= 0x2000000; INNER <<= 1) {
        int OUTER = TOTAL / INNER;
        time = count(INNER, OUTER);
        cout << INNER << "\t" << OUTER << "\t" << time << "\n";
    }
}
</code>```

That's what it compiles to (the loop itself):

```<code>00401062  xor         ecx,ecx
00401064  test        ebp,ebp
00401066  jle         count+83h (401083h)
00401068  xor         eax,eax
0040106A  test        ebx,ebx
0040106C  jle         count+7Ch (40107Ch)
0040106E  mov         edi,edi
00401070  or          esi,ecx
00401072  mov         dword ptr [edi+eax*4],esi
00401075  add         eax,1
00401078  cmp         eax,ebx
0040107A  jl          count+70h (401070h)
0040107C  add         ecx,1
0040107F  cmp         ecx,ebp
00401081  jl          count+68h (401068h)
</code>```

That's what the program outputs on my machine:

```<code>LOG2(INNER) LOG2(OUTER)  Time, ms
4           25           523
5           24           569
6           23           441
7           22           400
8           21           367
9           20           358
10          19           349
11          18           364
12          17           378
13          16           384
14          15           357
15          14           377
16          13           379
17          12           390
18          11           386
19          10           419
20          9            995
21          8            1,015
22          7            1,038
23          6            1,071
24          5            1,082
25          4            1,119
</code>```

I ask people to explain what's going on. As inner array grows, the number of cycles decreases, as the time does. As inner array outgrows the cache, cache misses begin to happen and time raises. It's all right so far.

BUT: when the INNER array size is 16 (that gives us 64 bytes of data), there is little performance boost, despite the greater number of jmps in code. It's little (523 vs. 569), but reproducible.

The question is: why this boost?

答: Just to clarify, some of the spaces in his table should actually be ,'s. you all can figure it out.</p>

OwnerDisplayName: Quassnoi

ContentLicense: CC BY-SA 2.5

Title: Cache, loops and performance

Body:
Some time ago I wrote a little piece of code to ask about on interviews and see how people understand concepts of cache and memory:

#include "stdafx.h"
#include <stdlib.h>
#include <windows.h>
#include <iostream>

#define TOTAL 0x20000000

using namespace std;

__int64 count(int INNER, int OUTER)
{
    int a = 0;
    int* arr = (int*) HeapAlloc(GetProcessHeap(), 0, INNER * sizeof(int));
    if (!arr) {
        cerr << "HeapAlloc failed\n";
        return 1;
    }
    LARGE_INTEGER freq;
    LARGE_INTEGER startTime, endTime;
    __int64 elapsedTime, elapsedMilliseconds;
    QueryPerformanceFrequency(&freq);
    QueryPerformanceCounter(&startTime);

    /* Начало работы */

    for (int i = 0; i < OUTER; i++) {
        for (int j = 0; j < INNER; j++) {
            a |= i;
            arr[j] = a;
        }
    }

    /* Конец работы */

    QueryPerformanceCounter(&endTime);
    elapsedTime = endTime.QuadPart - startTime.QuadPart;
    elapsedMilliseconds = (1000 * elapsedTime) / freq.QuadPart;
    HeapFree(GetProcessHeap(), 0, arr);
    return elapsedMilliseconds;
}

int _tmain(int argc, _TCHAR* argv[])
{
    __int64 time;
    for (int INNER = 0x10; INNER <= 0x2000000; INNER <<= 1) {
        int OUTER = TOTAL / INNER;
        time = count(INNER, OUTER);
        cout << INNER << "\t" << OUTER << "\t" << time << "\n";
    }
}

That's what it compiles to (the loop itself):

00401062  xor         ecx,ecx
00401064  test        ebp,ebp
00401066  jle         count+83h (401083h)
00401068  xor         eax,eax
0040106A  test        ebx,ebx
0040106C  jle         count+7Ch (40107Ch)
0040106E  mov         edi,edi
00401070  or          esi,ecx
00401072  mov         dword ptr [edi+eax*4],esi
00401075  add         eax,1
00401078  cmp         eax,ebx
0040107A  jl          count+70h (401070h)
0040107C  add         ecx,1
0040107F  cmp         ecx,ebp
00401081  jl          count+68h (401068h)

That's what the program outputs on my machine:

LOG2(INNER) LOG2(OUTER)  Time, ms
4           25           523
5           24           569
6           23           441
7           22           400
8           21           367
9           20           358
10          19           349
11          18           364
12          17           378
13          16           384
14          15           357
15          14           377
16          13           379
17          12           390
18          11           386
19          10           419
20          9            995
21          8            1,015
22          7            1,038
23          6            1,071
24          5            1,082
25          4            1,119

I ask people to explain what's going on. As inner array grows, the number of cycles decreases, as the time does. As inner array outgrows the cache, cache misses begin to happen and time raises. It's all right so far.

BUT: when the INNER array size is 16 (that gives us 64 bytes of data), there is little performance boost, despite the greater number of jmps in code. It's little (523 vs. 569), but reproducible.

The question is: why this boost?

LastEditorDisplayName: Quassnoi


问:
loading images few images from a bigger image file JavaScript
QUESTION: How can I load in 1 to 9 random images from a file containing hundreds of other images with JavaScript?

Just wanted to know if anyone here has any ideas for me. Because in the example below I am having trouble finding out how this website does it.

Thanks for the help.

example here

答: If each pokemon is an object with multiple properties (type, stats, etc), one of those properties were "imageid", you could use Math.random or a similar method to generate a random number between 1 and x, where x is your total number of images. Then a for...in loop to find the pokemon with the corresponding imageid, and display the appropriate image.</p>


问:
Find max height-width of irregular shape drawn on HTML 5 canvas
I've been doing some image processing recently, and am looking for a javascript solution to determine the longest line segment that is entirely within a non-regular shape. To sum it up, the line segment should be the longest line segment that touches the shape and not overlaps or moves outside of the shape.

Here are the steps which I have followed

step 1:

step 2:

step 3:

as shown in step 3 Blue line indicates max length.
It is working perfectly to determine the length of regular shapes, but in case of irregular shapes it is not working (also in the case of 3 points).

To calculate length first I have taken points (which are mouse coordinates on the canvas down event.

Here is the snippet for Canvas down :

```<code>function getXY(e) {
    var el = document.getElementById('canvas');
    var rect = el.getBoundingClientRect();
    /* console.log("widht "+$("#canvas").width());
    console.log("heihgt "+$("#canvas").height());
    console.log("X "+Math.round(e.clientX - rect.left));
    console.log("y "+Math.round(e.clientY - rect.top));*/
    return {
        x: Math.round(e.clientX - rect.left),
        y: Math.round(e.clientY - rect.top)
    }
}

 $('#canvas').mousedown(function(e) {
        var can = document.getElementById("canvas");
        var ctx = can.getContext('2d');
        if (condition == 1) {
            if (e.which == 1) {
                //store the points on mousedown
                var poss = getXY(e);
                i = i + 1;
                if (firstX == poss.x && firstY == poss.y) {
                    console.log(" inside if  poss.x===" + poss.x + " poss.y===" + poss.y);
                    //$('#crop').click();
                } else {
                    console.log(" inside else  poss.x===" + poss.x + " poss.y===" + poss.y);
                    points.push(Math.round(poss.x), Math.round(poss.y));
                    pointsforline.push({ "x": Math.round(poss.x), "y": Math.round(poss.y) });
                    xarray.push(poss.x);
                    yarray.push(poss.y);
                    sendpoints.push(Math.round(poss.x), Math.round(poss.y));
                    if(points.length >= 6){
                        $('#fixMarkingBtn').show();
                    }
                }

                // Type 1 using array

                 if(points.length == 6  && sendpoints.length ==6 ){
                 $('#fixMarkingBtn').show();
                 }

                // Type 2 using counter

               /* if (i == 3) {
                    $('#fixMarkingBtn').show();
                }*/

                if (i == 1) {
                    $('#undoMarkingBtn').show();
                    $('#resetMarkingBtn').show();
                    firstX = poss.x;
                    firstY = poss.y;
                    //change is here
                    Xmax = poss.x;
                    Ymax = poss.y;
                    Xmin = poss.x;
                    Ymin = poss.y;
                    minX1 = poss.x;
                    maxY1 = poss.y;
                    minX1 = poss.x;
                    minY1 = poss.y;

                }
                if (poss.x < Xmin) {
                    Xmin = poss.x;
                    minY1 = poss.y;
                }
                if (poss.x > Xmax) {
                    Xmax = poss.x;
                    maxY1 = poss.y;
                }
                if (poss.y < Ymin) {
                    Ymin = poss.y;
                    minX1 = poss.x;
                }
                if (poss.y > Ymax) {
                    Ymax = poss.y;
                    maxX1 = poss.x;
                }
                ctx.globalCompositeOperation = 'source-over';
                var oldposx = $('#oldposx').html();
                var oldposy = $('#oldposy').html();
                var posx = $('#posx').html();
                var posy = $('#posy').html();
                ctx.beginPath();
                ctx.lineWidth = 13;
                ctx.moveTo(oldposx, oldposy);
                if (oldposx != '') {
                    ctx.lineTo(posx, posy);
                    ctx.stroke();
                }
                $('#oldposx').html(poss.x);
                $('#oldposy').html(poss.y);
            }
            ctx.fillStyle = 'red';
            ctx.strokeStyle = 'red';
            ctx.fillRect(posx, posy, 10, 10);
            $('#posx').html(posx);
            $('#posy').html(posy);
        } //condition

    });
</code>```

here is the code I have used (point of problem) :

```<code>function calMaxMin() {
    for (var i = 0; i < points.length; i += 2) {
        if (i == 0) {
            Xmax = points[i];
            Ymax = points[i + 1];
            Xmin = points[i];
            Ymin = points[i + 1];
            minX1 = points[i];
            maxY1 = points[i + 1];
            minX1 = points[i];
            minY1 = points[i + 1];
        }
        if (points[i] < Xmin) {
            Xmin = points[i];
            minY1 = points[i + 1];
        }
        if (points[i] > Xmax) {
            Xmax = points[i];
            maxY1 = points[i + 1];
        }
        if (points[i + 1] < Ymin) {
            Ymin = points[i + 1];
            minX1 = points[i];
        }
        if (points[i + 1] > Ymax) {
            Ymax = points[i + 1];
            maxX1 = points[i];
        }
    }
}
</code>```

Problem image 1

Problem image 2 (what I'm getting right now)

Expected output

Any help would be appreciated.

Thanks in advance!

答:
The problem's complexity changes when you switch from a convex polygon to a concave polygon: you need to check for intersections and "grow" candidate segments.

With a convex polygon, you have one candidate set, defined by all segments (p1, p2), (p1, p3), ..., (p2, p3), ..., (pn-1, pn), wherein the longest of those candidates is the result:

This example has a total 10 candidates. You simply select the longest one.

When you include concave polygons you must modify the candidate segments to stretch to the edges of the polygon and exclude any segments that intersect the polygon.

The red segments are excluded. The green segments are the modified ones. There are more complicated cases not depicted as well.

NOTE: I've had to play quite a bit with this math in the past and will be linking to functions of an old JavaScript library I built. Points are represented as { x: number, y: number} and polygons as arrays of points.

Segments can be excluded for two reasons:

Either endpoint starts with the segment leaving the polygon. You can test this by getting the global angle of the candidate segment (from said endpoint) and the global angles of the two adjacent polygon edges and checking if the candidate segment's angle falls between those two.

The candidate segment intersects any of the edges (inclusive of edge endpoints).

Extension of segments is somewhat complicated:

Find all segments wherein either endpoint is a concave vertex of the polygon. Include it twice if both endpoints are concave.

For said (segment, endpoint) pairs, stretch the segment through the endpoint a long distance (like 10000000) via polar projection.

Detect all intersection points of the elongated segment with the polygon.

Find the intersection point that is nearest the unmodified endpoint. This intersection point and the unmodified endpoint is the new candidate segment.

The result is the longest remaining candidate segment.

HINT: Might I recommend using GeoGebra for diagramming (I am in no way affiliated)?

Body:
I've been doing some image processing recently, and am looking for a javascript solution to determine the longest line segment that is entirely within a non-regular shape. To sum it up, the line segment should be the longest line segment that touches the shape and not overlaps or moves outside of the shape.

Here are the steps which I have followed

step 1:

step 2:

step 3:

as shown in step 3 Blue line indicates max length.
It is working perfectly to determine the length of regular shapes, but in case of irregular shapes it is not working (also in the case of 3 points).

To calculate length first I have taken points (which are mouse coordinates on the canvas down event.

Here is the snippet for Canvas down :

function getXY(e) {
    var el = document.getElementById('canvas');
    var rect = el.getBoundingClientRect();
    /* console.log("widht "+$("#canvas").width());
    console.log("heihgt "+$("#canvas").height());
    console.log("X "+Math.round(e.clientX - rect.left));
    console.log("y "+Math.round(e.clientY - rect.top));*/
    return {
        x: Math.round(e.clientX - rect.left),
        y: Math.round(e.clientY - rect.top)
    }
}

 $('#canvas').mousedown(function(e) {
        var can = document.getElementById("canvas");
        var ctx = can.getContext('2d');
        if (condition == 1) {
            if (e.which == 1) {
                //store the points on mousedown
                var poss = getXY(e);
                i = i + 1;
                if (firstX == poss.x && firstY == poss.y) {
                    console.log(" inside if  poss.x===" + poss.x + " poss.y===" + poss.y);
                    //$('#crop').click();
                } else {
                    console.log(" inside else  poss.x===" + poss.x + " poss.y===" + poss.y);
                    points.push(Math.round(poss.x), Math.round(poss.y));
                    pointsforline.push({ "x": Math.round(poss.x), "y": Math.round(poss.y) });
                    xarray.push(poss.x);
                    yarray.push(poss.y);
                    sendpoints.push(Math.round(poss.x), Math.round(poss.y));
                    if(points.length >= 6){
                        $('#fixMarkingBtn').show();
                    }
                }

                // Type 1 using array

                 if(points.length == 6  && sendpoints.length ==6 ){
                 $('#fixMarkingBtn').show();
                 }

                // Type 2 using counter

               /* if (i == 3) {
                    $('#fixMarkingBtn').show();
                }*/

                if (i == 1) {
                    $('#undoMarkingBtn').show();
                    $('#resetMarkingBtn').show();
                    firstX = poss.x;
                    firstY = poss.y;
                    //change is here
                    Xmax = poss.x;
                    Ymax = poss.y;
                    Xmin = poss.x;
                    Ymin = poss.y;
                    minX1 = poss.x;
                    maxY1 = poss.y;
                    minX1 = poss.x;
                    minY1 = poss.y;

                }
                if (poss.x < Xmin) {
                    Xmin = poss.x;
                    minY1 = poss.y;
                }
                if (poss.x > Xmax) {
                    Xmax = poss.x;
                    maxY1 = poss.y;
                }
                if (poss.y < Ymin) {
                    Ymin = poss.y;
                    minX1 = poss.x;
                }
                if (poss.y > Ymax) {
                    Ymax = poss.y;
                    maxX1 = poss.x;
                }
                ctx.globalCompositeOperation = 'source-over';
                var oldposx = $('#oldposx').html();
                var oldposy = $('#oldposy').html();
                var posx = $('#posx').html();
                var posy = $('#posy').html();
                ctx.beginPath();
                ctx.lineWidth = 13;
                ctx.moveTo(oldposx, oldposy);
                if (oldposx != '') {
                    ctx.lineTo(posx, posy);
                    ctx.stroke();
                }
                $('#oldposx').html(poss.x);
                $('#oldposy').html(poss.y);
            }
            ctx.fillStyle = 'red';
            ctx.strokeStyle = 'red';
            ctx.fillRect(posx, posy, 10, 10);
            $('#posx').html(posx);
            $('#posy').html(posy);
        } //condition

    });

here is the code I have used (point of problem) :

function calMaxMin() {
    for (var i = 0; i < points.length; i += 2) {
        if (i == 0) {
            Xmax = points[i];
            Ymax = points[i + 1];
            Xmin = points[i];
            Ymin = points[i + 1];
            minX1 = points[i];
            maxY1 = points[i + 1];
            minX1 = points[i];
            minY1 = points[i + 1];
        }
        if (points[i] < Xmin) {
            Xmin = points[i];
            minY1 = points[i + 1];
        }
        if (points[i] > Xmax) {
            Xmax = points[i];
            maxY1 = points[i + 1];
        }
        if (points[i + 1] < Ymin) {
            Ymin = points[i + 1];
            minX1 = points[i];
        }
        if (points[i + 1] > Ymax) {
            Ymax = points[i + 1];
            maxX1 = points[i];
        }
    }
}

Problem image 1

Problem image 2 (what I'm getting right now)

Expected output

Any help would be appreciated.

Thanks in advance!


问:
Angular - How to create a persistent/permanent "Add to Home screen" button in my web app, just like Google Contribute
How to create a persistent/permanent "Add to Home screen" button in my web app, just like Google Contribute? (see image below)

Background: It's an Angular v5 app with PWA service worker and manifest.json all setup. On landing in the app, a banner will pop-up inviting users to Add to Home Screen. It's all working good.

So how to have a button in my web app like Google Contribute (see image below)?

答:
There is really no standard and no API to do that.
That being said, something can still be done.

As specified here:

https://developers.google.com/web/fundamentals/app-install-banners/

If you app meets certain criteria, Chrome will automatically show a banner to the user.

```<code>Has a web app manifest file with:
    a short_name (used on the home screen)
    a name (used in the banner)
    a 192x192 png icon (the icon declarations must include a mime type of image/png)
    a start_url that loads
Has a service worker registered on your site.
Is served over HTTPS (a requirement for using service worker).
Meets a site engagement heuristic defined by Chrome (this is regularly being changed).
</code>```

As alternative for iOS, I suggest the following library:

http://cubiq.org/add-to-home-screen (https://github.com/cubiq/add-to-homescreen)

Body:
There is really no standard and no API to do that.
That being said, something can still be done.

As specified here:

https://developers.google.com/web/fundamentals/app-install-banners/

If you app meets certain criteria, Chrome will automatically show a banner to the user.

Has a web app manifest file with:
    a short_name (used on the home screen)
    a name (used in the banner)
    a 192x192 png icon (the icon declarations must include a mime type of image/png)
    a start_url that loads
Has a service worker registered on your site.
Is served over HTTPS (a requirement for using service worker).
Meets a site engagement heuristic defined by Chrome (this is regularly being changed).

As alternative for iOS, I suggest the following library:

http://cubiq.org/add-to-home-screen (https://github.com/cubiq/add-to-homescreen)


问:
ic_launcher_foreground.xml is having trouble finding several attributes while gradle build
i just upgraded from android studio 2.1 to a stable 3.0 and i'm getting errors while making a new project on it (i am also new to android studio :D)
here are the errors am getting

Error:(7) No resource identifier found for attribute 'fillType' in package 'android'

Error:(28) No resource identifier found for attribute 'fillType' in package 'android'

Error:(13) No resource identifier found for attribute 'endX' in package 'android'

Error:(13) No resource identifier found for attribute 'startX' in package 'android'

Error:(19) No resource identifier found for attribute 'offset' in package 'android'

and a couple of exceptions

Error:java.util.concurrent.ExecutionException: com.android.ide.common.process.ProcessException: Error while executing process E:\AndroidSDK\build-tools\27.0.1\aapt.exe with arguments {package -f --no-crunch -I E:\AndroidSDK\platforms\android-23\android.jar -M \?\C:\Users\ShaD iLiX\AndroidStudioProjects\Test1\app\build\intermediates\manifests\full\debug\AndroidManifest.xml -S C:\Users\ShaD iLiX\AndroidStudioProjects\Test1\app\build\intermediates\res\merged\debug -m -J \?\C:\Users\ShaD iLiX\AndroidStudioProjects\Test1\app\build\generated\source\r\debug -F C:\Users\ShaD iLiX\AndroidStudioProjects\Test1\app\build\intermediates\res\debug\resources-debug.ap_ --custom-package com.example.shadilix.test1 -0 apk --output-text-symbols \?\C:\Users\ShaD iLiX\AndroidStudioProjects\Test1\app\build\intermediates\symbols\debug --no-version-vectors}

Error:com.android.ide.common.process.ProcessException: Error while executing process E:\AndroidSDK\build-tools\27.0.1\aapt.exe with arguments {package -f --no-crunch -I E:\AndroidSDK\platforms\android-23\android.jar -M \?\C:\Users\ShaD iLiX\AndroidStudioProjects\Test1\app\build\intermediates\manifests\full\debug\AndroidManifest.xml -S C:\Users\ShaD iLiX\AndroidStudioProjects\Test1\app\build\intermediates\res\merged\debug -m -J \?\C:\Users\ShaD iLiX\AndroidStudioProjects\Test1\app\build\generated\source\r\debug -F C:\Users\ShaD iLiX\AndroidStudioProjects\Test1\app\build\intermediates\res\debug\resources-debug.ap_ --custom-package com.example.shadilix.test1 -0 apk --output-text-symbols \?\C:\Users\ShaD iLiX\AndroidStudioProjects\Test1\app\build\intermediates\symbols\debug --no-version-vectors}

Error:org.gradle.process.internal.ExecException: Process 'command 'E:\AndroidSDK\build-tools\27.0.1\aapt.exe'' finished with non-zero exit value 1

Error:Execution failed for task ':app:processDebugResources'.

Failed to execute aapt

Here is the ic_Launcher_foreground.xml code :

```<code><vector xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:aapt="http://schemas.android.com/aapt"
android:width="108dp"
android:height="108dp"
android:viewportHeight="108"
android:viewportWidth="108">
<path
    android:fillType="evenOdd"
    android:pathData="M32,64C32,64 38.39,52.99 44.13,50.95C51.37,48.37 70.14,49.57 70.14,49.57L108.26,87.69L108,109.01L75.97,107.97L32,64Z"
    android:strokeColor="#00000000"
    android:strokeWidth="1">
    <aapt:attr name="android:fillColor">
        <gradient
            android:endX="78.5885"
            android:endY="90.9159"
            android:startX="48.7653"
            android:startY="61.0927"
            android:type="linear">
            <item
                android:color="#44000000"
                android:offset="0.0" />
            <item
                android:color="#00000000"
                android:offset="1.0" />
        </gradient>
    </aapt:attr>
</path>
<path
    android:fillColor="#FFFFFF"
    android:fillType="nonZero"
    android:pathData="M66.94,46.02L66.94,46.02C72.44,50.07 76,56.61 76,64L32,64C32,56.61 35.56,50.11 40.98,46.06L36.18,41.19C35.45,40.45 35.45,39.3 36.18,38.56C36.91,37.81 38.05,37.81 38.78,38.56L44.25,44.05C47.18,42.57 50.48,41.71 54,41.71C57.48,41.71 60.78,42.57 63.68,44.05L69.11,38.56C69.84,37.81 70.98,37.81 71.71,38.56C72.44,39.3 72.44,40.45 71.71,41.19L66.94,46.02ZM62.94,56.92C64.08,56.92 65,56.01 65,54.88C65,53.76 64.08,52.85 62.94,52.85C61.8,52.85 60.88,53.76 60.88,54.88C60.88,56.01 61.8,56.92 62.94,56.92ZM45.06,56.92C46.2,56.92 47.13,56.01 47.13,54.88C47.13,53.76 46.2,52.85 45.06,52.85C43.92,52.85 43,53.76 43,54.88C43,56.01 43.92,56.92 45.06,56.92Z"
    android:strokeColor="#00000000"
    android:strokeWidth="1" />
</code>```

here is My build.gradle file

```<code>    apply plugin: 'com.android.application'

android {
    compileSdkVersion 23
    buildToolsVersion "27.0.1"

    defaultConfig {
        applicationId "com.example.shadilix.test1"
        minSdkVersion 23
        targetSdkVersion 23
        versionCode 1
        versionName "1.0"
        testInstrumentationRunner "android.support.test.runner.AndroidJUnitRunner"
    }
    buildTypes {
        release {
            minifyEnabled false
            proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'
        }
    }
}

dependencies {
    implementation fileTree(dir: 'libs', include: ['*.jar'])
    implementation 'com.android.support:appcompat-v7:23.+'
    implementation 'com.android.support.constraint:constraint-layout:1.0.2'
    testImplementation 'junit:junit:4.12'
    androidTestImplementation 'com.android.support.test:runner:1.0.1'
    androidTestImplementation 'com.android.support.test.espresso:espresso-core:3.0.1'
}
</code>```

答: clean build and/or restart and invalidate might solve the issue</p>

Body:
i just upgraded from android studio 2.1 to a stable 3.0 and i'm getting errors while making a new project on it (i am also new to android studio :D)
here are the errors am getting

Error:(7) No resource identifier found for attribute 'fillType' in package 'android'

Error:(28) No resource identifier found for attribute 'fillType' in package 'android'

Error:(13) No resource identifier found for attribute 'endX' in package 'android'

Error:(13) No resource identifier found for attribute 'startX' in package 'android'

Error:(19) No resource identifier found for attribute 'offset' in package 'android'

and a couple of exceptions

Error:java.util.concurrent.ExecutionException: com.android.ide.common.process.ProcessException: Error while executing process E:\AndroidSDK\build-tools\27.0.1\aapt.exe with arguments {package -f --no-crunch -I E:\AndroidSDK\platforms\android-23\android.jar -M \?\C:\Users\ShaD iLiX\AndroidStudioProjects\Test1\app\build\intermediates\manifests\full\debug\AndroidManifest.xml -S C:\Users\ShaD iLiX\AndroidStudioProjects\Test1\app\build\intermediates\res\merged\debug -m -J \?\C:\Users\ShaD iLiX\AndroidStudioProjects\Test1\app\build\generated\source\r\debug -F C:\Users\ShaD iLiX\AndroidStudioProjects\Test1\app\build\intermediates\res\debug\resources-debug.ap_ --custom-package com.example.shadilix.test1 -0 apk --output-text-symbols \?\C:\Users\ShaD iLiX\AndroidStudioProjects\Test1\app\build\intermediates\symbols\debug --no-version-vectors}

Error:com.android.ide.common.process.ProcessException: Error while executing process E:\AndroidSDK\build-tools\27.0.1\aapt.exe with arguments {package -f --no-crunch -I E:\AndroidSDK\platforms\android-23\android.jar -M \?\C:\Users\ShaD iLiX\AndroidStudioProjects\Test1\app\build\intermediates\manifests\full\debug\AndroidManifest.xml -S C:\Users\ShaD iLiX\AndroidStudioProjects\Test1\app\build\intermediates\res\merged\debug -m -J \?\C:\Users\ShaD iLiX\AndroidStudioProjects\Test1\app\build\generated\source\r\debug -F C:\Users\ShaD iLiX\AndroidStudioProjects\Test1\app\build\intermediates\res\debug\resources-debug.ap_ --custom-package com.example.shadilix.test1 -0 apk --output-text-symbols \?\C:\Users\ShaD iLiX\AndroidStudioProjects\Test1\app\build\intermediates\symbols\debug --no-version-vectors}

Error:org.gradle.process.internal.ExecException: Process 'command 'E:\AndroidSDK\build-tools\27.0.1\aapt.exe'' finished with non-zero exit value 1

Error:Execution failed for task ':app:processDebugResources'.

Failed to execute aapt

Here is the ic_Launcher_foreground.xml code :

<vector xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:aapt="http://schemas.android.com/aapt"
android:width="108dp"
android:height="108dp"
android:viewportHeight="108"
android:viewportWidth="108">
<path
    android:fillType="evenOdd"
    android:pathData="M32,64C32,64 38.39,52.99 44.13,50.95C51.37,48.37 70.14,49.57 70.14,49.57L108.26,87.69L108,109.01L75.97,107.97L32,64Z"
    android:strokeColor="#00000000"
    android:strokeWidth="1">
    <aapt:attr name="android:fillColor">
        <gradient
            android:endX="78.5885"
            android:endY="90.9159"
            android:startX="48.7653"
            android:startY="61.0927"
            android:type="linear">
            <item
                android:color="#44000000"
                android:offset="0.0" />
            <item
                android:color="#00000000"
                android:offset="1.0" />
        </gradient>
    </aapt:attr>
</path>
<path
    android:fillColor="#FFFFFF"
    android:fillType="nonZero"
    android:pathData="M66.94,46.02L66.94,46.02C72.44,50.07 76,56.61 76,64L32,64C32,56.61 35.56,50.11 40.98,46.06L36.18,41.19C35.45,40.45 35.45,39.3 36.18,38.56C36.91,37.81 38.05,37.81 38.78,38.56L44.25,44.05C47.18,42.57 50.48,41.71 54,41.71C57.48,41.71 60.78,42.57 63.68,44.05L69.11,38.56C69.84,37.81 70.98,37.81 71.71,38.56C72.44,39.3 72.44,40.45 71.71,41.19L66.94,46.02ZM62.94,56.92C64.08,56.92 65,56.01 65,54.88C65,53.76 64.08,52.85 62.94,52.85C61.8,52.85 60.88,53.76 60.88,54.88C60.88,56.01 61.8,56.92 62.94,56.92ZM45.06,56.92C46.2,56.92 47.13,56.01 47.13,54.88C47.13,53.76 46.2,52.85 45.06,52.85C43.92,52.85 43,53.76 43,54.88C43,56.01 43.92,56.92 45.06,56.92Z"
    android:strokeColor="#00000000"
    android:strokeWidth="1" />

here is My build.gradle file

    apply plugin: 'com.android.application'

android {
    compileSdkVersion 23
    buildToolsVersion "27.0.1"

    defaultConfig {
        applicationId "com.example.shadilix.test1"
        minSdkVersion 23
        targetSdkVersion 23
        versionCode 1
        versionName "1.0"
        testInstrumentationRunner "android.support.test.runner.AndroidJUnitRunner"
    }
    buildTypes {
        release {
            minifyEnabled false
            proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'
        }
    }
}

dependencies {
    implementation fileTree(dir: 'libs', include: ['*.jar'])
    implementation 'com.android.support:appcompat-v7:23.+'
    implementation 'com.android.support.constraint:constraint-layout:1.0.2'
    testImplementation 'junit:junit:4.12'
    androidTestImplementation 'com.android.support.test:runner:1.0.1'
    androidTestImplementation 'com.android.support.test.espresso:espresso-core:3.0.1'
}


问:
VS Code resx file extension
Seems like there is no way to automatically create and manage resx files in VS Code now. Does someone know extension for it?

P.S. Yeah, I know that I can edit resx file as bare xml, but it`s not a right way.

答:
The problem with resx is that it uses a Visual Studio "Custom Tool" to generate the code for the resources, and so requires Visual Studio to function fully.

I've been working on a replacement to resx that should also work from VS Code. It uses json rather than xml to define the resources, but otherwise behaves much like a resx file. The json resources file uses a ".resj" extension, and has a very simple structure. It currently only supports string resources that can be defined either inline in the json, or in an external file reference.

The project is open source on GitHub here:
https://github.com/MarkPflug/Elemental.JsonResource/

This is available as a nuget package "Elemental.JsonResource", currently only pre-release. Simply add this package to your project to enable using resj files. It doesn't add a runtime dependency to your project, everything is done at build-time. My hope is to provide feature-parity with what a resx file can do, but it could be useful even in its current state.

Title: VS Code resx file extension


问:
shopify hmac verification php
This is my code :

```<code>function verifyRequest($request, $secret) {
  // Per the Shopify docs:
  // Everything except hmac and signature...

  $hmac = $request['hmac'];
  unset($request['hmac']);
  unset($request['signature']);

  // Sorted lexilogically...
  ksort($request);

  // Special characters replaced...
  foreach ($request as $k => $val) {
    $k = str_replace('%', '%25', $k);
    $k = str_replace('&', '%26', $k);
    $k = str_replace('=', '%3D', $k);
    $val = str_replace('%', '%25', $val);
    $val = str_replace('&', '%26', $val);
    $params[$k] = $val;
  }

  echo $http = "protocol=". urldecode("https://").http_build_query( $params) ;
  echo $test = hash_hmac("sha256", $http , $secret);

  // enter code hereVerified when equal
  return $hmac === $test;
}
</code>```

The hmac from shopi and hmac created from my code is not matching.

What am I doing wrong?

答:
You only need to include the request parameters when creating the list of key-value pairs - don't need "protocol=https://".

https://help.shopify.com/api/getting-started/authentication/oauth#verification

You'll need to urldecode() the result of http_build_query(). It returns a url-encoded query string.

http://php.net/manual/en/function.http-build-query.php

Instead of:

```<code> echo $http = "protocol=". urldecode("https://").http_build_query( $params) ;
 echo $test = hash_hmac("sha256", $http , $secret);
</code>```

Something like this:

```<code> $http = urldecode(http_build_query($params));
 $test = hash_hmac('sha256', $http, $secret);
</code>```

Title: shopify hmac verification php

Body:
This is my code :

function verifyRequest($request, $secret) {
  // Per the Shopify docs:
  // Everything except hmac and signature...

  $hmac = $request['hmac'];
  unset($request['hmac']);
  unset($request['signature']);

  // Sorted lexilogically...
  ksort($request);

  // Special characters replaced...
  foreach ($request as $k => $val) {
    $k = str_replace('%', '%25', $k);
    $k = str_replace('&', '%26', $k);
    $k = str_replace('=', '%3D', $k);
    $val = str_replace('%', '%25', $val);
    $val = str_replace('&', '%26', $val);
    $params[$k] = $val;
  }

  echo $http = "protocol=". urldecode("https://").http_build_query( $params) ;
  echo $test = hash_hmac("sha256", $http , $secret);

  // enter code hereVerified when equal
  return $hmac === $test;
}

The hmac from shopi and hmac created from my code is not matching.

What am I doing wrong?

Body:
You only need to include the request parameters when creating the list of key-value pairs - don't need "protocol=https://".

https://help.shopify.com/api/getting-started/authentication/oauth#verification

You'll need to urldecode() the result of http_build_query(). It returns a url-encoded query string.

http://php.net/manual/en/function.http-build-query.php

Instead of:

 echo $http = "protocol=". urldecode("https://").http_build_query( $params) ;
 echo $test = hash_hmac("sha256", $http , $secret);

Something like this:

 $http = urldecode(http_build_query($params));
 $test = hash_hmac('sha256', $http, $secret);


问:
How use long instead of int can bulletproof the following method - Effective Java
Consider the following code picked from Joshua Bloch - Effective Java, page 263

```<code>// Broken - requires synchronization!
private static volatile int nextSerialNumber = 0;
public static int generateSerialNumber() {
    return nextSerialNumber++;
}
</code>```

One way to fix the
  generateSerialNumber method is to add
  the synchronized modifier to its
  declaration. This ensures that
  multiple invocations won’t be
  interleaved, and that each invocation
  will see the effects of all previous
  invocations. Once you’ve done that,
  you can and should remove the volatile
  modifier from nextSerialNumber. To
  bulletproof the method, use long
  instead of int, or throw an exception
  if nextSerialNumber is about to wrap.

I understand that we can remove volatile after we make generateSerialNumber synchronized, as it is redundant. But, does it make any harm? Any performance penalty if I am having both synchronized and volatile like

```<code>private static volatile int nextSerialNumber = 0;
public static synchronized int generateSerialNumber() {
    return nextSerialNumber++;
}
</code>```

What does, use long instead of int means? I do not understand how this bulletproof the method?

答:
It simply means that long will hold many more numbers than int.

or throw an exception if nextSerialNumber is about to wrap

implies that the concern here is that you run out of numbers and you end up with an overflow. You want to ensure that does not happen. The thing is, if you are at the maximum integer possible and you increment, the program does not fail. It happily goes not incrementing but the result is no longer correct.

Using long will postpone this possibility. Throwing the exception will indicate that it has happened.

Body:
Consider the following code picked from Joshua Bloch - Effective Java, page 263

// Broken - requires synchronization!
private static volatile int nextSerialNumber = 0;
public static int generateSerialNumber() {
    return nextSerialNumber++;
}

One way to fix the
  generateSerialNumber method is to add
  the synchronized modifier to its
  declaration. This ensures that
  multiple invocations won’t be
  interleaved, and that each invocation
  will see the effects of all previous
  invocations. Once you’ve done that,
  you can and should remove the volatile
  modifier from nextSerialNumber. To
  bulletproof the method, use long
  instead of int, or throw an exception
  if nextSerialNumber is about to wrap.

I understand that we can remove volatile after we make generateSerialNumber synchronized, as it is redundant. But, does it make any harm? Any performance penalty if I am having both synchronized and volatile like

private static volatile int nextSerialNumber = 0;
public static synchronized int generateSerialNumber() {
    return nextSerialNumber++;
}

What does, use long instead of int means? I do not understand how this bulletproof the method?


问:
my own directive is not working AngularJS
I try to create my directiv. When I make the same code on start angularjs is stopped.

```<code>demo
</code>```

https://codepen.io/Turqus/pen/yPPmbG?editors=1011

Could someone explain me whats wrong is?

答:
you have to put the first letter of the directives name in lower case as the error in the console told you ( F12 in any browser, then go to console tab ) :

error log : "Directive/Component name 'MyExample' is invalid. The first character must be a lowercase letter"

```<code>    (function(){

  angular
    .module('App', [])
    .controller('ExampleCtrl', ExampleCtrl);

  function ExampleCtrl() {
    var vm = this;
    vm.name = "yo";
  };

})();

(function(){

  angular
    .module('App')
    .directive('myExample', MyExample);    // <----------------- HER

    function MyExample() {
      var directive = {
        restrict: 'E',
        template: '<div>one more time</div>',
        controller: 'MyController',
        controllerAs: 'vm'
      };
      return directive;
    }

    function MyController() {

    }

})();
</code>```

Body:
I try to create my directiv. When I make the same code on start angularjs is stopped.

demo

https://codepen.io/Turqus/pen/yPPmbG?editors=1011

Could someone explain me whats wrong is?

Body:
you have to put the first letter of the directives name in lower case as the error in the console told you ( F12 in any browser, then go to console tab ) :

error log : "Directive/Component name 'MyExample' is invalid. The first character must be a lowercase letter"

    (function(){

  angular
    .module('App', [])
    .controller('ExampleCtrl', ExampleCtrl);

  function ExampleCtrl() {
    var vm = this;
    vm.name = "yo";
  };

})();

(function(){

  angular
    .module('App')
    .directive('myExample', MyExample);    // <----------------- HER

    function MyExample() {
      var directive = {
        restrict: 'E',
        template: '<div>one more time</div>',
        controller: 'MyController',
        controllerAs: 'vm'
      };
      return directive;
    }

    function MyController() {

    }

})();


问:
Error while making Azure IoT Hub Device Identities in bulk
I am following https://learn.microsoft.com/en-us/azure/iot-hub/iot-hub-bulk-identity-mgmt to do Bulk upload of Device Identities in Azure IoT Hub. All codes given here are in C# so I am converting it to JAVA equivalent.

Using Import devices example – bulk device provisioning I am getting following json-

```<code>{"id":"d3d78b0d-6c8c-4ef5-a321-91fbb6a4b7d1","importMode":"create","status":"enabled","authentication":{"symmetricKey":{"primaryKey":"f8/UZcYbhPxnNdbSl2J+0Q==","secondaryKey":"lbq4Y4Z8qWmfUxAQjRsDjw=="}}}
{"id":"70bbe407-8d65-4f57-936f-ef402aa66d07","importMode":"create","status":"enabled","authentication":{"symmetricKey":{"primaryKey":"9e7fDNIFbMu/NmOfxo/vGg==","secondaryKey":"nwFiKR4HV9KYHzkeyu8nLA=="}}}
</code>```

To import the file from blob following function is called-

```<code>CompletableFuture<JobProperties> importJob = registryManager
    .importDevicesAsync(inURI, outURI);
</code>```

In the above code, we need to provide URI with SAS code, for that Get the container SAS URI equivalent code is below-

```<code>static String GetContainerSasUri(CloudBlobContainer container) {
    SharedAccessBlobPolicy sasConstraints = new SharedAccessBlobPolicy();
    sasConstraints.setSharedAccessExpiryTime(new Date(new Date().getTime() + TimeUnit.DAYS.toMillis(1)));
    sasConstraints.setPermissions(EnumSet.of(SharedAccessBlobPermissions.READ, SharedAccessBlobPermissions.WRITE,
            SharedAccessBlobPermissions.LIST, SharedAccessBlobPermissions.DELETE));

    BlobContainerPermissions permissions = new BlobContainerPermissions();
    permissions.setPublicAccess(BlobContainerPublicAccessType.CONTAINER);
    permissions.getSharedAccessPolicies().put("testpolicy", sasConstraints);
    try {
        container.uploadPermissions(permissions);
    } catch (StorageException e1) {
        e1.printStackTrace();
    }
    String sasContainerToken = null;
    try {
        sasContainerToken = container.generateSharedAccessSignature(sasConstraints, "testpolicy");
    } catch (InvalidKeyException e) {
        e.printStackTrace();
    } catch (StorageException e) {
        e.printStackTrace();
    }
    System.out.println("URI " + container.getUri() +"?"+ sasContainerToken);
    return container.getUri() + "?" + sasContainerToken;
}
</code>```

Now the problem is coming here. For the output container I am getting following error-

```<code>java.util.concurrent.ExecutionException: com.microsoft.azure.sdk.iot.service.exceptions.IotHubBadFormatException: Bad message format! ErrorCode:BlobContainerValidationError;Unauthorized to write to output blob container. Tracking ID:2dcb2efbf1e14e33ba60dc8415dc03c3-G:4-TimeStamp:11/08/2017 16:16:10
</code>```

Please help me to know why I am getting Bad Message Format error? Is there a problem with the SAS key generating code or my blob container is not having Write permission?

答: are you using a service or Account-level SAS? The error thrown suggests the service isn't authorized or have the delegated permissions to write to the designated blob container. Check out the resource here on how to setup an account level SAS and how to delegate read, write and delete operations on blob containers. https://learn.microsoft.com/en-us/rest/api/storageservices/Delegating-Access-with-a-Shared-Access-Signature?redirectedfrom=MSDN "snipped content: "An account-level SAS, introduced with version 2015-04-05. The account SAS delegates access to resources in one or more of the storage services. All of the operations available via a service SAS are also available via an account SAS. Additionally, with the account SAS, you can delegate access to operations that apply to a given service, such as Get/Set Service Properties and Get Service Stats. You can also delegate access to read, write, and delete operations on blob containers, tables, queues, and file shares that are not permitted with a service SAS. See Constructing an Account SAS for more information about account SAS."</p>

Body:
I am following https://learn.microsoft.com/en-us/azure/iot-hub/iot-hub-bulk-identity-mgmt to do Bulk upload of Device Identities in Azure IoT Hub. All codes given here are in C# so I am converting it to JAVA equivalent.

Using Import devices example – bulk device provisioning I am getting following json-

{"id":"d3d78b0d-6c8c-4ef5-a321-91fbb6a4b7d1","importMode":"create","status":"enabled","authentication":{"symmetricKey":{"primaryKey":"f8/UZcYbhPxnNdbSl2J+0Q==","secondaryKey":"lbq4Y4Z8qWmfUxAQjRsDjw=="}}}
{"id":"70bbe407-8d65-4f57-936f-ef402aa66d07","importMode":"create","status":"enabled","authentication":{"symmetricKey":{"primaryKey":"9e7fDNIFbMu/NmOfxo/vGg==","secondaryKey":"nwFiKR4HV9KYHzkeyu8nLA=="}}}

To import the file from blob following function is called-

CompletableFuture<JobProperties> importJob = registryManager
    .importDevicesAsync(inURI, outURI);

In the above code, we need to provide URI with SAS code, for that Get the container SAS URI equivalent code is below-

static String GetContainerSasUri(CloudBlobContainer container) {
    SharedAccessBlobPolicy sasConstraints = new SharedAccessBlobPolicy();
    sasConstraints.setSharedAccessExpiryTime(new Date(new Date().getTime() + TimeUnit.DAYS.toMillis(1)));
    sasConstraints.setPermissions(EnumSet.of(SharedAccessBlobPermissions.READ, SharedAccessBlobPermissions.WRITE,
            SharedAccessBlobPermissions.LIST, SharedAccessBlobPermissions.DELETE));

    BlobContainerPermissions permissions = new BlobContainerPermissions();
    permissions.setPublicAccess(BlobContainerPublicAccessType.CONTAINER);
    permissions.getSharedAccessPolicies().put("testpolicy", sasConstraints);
    try {
        container.uploadPermissions(permissions);
    } catch (StorageException e1) {
        e1.printStackTrace();
    }
    String sasContainerToken = null;
    try {
        sasContainerToken = container.generateSharedAccessSignature(sasConstraints, "testpolicy");
    } catch (InvalidKeyException e) {
        e.printStackTrace();
    } catch (StorageException e) {
        e.printStackTrace();
    }
    System.out.println("URI " + container.getUri() +"?"+ sasContainerToken);
    return container.getUri() + "?" + sasContainerToken;
}

Now the problem is coming here. For the output container I am getting following error-

java.util.concurrent.ExecutionException: com.microsoft.azure.sdk.iot.service.exceptions.IotHubBadFormatException: Bad message format! ErrorCode:BlobContainerValidationError;Unauthorized to write to output blob container. Tracking ID:2dcb2efbf1e14e33ba60dc8415dc03c3-G:4-TimeStamp:11/08/2017 16:16:10

Please help me to know why I am getting Bad Message Format error? Is there a problem with the SAS key generating code or my blob container is not having Write permission?


问:
Pandas groupby and aggregation output should include all the original columns (including the ones not aggregated on)
I have the following data frame and want to:

Group records by month

Sum QTY_SOLDand NET_AMT of each unique UPC_ID(per month)

Include the rest of the columns as well in the resulting dataframe

The way I thought I can do this is 1st: create a month column to aggregate the D_DATES, then sum QTY_SOLD by UPC_ID.

Script:

```<code># Convert date to date time object
df['D_DATE'] = pd.to_datetime(df['D_DATE'])

# Create aggregated months column
df['month'] = df['D_DATE'].apply(dt.date.strftime, args=('%Y.%m',))

# Group by month and sum up quantity sold by UPC_ID
df = df.groupby(['month', 'UPC_ID'])['QTY_SOLD'].sum()
</code>```

Current data frame:

```<code>UPC_ID | UPC_DSC | D_DATE | QTY_SOLD | NET_AMT
----------------------------------------------
111      desc1    2/26/2017   2         10 (2 x $5)
222      desc2    2/26/2017   3         15
333      desc3    2/26/2017   1         4
111      desc1    3/1/2017    1         5
111      desc1    3/3/2017    4         20
</code>```

Desired Output:

```<code>MONTH | UPC_ID | QTY_SOLD | NET_AMT | UPC_DSC
----------------------------------------------
2017-2      111     2         10       etc...
2017-2      222     3         15
2017-2      333     1         4
2017-3      111     5         25
</code>```

Actual Output:

```<code>MONTH | UPC_ID
----------------------------------------------
2017-2      111     2
            222     3
            333     1
2017-3      111     5
...
</code>```

Questions:

How do I include the month for each row?

How do I include the rest of the columns of the dataframe?

How do also sum NET_AMT in addition to QTY_SOLD?

答:
I am thinking about this long time, thanks for your question push me to make it .By using agg and  if...else

```<code>df.groupby(['month', 'UPC_ID'],as_index=False).agg(lambda x : x.sum() if x.dtype=='int64' else x.head(1))
Out[1221]:
   month  UPC_ID UPC_DSC     D_DATE  QTY_SOLD  NET_AMT
0      2     111   desc1 2017-02-26         2       10
1      2     222   desc2 2017-02-26         3       15
2      2     333   desc3 2017-02-26         1        4
3      3     111   desc1 2017-03-01         5       25
</code>```

ContentLicense: CC BY-SA 4.0

Body:
I have the following data frame and want to:

Group records by month

Sum QTY_SOLDand NET_AMT of each unique UPC_ID(per month)

Include the rest of the columns as well in the resulting dataframe

The way I thought I can do this is 1st: create a month column to aggregate the D_DATES, then sum QTY_SOLD by UPC_ID.

Script:

# Convert date to date time object
df['D_DATE'] = pd.to_datetime(df['D_DATE'])

# Create aggregated months column
df['month'] = df['D_DATE'].apply(dt.date.strftime, args=('%Y.%m',))

# Group by month and sum up quantity sold by UPC_ID
df = df.groupby(['month', 'UPC_ID'])['QTY_SOLD'].sum()

Current data frame:

UPC_ID | UPC_DSC | D_DATE | QTY_SOLD | NET_AMT
----------------------------------------------
111      desc1    2/26/2017   2         10 (2 x $5)
222      desc2    2/26/2017   3         15
333      desc3    2/26/2017   1         4
111      desc1    3/1/2017    1         5
111      desc1    3/3/2017    4         20

Desired Output:

MONTH | UPC_ID | QTY_SOLD | NET_AMT | UPC_DSC
----------------------------------------------
2017-2      111     2         10       etc...
2017-2      222     3         15
2017-2      333     1         4
2017-3      111     5         25

Actual Output:

MONTH | UPC_ID
----------------------------------------------
2017-2      111     2
            222     3
            333     1
2017-3      111     5
...

Questions:

How do I include the month for each row?

How do I include the rest of the columns of the dataframe?

How do also sum NET_AMT in addition to QTY_SOLD?

Body:
I am thinking about this long time, thanks for your question push me to make it .By using agg and  if...else

df.groupby(['month', 'UPC_ID'],as_index=False).agg(lambda x : x.sum() if x.dtype=='int64' else x.head(1))
Out[1221]:
   month  UPC_ID UPC_DSC     D_DATE  QTY_SOLD  NET_AMT
0      2     111   desc1 2017-02-26         2       10
1      2     222   desc2 2017-02-26         3       15
2      2     333   desc3 2017-02-26         1        4
3      3     111   desc1 2017-03-01         5       25


问:
Threads in java - use sleep inside run
I want, after the print process, to stop the number of seconds registered, but when I run the play function, it does not reach sleep.
I can make the play function sleep, but I want to run thread.sleep() directly in the run function. Is it possible and how can I achieve this?

I have the following code:

```<code>public class Player implements Runnable {
    private String name;
    private String MusicalInstrument;
    Player(String name, String MusicalInstrument) {
        this.name = name;
        this.MusicalInstrument = MusicalInstrument;
    }
    public void run() {
        try {
            play();
            Thread.sleep(5000);
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
    }

    public void play() {
        while (true) {
            // print a message
            System.out.println(name + " is playing " + MusicalInstrument);
        }
    }
}
</code>```

答:
You are just continuously going to print because your while() runs indefinitely inside your play method and therefore you never return and reach the Thread.sleep method call inside your run() method. You should rework your methods to be more appropriate to what you are trying to do.</p>

```<code>public void run() {
    while(true)
    {
        try {
            play();
            Thread.sleep(5000);
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
    }
}

public void play() {
    System.out.println(name + " is playing " + MusicalInstrument);
}
</code>```

Title: Threads in java - use sleep inside run

Body:
I want, after the print process, to stop the number of seconds registered, but when I run the play function, it does not reach sleep.
I can make the play function sleep, but I want to run thread.sleep() directly in the run function. Is it possible and how can I achieve this?

I have the following code:

public class Player implements Runnable {
    private String name;
    private String MusicalInstrument;
    Player(String name, String MusicalInstrument) {
        this.name = name;
        this.MusicalInstrument = MusicalInstrument;
    }
    public void run() {
        try {
            play();
            Thread.sleep(5000);
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
    }

    public void play() {
        while (true) {
            // print a message
            System.out.println(name + " is playing " + MusicalInstrument);
        }
    }
}

Body:
You are just continuously going to print because your while() runs indefinitely inside your play method and therefore you never return and reach the Thread.sleep method call inside your run() method. You should rework your methods to be more appropriate to what you are trying to do.

public void run() {
    while(true)
    {
        try {
            play();
            Thread.sleep(5000);
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
    }
}

public void play() {
    System.out.println(name + " is playing " + MusicalInstrument);
}


问:
img src relative path in angular 4 returned undefined error
I am trying to display images on my site using this logic:
Upon component initialization, angular will get img links from a web server(google firebase).
The images are hosted in a image host server like imgur.
then the component will update and display the images.

but right now it returned an undefined error.
Detail code is shown below.

from home.component.ts

```<code>import { Component, OnInit, OnChanges } from '@angular/core';
import {HttpResponse, HttpEvent} from '@angular/common/http';
import {DbService} from '../db.service';
import {LEDProduct} from '../LED-product.model';
@Component({
  selector: 'app-home',
  templateUrl: './home.component.html',
  styleUrls: ['./home.component.css']
})
export class HomeComponent implements OnInit {

  sampleLEDLinks: LEDProduct[];

  constructor(private dbService: DbService) { }

  ngOnInit() {
    this.dbService.getHomePageImgs().subscribe(
      (returnedLinks: LEDProduct[]) => {
        this.sampleLEDLinks = returnedLinks;
      }
    );

  }

}
</code>```

from view template

```<code><div class="row" *ngFor="let link of sampleLEDLinks">
  <img  [src]="'//' + link.imgLink" alt="{{link.imgLink}}" width="100">
</div>
</code>```

LED product model template:

```<code>export class LEDProduct {
  public imgLink: string;

  constructor(imgLink: string) {
    this.imgLink = imgLink;
  }

}
</code>```

now, i also logged the returned url to make sure the links are indeed returned to the app.
and this is the console logged returned obj from chrome

```<code>(2) [{…}, {…}]
0
:
{link: "i.imgur.com/hy9aFEq.png"}
1
:
{link: "i.imgur.com/JRITacY.gif"}
length
:
2
__proto__
:
Array(0)
</code>```

but the view is still empty with an error as follow

is it because of the returned type not matched? I am really confused

答:
It turns out when angular is contacting server you will need to get it asynchronously. therefore I need to use Async Pipe in order to get data from server.

there are a few simple changes needed:

map the returned type to model
in the service:

getHomePageImgsType(): Observable {

```<code>return this.httpClient.get<LEDProduct[]>('.../linkList.json')
.map(
  links=> links
);
</code>```

add async pipe to the object[]
on view component:

```<code><div class="row" *ngFor="let link of sampleLEDLinks | async">
  <img  [src]="'//' + link.imgLink" alt="{{link.imgLink}}" width="100">
</div>
</code>```

Body:
I am trying to display images on my site using this logic:
Upon component initialization, angular will get img links from a web server(google firebase).
The images are hosted in a image host server like imgur.
then the component will update and display the images.

but right now it returned an undefined error.
Detail code is shown below.

from home.component.ts

import { Component, OnInit, OnChanges } from '@angular/core';
import {HttpResponse, HttpEvent} from '@angular/common/http';
import {DbService} from '../db.service';
import {LEDProduct} from '../LED-product.model';
@Component({
  selector: 'app-home',
  templateUrl: './home.component.html',
  styleUrls: ['./home.component.css']
})
export class HomeComponent implements OnInit {

  sampleLEDLinks: LEDProduct[];

  constructor(private dbService: DbService) { }

  ngOnInit() {
    this.dbService.getHomePageImgs().subscribe(
      (returnedLinks: LEDProduct[]) => {
        this.sampleLEDLinks = returnedLinks;
      }
    );

  }

}

from view template

LED product model template:

export class LEDProduct {
  public imgLink: string;

  constructor(imgLink: string) {
    this.imgLink = imgLink;
  }

}

now, i also logged the returned url to make sure the links are indeed returned to the app.
and this is the console logged returned obj from chrome

(2) [{…}, {…}]
0
:
{link: "i.imgur.com/hy9aFEq.png"}
1
:
{link: "i.imgur.com/JRITacY.gif"}
length
:
2
__proto__
:
Array(0)

but the view is still empty with an error as follow

is it because of the returned type not matched? I am really confused

Body:
It turns out when angular is contacting server you will need to get it asynchronously. therefore I need to use Async Pipe in order to get data from server.

there are a few simple changes needed:

map the returned type to model
in the service:

getHomePageImgsType(): Observable {

return this.httpClient.get<LEDProduct[]>('.../linkList.json')
.map(
  links=> links
);

add async pipe to the object[]
on view component:

<div class="row" *ngFor="let link of sampleLEDLinks | async">
  <img  [src]="'//' + link.imgLink" alt="{{link.imgLink}}" width="100">
</div>


问:
Do good multiplayer/mmo client<>server games use latency within movement calculations?
There's a couple of questions here.

Imagine I have client A who's going to send the following message to Server: "START MOVEMENT FORWARD".

The server will not receive this message instantly, as there is a delay because of latency.

Question 1: ping (or better: round trip time) is the amount of time it takes for the client to send a message to the server and receive a response back. Does this mean the following if you can ignore the time it takes for the server to notice that it has received a message and start sending a response (this should be very short)?

time it takes for client to send someting to server = round-trip-time / 2

time it takes for server to send something to client = round-trip-time / 2

So, when client A sends that message, the server will supposedly receive that message round-trip-time / 2 milliseconds after the client has send the message. This leads me to the next question.

Question 2: should the client first send the package, and then wait round-trip-time / 2 milliseconds before actually executing that command client-side (in this case: move forward) to compensate with the latency/lag?

Now, the server will send the following message to all nearby players: "CLIENT A IS NOW MOVING FORWARD". These clients will then make sure that the character of client a starts moving, this leads me to the next question.

Question 3: should the client receiving the message that an other client has moved take into account that this message was send by the server round-trip-time / 2 milliseconds ago? So that the current time used for movement calculations timestamps should be reduced by round-trip-time / 2?

All these methods would in my mind make sure that synchronisation improves between clients, as latency is taken into account. Is this the right way of doing things? Do most other good multiplayer games do this? Any comments, suggestions, alternatives or random but related shouts that you'd like to give? Thanks in advance.

答:
There are several network models to solve these problems;

In network game, you need to sync two things, one is time, other is space.

A network game model called lockstep;

you should have a look at the article written by age of empire2 game studio, which describe details in lockstep model.

In this Model, Client and server run game logic frame by frame, for example, RTS use 100ms as a frame,  Server and client will sync frame Id, which means to sync time.

Client at frame 50, Send Command MoveForward,  but not run it immediately, client will tell server to run move command at frame 51;
then when frame 51 comes,  server and client will run command at the same time.
so client and server logic will be same.

In such model, at frame 50, client and server will run command issued at frame 49 perhaps,  so there are alway 100ms or more delay in client  input feedback.

the lag between client and server not only contains network RTT, but also contains logic frame delay， which is 100ms;

in this model, to sync space, you need to make your client code and server code  Deterministic, so they can only sync command and frameId, there are no needs to sync  entity state.

in this model, input feedback is large, so you need to play animation or sound to help player ignore the lag.

other models use state sync

in this model, we also need to sync time, so client will guess what current time in server.

when player input, client move immediately, then send move command or client target pos to server with current server timestamp, which is estimated by client.

when server receive the client command, it know when the command is issued in server time by client,  it will try to run the command with extrapolation.

all other clients will receive the command, with its server time, the all other clients will try to extrapolate the command.

these technologies include  Client Prediction,  Server Lag compensation， Server Entity interpolation.

in this model, client input feedback is short, but for some impulse command, such as using skill, we still need to use lockstep method, with animation , sound and particle effects  to makeup the input feedback time.

In network game, there at least two kinds command,  first like movement, command will run for a certain time, like a steady stream, which has the attribute of Continuity.

the other like using skill with cold time, command effect will take in impulse, we should treat them differently.


问:
Newtonsoft deserialize multiple JSON files with cross references
I have two JSON files (that I can't change the format for) in the following format:

Main file -

```<code>[
   {
      "Name":"XYZ",
      "UnitReferenceId":1
   },
   {
      "Name":"ABC",
      "UnitReferenceId":2
   }
]
</code>```

The lookup/reference JSON file -

```<code>[
   {
      "UnitReferenceId":1,
      "Units":[
         {
            "Unit":"mg",
            "Scale":1
         },
         {
            "Unit":"gm",
            "Scale":1000
         },
         {
            "Unit":"kg",
            "Scale":1000000
         }
      ]
   },
   {
      "UnitReferenceId":2,
      "Units":[
         {
            "Unit":"mm",
            "Scale":1
         },
         {
            "Unit":"m",
            "Scale":1000
         },
         {
            "Unit":"km",
            "Scale":1000000
         }
      ]
   }
]
</code>```

How would I go about deserializing that into C# classes using Newtonsoft JSON into something like:

```<code>public class Widget
{
    public string Name {get; set;}
    public UnitReference UnitReference { get; set; }
}

public class UnitReference
{
    public long UnitReferenceId { get; set; }
    public List<Unit> Units { get; set; }
}
public class Unit
{
    [JsonProperty("Unit")]
    public string UnitValue { get; set; }
    public long Scale { get; set; }
}
</code>```

Any help would be greatly appreciated!

答:
You can do this by reading your two JSON files as follows:

First read the lookup/reference JSON file for UnitReference as a List<UnitReference>, then convert to a Dictionary<long, UnitReference> lookup table.

Next, read the main file using a custom JsonConverter for Widget that is passed the Dictionary<long, UnitReference> lookup table and can translate between UnitReferenceId and UnitReference during reading and writing.

Thus your classes would look like the following:

```<code>public class UnitReference
{
    readonly long unitReferenceId;

    public UnitReference(long unitReferenceId)
    {
        this.unitReferenceId = unitReferenceId;
    }

    public long UnitReferenceId { get { return unitReferenceId; } }

    public List<Unit> Units { get; set; }
}

public class Unit
{
    [JsonProperty("Unit")]
    public string UnitValue { get; set; }
    public long Scale { get; set; }
}

public class Widget
{
    public string Name { get; set; }

    public UnitReference UnitReference { get; set; }
}
</code>```

(My only modification was to make UnitReferenceId be read-only so that it safely could be used as a dictionary key.)

Then, define the following converter:

```<code>public class WidgetConverter : CustomPropertyConverterBase<Widget>
{
    readonly IDictionary<long, UnitReference> units;

    public WidgetConverter(IDictionary<long, UnitReference> units)
    {
        this.units = units;
    }

    protected override void ReadCustomProperties(JObject obj, Widget value, JsonSerializer serializer)
    {
        var id = (long?)obj.GetValue("UnitReferenceId", StringComparison.OrdinalIgnoreCase);
        if (id != null)
            value.UnitReference = units[id.Value];
    }

    protected override bool ShouldSerialize(JsonProperty property, object value)
    {
        if (property.UnderlyingName == nameof(Widget.UnitReference))
            return false;
        return base.ShouldSerialize(property, value);
    }

    protected override void WriteCustomProperties(JsonWriter writer, Widget value, JsonSerializer serializer)
    {
        if (value.UnitReference != null)
        {
            writer.WritePropertyName("UnitReferenceId");
            writer.WriteValue(value.UnitReference.UnitReferenceId);
        }
    }
}

public abstract class CustomPropertyConverterBase<T> : JsonConverter where T : class
{
    public override bool CanConvert(Type objectType)
    {
        return typeof(T).IsAssignableFrom(objectType);
    }

    public override object ReadJson(JsonReader reader, Type objectType, object existingValue, JsonSerializer serializer)
    {
        if (reader.TokenType == JsonToken.Null)
            return null;
        var jObj = JObject.Load(reader);
        var contract = (JsonObjectContract)serializer.ContractResolver.ResolveContract(objectType);
        var value = existingValue as T ?? (T)contract.DefaultCreator();

        ReadCustomProperties(jObj, value, serializer);

        // Populate the remaining properties.
        using (var subReader = jObj.CreateReader())
        {
            serializer.Populate(subReader, value);
        }

        return value;
    }

    protected abstract void ReadCustomProperties(JObject obj, T value, JsonSerializer serializer);

    public override void WriteJson(JsonWriter writer, object value, JsonSerializer serializer)
    {
        var contract = (JsonObjectContract)serializer.ContractResolver.ResolveContract(value.GetType());
        writer.WriteStartObject();
        foreach (var property in contract.Properties.Where(p => ShouldSerialize(p, value)))
        {
            var propertyValue = property.ValueProvider.GetValue(value);
            if (propertyValue == null && serializer.NullValueHandling == NullValueHandling.Ignore)
                continue;
            writer.WritePropertyName(property.PropertyName);
            serializer.Serialize(writer, propertyValue);
        }
        WriteCustomProperties(writer, (T)value, serializer);
        writer.WriteEndObject();
    }

    protected virtual bool ShouldSerialize(JsonProperty property, object value)
    {
        return property.Readable && !property.Ignored && (property.ShouldSerialize == null || property.ShouldSerialize(value));
    }

    protected abstract void WriteCustomProperties(JsonWriter writer, T value, JsonSerializer serializer);
}
</code>```

And deserialize as follows:

```<code>var units = JsonConvert.DeserializeObject<List<UnitReference>>(unitsJsonString)
    .ToDictionary(u => u.UnitReferenceId);

var settings = new JsonSerializerSettings
{
    Converters = { new WidgetConverter(units) },
};
var widgets = JsonConvert.DeserializeObject<List<Widget>>(widgetsJsonString, settings);
</code>```

Notes:

Here I am deserializing from JSON strings for demo purposes, but you can deserialize directly from your file(s) as shown in Deserialize JSON from a file.

The base class CustomPropertyConverterBase<T> for WidgetConverter automatically reads and writes all properties for the object being (de)serialized.  WidgetConverter then overrides this behavior for the UnitReference property only, avoiding the necessity to manually serialize all the remaining properties of Widget.

Sample fiddle.

Body:
I have two JSON files (that I can't change the format for) in the following format:

Main file -

[
   {
      "Name":"XYZ",
      "UnitReferenceId":1
   },
   {
      "Name":"ABC",
      "UnitReferenceId":2
   }
]

The lookup/reference JSON file -

[
   {
      "UnitReferenceId":1,
      "Units":[
         {
            "Unit":"mg",
            "Scale":1
         },
         {
            "Unit":"gm",
            "Scale":1000
         },
         {
            "Unit":"kg",
            "Scale":1000000
         }
      ]
   },
   {
      "UnitReferenceId":2,
      "Units":[
         {
            "Unit":"mm",
            "Scale":1
         },
         {
            "Unit":"m",
            "Scale":1000
         },
         {
            "Unit":"km",
            "Scale":1000000
         }
      ]
   }
]

How would I go about deserializing that into C# classes using Newtonsoft JSON into something like:

public class Widget
{
    public string Name {get; set;}
    public UnitReference UnitReference { get; set; }
}

public class UnitReference
{
    public long UnitReferenceId { get; set; }
    public List<Unit> Units { get; set; }
}
public class Unit
{
    [JsonProperty("Unit")]
    public string UnitValue { get; set; }
    public long Scale { get; set; }
}

Any help would be greatly appreciated!

Body:
You can do this by reading your two JSON files as follows:

First read the lookup/reference JSON file for UnitReference as a List<UnitReference>, then convert to a Dictionary<long, UnitReference> lookup table.

Next, read the main file using a custom JsonConverter for Widget that is passed the Dictionary<long, UnitReference> lookup table and can translate between UnitReferenceId and UnitReference during reading and writing.

Thus your classes would look like the following:

public class UnitReference
{
    readonly long unitReferenceId;

    public UnitReference(long unitReferenceId)
    {
        this.unitReferenceId = unitReferenceId;
    }

    public long UnitReferenceId { get { return unitReferenceId; } }

    public List<Unit> Units { get; set; }
}

public class Unit
{
    [JsonProperty("Unit")]
    public string UnitValue { get; set; }
    public long Scale { get; set; }
}

public class Widget
{
    public string Name { get; set; }

    public UnitReference UnitReference { get; set; }
}

(My only modification was to make UnitReferenceId be read-only so that it safely could be used as a dictionary key.)

Then, define the following converter:

public class WidgetConverter : CustomPropertyConverterBase<Widget>
{
    readonly IDictionary<long, UnitReference> units;

    public WidgetConverter(IDictionary<long, UnitReference> units)
    {
        this.units = units;
    }

    protected override void ReadCustomProperties(JObject obj, Widget value, JsonSerializer serializer)
    {
        var id = (long?)obj.GetValue("UnitReferenceId", StringComparison.OrdinalIgnoreCase);
        if (id != null)
            value.UnitReference = units[id.Value];
    }

    protected override bool ShouldSerialize(JsonProperty property, object value)
    {
        if (property.UnderlyingName == nameof(Widget.UnitReference))
            return false;
        return base.ShouldSerialize(property, value);
    }

    protected override void WriteCustomProperties(JsonWriter writer, Widget value, JsonSerializer serializer)
    {
        if (value.UnitReference != null)
        {
            writer.WritePropertyName("UnitReferenceId");
            writer.WriteValue(value.UnitReference.UnitReferenceId);
        }
    }
}

public abstract class CustomPropertyConverterBase<T> : JsonConverter where T : class
{
    public override bool CanConvert(Type objectType)
    {
        return typeof(T).IsAssignableFrom(objectType);
    }

    public override object ReadJson(JsonReader reader, Type objectType, object existingValue, JsonSerializer serializer)
    {
        if (reader.TokenType == JsonToken.Null)
            return null;
        var jObj = JObject.Load(reader);
        var contract = (JsonObjectContract)serializer.ContractResolver.ResolveContract(objectType);
        var value = existingValue as T ?? (T)contract.DefaultCreator();

        ReadCustomProperties(jObj, value, serializer);

        // Populate the remaining properties.
        using (var subReader = jObj.CreateReader())
        {
            serializer.Populate(subReader, value);
        }

        return value;
    }

    protected abstract void ReadCustomProperties(JObject obj, T value, JsonSerializer serializer);

    public override void WriteJson(JsonWriter writer, object value, JsonSerializer serializer)
    {
        var contract = (JsonObjectContract)serializer.ContractResolver.ResolveContract(value.GetType());
        writer.WriteStartObject();
        foreach (var property in contract.Properties.Where(p => ShouldSerialize(p, value)))
        {
            var propertyValue = property.ValueProvider.GetValue(value);
            if (propertyValue == null && serializer.NullValueHandling == NullValueHandling.Ignore)
                continue;
            writer.WritePropertyName(property.PropertyName);
            serializer.Serialize(writer, propertyValue);
        }
        WriteCustomProperties(writer, (T)value, serializer);
        writer.WriteEndObject();
    }

    protected virtual bool ShouldSerialize(JsonProperty property, object value)
    {
        return property.Readable && !property.Ignored && (property.ShouldSerialize == null || property.ShouldSerialize(value));
    }

    protected abstract void WriteCustomProperties(JsonWriter writer, T value, JsonSerializer serializer);
}

And deserialize as follows:

var units = JsonConvert.DeserializeObject<List<UnitReference>>(unitsJsonString)
    .ToDictionary(u => u.UnitReferenceId);

var settings = new JsonSerializerSettings
{
    Converters = { new WidgetConverter(units) },
};
var widgets = JsonConvert.DeserializeObject<List<Widget>>(widgetsJsonString, settings);

Notes:

Here I am deserializing from JSON strings for demo purposes, but you can deserialize directly from your file(s) as shown in Deserialize JSON from a file.

The base class CustomPropertyConverterBase<T> for WidgetConverter automatically reads and writes all properties for the object being (de)serialized.  WidgetConverter then overrides this behavior for the UnitReference property only, avoiding the necessity to manually serialize all the remaining properties of Widget.

Sample fiddle.


问:
Android calculator - plus button
I have a plus button on my calculator. The first statement is to add a "+" sign when there is no input (calculation string variable holds all input from user). The second statement is to prevent the user from typing 2 "+" signs in a row by adding "".

It keeps giving me an error: java.lang.StringIndexOutOfBoundsException: length=0; index=0.

```<code>btnMinus.setOnClickListener(new View.OnClickListener() {
    @Override

    public void onClick(View view) {
        calculation = tvCalculation.getText().toString();

        Character lastChar = calculation.charAt(calculation.length());

        //App negeert deze statements
        if(calculation.length() >= 0) {
                tvCalculation.setText(calculation + "-");
        } else if (lastChar.toString().equals("+")) {
                tvCalculation.setText(calculation + "");
        }
    }
});
</code>```

Someone told me it's because of the toString() at line 4.

答:
If you intend to read the last character of the 'calculation' string then you would need to do;

```<code>Character lastChar = calculation.charAt(calculation.length()-1);
</code>```

Note the -1 after calculation.Length().

Title: Android calculator - plus button

Body:
I have a plus button on my calculator. The first statement is to add a "+" sign when there is no input (calculation string variable holds all input from user). The second statement is to prevent the user from typing 2 "+" signs in a row by adding "".

It keeps giving me an error: java.lang.StringIndexOutOfBoundsException: length=0; index=0.

btnMinus.setOnClickListener(new View.OnClickListener() {
    @Override

    public void onClick(View view) {
        calculation = tvCalculation.getText().toString();

        Character lastChar = calculation.charAt(calculation.length());

        //App negeert deze statements
        if(calculation.length() >= 0) {
                tvCalculation.setText(calculation + "-");
        } else if (lastChar.toString().equals("+")) {
                tvCalculation.setText(calculation + "");
        }
    }
});

Someone told me it's because of the toString() at line 4.

Body:
If you intend to read the last character of the 'calculation' string then you would need to do;

Character lastChar = calculation.charAt(calculation.length()-1);

Note the -1 after calculation.Length().