问:
d3v4.js - d3.line not drawing the right values
I initially followed a simple line example to graph a line in d3.js (https://bl.ocks.org/d3noob/402dd382a51a4f6eea487f9a35566de0).

My real world requires to manipulate a bit the original data, and thus I added a nest() and a rollup() to sum the closes per day. I.e. on May 07, the graph line should show 400 instead of 100.

Based on the codes and tsv file below:

I get the correct information in the console, i.e 400 on May 07.

I'm unable to get that 400 number on the graph. Instead, I always get 100.

Based on my research, my feeling is the d3.line function is reading the "data" info instead of the nested/rolledup "groupByDate" information (not reading "values" but "closes"). When i try to change things, I get a message:
d3.v4.min.js:2 Error: <path> attribute d: Expected number, "MNaN,450LNaN,447L…"

I've searched through many answers in this site and changed my d3.line function to include the groupByDate information, but it seems, the wrong way. I just need that line to jump to 400 on day 07, as in the console.

```<code>    <!DOCTYPE html>
<svg width="960" height="500"></svg>
<script src="https://d3js.org/d3.v4.min.js"></script>
<script>

var svg = d3.select("svg"),
    margin = {top: 20, right: 20, bottom: 30, left: 50},
    width = +svg.attr("width") - margin.left - margin.right,
    height = +svg.attr("height") - margin.top - margin.bottom,
    g = svg.append("g").attr("transform", "translate(" + margin.left + "," + margin.top + ")");

var parseTime = d3.timeParse("%d-%b-%y");

var x = d3.scaleTime()
    .rangeRound([0, width]);

var y = d3.scaleLinear()
    .rangeRound([height, 0]);

var vline = d3.line()
    .x(function(d) { return x(d.date); })
    .y(function(d) { return y(+d.close); });

d3.tsv("data.tsv", function(d) {
  d.date = parseTime(d.date);
  d.close = +d.close;
  return d;
}, function(data) {
  var groupByDate = d3.nest()
    .key(function(d) { return d.date; })
    .rollup(function(d) { return d3.sum(d, function(g) { return +g.close; }); })
    .entries(data);

    groupByDate.forEach(function(d) {
         d.date = d.key;
         d.close = +d.close;
         d.close = d.value;
        });

    console.log(groupByDate);

  x.domain(d3.extent(data, function(d) { return d.date; }));
  y.domain(d3.extent(groupByDate, function(d) { return d.value; }));

  g.append("g")
      .attr("transform", "translate(0," + height + ")")
      .call(d3.axisBottom(x))
    .select(".domain")
      .remove();

  g.append("g")
      .call(d3.axisLeft(y))
    .append("text")
      .attr("fill", "#000")
      .attr("transform", "rotate(-90)")
      .attr("y", 6)
      .attr("dy", "0.71em")
      .attr("text-anchor", "end")
      .text("Price ($)");

  g.append("path")
      .datum(data)
      .attr("fill", "none")
      .attr("stroke", "steelblue")
      .attr("stroke-linejoin", "round")
      .attr("stroke-linecap", "round")
      .attr("stroke-width", 1.5)
      .attr("d", vline);
});

</script>
</code>```

data.tsv

```<code>date    close
24-Apr-07   93.24
25-Apr-07   95.35
26-Apr-07   98.84
27-Apr-07   99.92
30-Apr-07   99.80
1-May-07    99.47
2-May-07    100.39
3-May-07    100.40
4-May-07    100.81
7-May-07    100.00
7-May-07    100.00
7-May-07    100.00
7-May-07    100.00
8-May-07    105.06
9-May-07    106.88
10-May-07   107.34
11-May-07   108.74
14-May-07   109.36
15-May-07   107.52
16-May-07   107.34
</code>```

答:
You should be passing groupByData rather than data to your path. But the reason that this then doesn't work is that the nest.key has to be a string, so it's parsing your time back to a string which then won't work with your x scale. I'd suggest removing parseTime from the row conversion and instead adding it to your x scale domain and to the vline x function (although this means putting it in two places so perhaps there's a better way...).

Your x scale domain would become:

x.domain(d3.extent(data, function(d) { return parseTime(d.date); }));

And vline would become:

var vline = d3.line()
    .x(function(d) { return x(parseTime(d.date)); })...

Body:
I initially followed a simple line example to graph a line in d3.js (https://bl.ocks.org/d3noob/402dd382a51a4f6eea487f9a35566de0).

My real world requires to manipulate a bit the original data, and thus I added a nest() and a rollup() to sum the closes per day. I.e. on May 07, the graph line should show 400 instead of 100.

Based on the codes and tsv file below:

I get the correct information in the console, i.e 400 on May 07.

I'm unable to get that 400 number on the graph. Instead, I always get 100.

Based on my research, my feeling is the d3.line function is reading the "data" info instead of the nested/rolledup "groupByDate" information (not reading "values" but "closes"). When i try to change things, I get a message:
d3.v4.min.js:2 Error: <path> attribute d: Expected number, "MNaN,450LNaN,447L…"

I've searched through many answers in this site and changed my d3.line function to include the groupByDate information, but it seems, the wrong way. I just need that line to jump to 400 on day 07, as in the console.

    <!DOCTYPE html>
<svg width="960" height="500"></svg>

data.tsv

date    close
24-Apr-07   93.24
25-Apr-07   95.35
26-Apr-07   98.84
27-Apr-07   99.92
30-Apr-07   99.80
1-May-07    99.47
2-May-07    100.39
3-May-07    100.40
4-May-07    100.81
7-May-07    100.00
7-May-07    100.00
7-May-07    100.00
7-May-07    100.00
8-May-07    105.06
9-May-07    106.88
10-May-07   107.34
11-May-07   108.74
14-May-07   109.36
15-May-07   107.52
16-May-07   107.34


来源: stackexchange

问:
Can I use the API to post to any course in my domain?
I am able to create an announcement in my own courses using the API Guidance page found here.

I would like to be able to post to ANY course in my domain as a Super Admin.

Is this something I can do with a Google App Script project at all or am I wasting my time looking? Advice and pointers gratefully received.

答: On your super admin account, you could use 2 API methods. You could call courses.list (ref) which will return an array of all the courses. Loop through the returned array.  While looping through the array, create an individual announcement call for each course.

ContentLicense: CC BY-SA 3.0


问:
"hg commit -m 'My changes' " error
I follow this article to create a repository using Mercurial:

```<code>$ hg clone http://selenic.com/repo/hello
$ cd hello
$ hg add a.txt
$ hg commit -m 'My changes'
</code>```

but when i use hg commit -m 'My changes', it shows error :

```<code>abort: changes':
</code>```

What can I do about it?

答: Single-quoted strings need to be supported by your shell.  Double quotes should work.  For example, the Windows shell only supports double quotes.</p>

Title: "hg commit -m 'My changes' " error

Body:
I follow this article to create a repository using Mercurial:

$ hg clone http://selenic.com/repo/hello
$ cd hello
$ hg add a.txt
$ hg commit -m 'My changes'

but when i use hg commit -m 'My changes', it shows error :

abort: changes':

What can I do about it?

ContentLicense: CC BY-SA 2.5


问:
Should I rely on transitive dependencies in Maven if they come from other sub-module of my parent?
Suppose we are working on mortgage sub-module, and we are directly using the Google Guava classes in module code, but the dependcy for the guava is defined in other sub-module under the same parent and we have access to Guava classes only by transitive dependency on "investment" module:

```<code>banking-system (parent pom.xml)
|
|-- investment (pom.xml defines <dependency>guava</dependency>)
|
|-- mortgage (pom.xml defiens <dependency>investment</dependency>)
</code>```

Should we still put a <dependency> to Guava in the mortgage pom.xml?

The cons looks like duplication in our pom.xml, the pros are: if someone developing "investment" will drop guava, then it will not stop our mortgage sub-module from being successfuly build.

If yes, then what <version> shoudle we specify? (none + <dependencyManagement> in parent pom?)

If yes, should we use a <provided> scope in some module then?

Note: Keep in mind, that I am asking in specific situation, when modules have common parent pom (e.g. being an application as whole).

Maybe this structure was not the best example, imagine:

```<code>banking-app
    banking-core (dep.on: guava, commons, spring)
    investment (dep.on: banking-core)
    mortgage (dep.on: banking-core)
</code>```

Should still Investment explicitly declare Spring when it use @Component, and declare Guava if it uses Guava's LoadedCache?

答:
we are directly using the Google Guava classes in module code, but the
  dependcy for the guava is defined in other sub-module under the same
  parent and we have access to Guava classes only by transitive
  dependency on "investment" module [...] Should we still put a  to Guava in the mortgage pom.xml?

Yes, you should declare Google Guava dependency in your module and not expect it to be available as transitive-dependency. Even if it works with the current version, it may not be the case anymore in later versions of direct dependencies.

If your code depends on a module, your code should depends only directly on classes of this module, not a transitive-dependency of this module. As you mentioned, there is no guarantee that the investment module will continue to depend on Guava in the future. You need to specify this dependency either in the parent's pom.xml or in the module itself to ensure it will be available without relying on transitive dependencies. It's not duplication as such, how else can you tell Maven your module depends on Guava?

I do not see any situation in which minimal best practices are respected where you would need to do otherwise.

If yes, then what <version> shoudle we specify? (none + <dependencyManagement> in parent pom?)

Yes, using <dependencyManagement> in parent and using a <dependency> in your child module without version is best: you will make sure all your modules uses the same version of your dependency. As your modules are an application as a whole, it is probably better as it will avoid various issues such as having different versions of the same dependency being present on the classpath causing havoc.

Even if for some reason one of your module using the same parent requires a different version of our dependency, it will still be possible to override the version for this specific module using <version>.

If yes, should we use a  scope in some module then?

Probably not, having the dependency with a compile scope is the best wat to go with most packaging methods.

However you may have situations where you need or prefer to do this, for example if said modules requires to use a runtime environment specific version, or if your deployment or packaging model is designed in a way that demands it. Given the situation you expose, both are possible, though most of the time it should not be necessary.

Body:
Suppose we are working on mortgage sub-module, and we are directly using the Google Guava classes in module code, but the dependcy for the guava is defined in other sub-module under the same parent and we have access to Guava classes only by transitive dependency on "investment" module:

banking-system (parent pom.xml)
|
|-- investment (pom.xml defines <dependency>guava</dependency>)
|
|-- mortgage (pom.xml defiens <dependency>investment</dependency>)

Should we still put a <dependency> to Guava in the mortgage pom.xml?

The cons looks like duplication in our pom.xml, the pros are: if someone developing "investment" will drop guava, then it will not stop our mortgage sub-module from being successfuly build.

If yes, then what <version> shoudle we specify? (none + <dependencyManagement> in parent pom?)

If yes, should we use a <provided> scope in some module then?

Note: Keep in mind, that I am asking in specific situation, when modules have common parent pom (e.g. being an application as whole).

Maybe this structure was not the best example, imagine:

banking-app
    banking-core (dep.on: guava, commons, spring)
    investment (dep.on: banking-core)
    mortgage (dep.on: banking-core)

Should still Investment explicitly declare Spring when it use @Component, and declare Guava if it uses Guava's LoadedCache?


问:
Typeform data into a dictionary
I try to use import data from my typeform containing my own excercise data. The package typeform uses typeforms API to download the data. I want to put my responses in a dictionary so that I can use pandas to analyze the data.

The package documentation is short and it provides 6 rows of code on how to import the data. My first problem is that I get an error that I down't know how to handle

UnicodeEncodeError: 'ascii' codec can't encode character u'\xe5' in position 10: ordinal not in range(128)

My second problem is that I'm not sure how to do a for loop over .questions and .answers response in order to build a dictionary. The documentation loops and prints the answers out, but I want the in a dictionary. I think I can start with an empty dictionary and use the append method.

Here is my modification of the code on the package documentation page:

```<code>import typeform

# set my parameters and download the form data
apikey = '07466391d081290e87a95868893868e6e55c73c3'
formid = 'xqBhCO'
form = typeform.Form(api_key=apikey, form_id=formid)

# Fetch all responses to the form with default options
responses = form.get_responses()
responses # I have 16 questions and 138 responses

# Print '<question>: <answer>' for all responses to this form
for response in responses:
    for answer in response.answers:
        print '{question}: {answer}'.format(question=answer.question,
        answer=answer.answer)
</code>```

Running this code produces the output:

```<code>  ...
  Yoga: 1
  date: 2017-11-10
  Traceback (most recent call last):
    File "<stdin>", line 3, in <module>
  UnicodeEncodeError: 'ascii' codec can't encode character u'\xe5' in position 10:
ordinal not in range(128)
</code>```

Update

After reading typeforms API documentation I saw that I can use

```<code>https://api.typeform.com/v1/form/[typeform_UID]?key=[your_API_key]
</code>```

In order to see the data, so for my case that is https://api.typeform.com/v1/form/xqBhCO?key=07466391d081290e87a95868893868e6e55c73c3 Hence if there is another package, more known/stable than typeform e.g. beautifulsoup maybe I could use that one to go from my responses to a nice pandas dataframe?

答:
The typeform package doesn't seem to work as intended in Python 2 - so this is typeforms fault.

The typeform package - and your example code - works in Python 3 however.

(Unicode string handling changed a lot in Python 3)

```<code>import typeform

# set my parameters and download the form data
apikey = '07466391d081290e87a95868893868e6e55c73c3'
formid = 'xqBhCO'
form = typeform.Form(api_key=apikey, form_id=formid)

# Fetch all responses to the form with default options
responses = form.get_responses()
responses # I have 16 questions and 138 responses

# Print '<question>: <answer>' for all responses to this form
for response in responses:
    for answer in response.answers:
        print('{question}: {answer}'.format(question=answer.question,
        answer=answer.answer))
</code>```

Title: Typeform data into a dictionary

Body:
I try to use import data from my typeform containing my own excercise data. The package typeform uses typeforms API to download the data. I want to put my responses in a dictionary so that I can use pandas to analyze the data.

The package documentation is short and it provides 6 rows of code on how to import the data. My first problem is that I get an error that I down't know how to handle

UnicodeEncodeError: 'ascii' codec can't encode character u'\xe5' in position 10: ordinal not in range(128)

My second problem is that I'm not sure how to do a for loop over .questions and .answers response in order to build a dictionary. The documentation loops and prints the answers out, but I want the in a dictionary. I think I can start with an empty dictionary and use the append method.

Here is my modification of the code on the package documentation page:

import typeform

# set my parameters and download the form data
apikey = '07466391d081290e87a95868893868e6e55c73c3'
formid = 'xqBhCO'
form = typeform.Form(api_key=apikey, form_id=formid)

# Fetch all responses to the form with default options
responses = form.get_responses()
responses # I have 16 questions and 138 responses

# Print '<question>: <answer>' for all responses to this form
for response in responses:
    for answer in response.answers:
        print '{question}: {answer}'.format(question=answer.question,
        answer=answer.answer)

Running this code produces the output:

  ...
  Yoga: 1
  date: 2017-11-10
  Traceback (most recent call last):
    File "<stdin>", line 3, in <module>
  UnicodeEncodeError: 'ascii' codec can't encode character u'\xe5' in position 10:
ordinal not in range(128)

Update

After reading typeforms API documentation I saw that I can use

https://api.typeform.com/v1/form/[typeform_UID]?key=[your_API_key]

In order to see the data, so for my case that is https://api.typeform.com/v1/form/xqBhCO?key=07466391d081290e87a95868893868e6e55c73c3 Hence if there is another package, more known/stable than typeform e.g. beautifulsoup maybe I could use that one to go from my responses to a nice pandas dataframe?

Body:
The typeform package doesn't seem to work as intended in Python 2 - so this is typeforms fault.

The typeform package - and your example code - works in Python 3 however.

(Unicode string handling changed a lot in Python 3)

import typeform

# set my parameters and download the form data
apikey = '07466391d081290e87a95868893868e6e55c73c3'
formid = 'xqBhCO'
form = typeform.Form(api_key=apikey, form_id=formid)

# Fetch all responses to the form with default options
responses = form.get_responses()
responses # I have 16 questions and 138 responses

# Print '<question>: <answer>' for all responses to this form
for response in responses:
    for answer in response.answers:
        print('{question}: {answer}'.format(question=answer.question,
        answer=answer.answer))


问:
Hyperledger Composer BNA deployment results in timeout
I've successfully deployed a bna on the provided hlfv1 network by Composer. I now want to deploy it on my own network. I've followed the tutorial "Build your first network" for Hyperledger Fabric and added a CA. Now, when trying to deploy a BNA with composer, using composer network deploy -a maintenance-network.bna -p maintenance -i PeerAdmin -s randomString -A admin -S, i get an error:

```<code>Error: Error trying deploy. Error: Error trying to instantiate composer runtime. Error: Timeout expired while starting chaincode maintenance-network:0.14.2(networkid:dev,peerid:peer0.org1.example.com,tx:a2ee7c864d656d01315f128ba9c028d5059ef2f9e008f97d2c1ad11fbd6b1013)
Command failed
</code>```

Does anyone know what causes the error ?

This is the output of docker ps:

```<code>CONTAINER ID        IMAGE                        COMMAND                  CREATED             STATUS              PORTS                                              NAMES
b8cf89d35ba5        hyperledger/fabric-peer      "peer node start"        13 minutes ago      Up 13 minutes       0.0.0.0:10051->7051/tcp, 0.0.0.0:10053->7053/tcp   peer1.org2.example.com
492a09998560        hyperledger/fabric-orderer   "orderer"                13 minutes ago      Up 13 minutes       0.0.0.0:7050->7050/tcp                             orderer.example.com
d25c64b188d1        hyperledger/fabric-peer      "peer node start"        13 minutes ago      Up 13 minutes       0.0.0.0:8051->7051/tcp, 0.0.0.0:8053->7053/tcp     peer1.org1.example.com
2e64ba87132e        hyperledger/fabric-peer      "peer node start"        13 minutes ago      Up 13 minutes       0.0.0.0:7051->7051/tcp, 0.0.0.0:7053->7053/tcp     peer0.org1.example.com
55a23706aaf8        hyperledger/fabric-peer      "peer node start"        13 minutes ago      Up 13 minutes       0.0.0.0:9051->7051/tcp, 0.0.0.0:9053->7053/tcp     peer0.org2.example.com
f719beb58fb9        hyperledger/fabric-ca        "sh -c 'fabric-ca-..."   13 minutes ago      Up 13 minutes       0.0.0.0:7054->7054/tcp                             ca_peerOrg1
</code>```

This is my connection.json:

```<code>{
"type": "hlfv1",
"name": "maintenance",
"orderers": [
   { "url" : "grpc://localhost:7050" }
],
"ca": { "url": "http://localhost:7054",
        "name": "ca-org1"
},
"peers": [
        {
            "requestURL": "grpc://localhost:7051",
            "eventURL": "grpc://localhost:7053"
        },
        {
            "requestURL": "grpc://localhost:8051",
            "eventURL": "grpc://localhost:8053"
        }
],
"keyValStore": "/home/vagrant/.composer-credentials",
"channel": "mychannel",
"mspID": "Org1MSP",
"timeout": "1000"
}
</code>```

I'm using Ubuntu 16.04 and Composer v0.14.2.  Please tell me if you need any more information or files.

答: have you actually done a composer runtime install on the new peers you have added? Needs to be done on each peer.  This installs the Composer runtime code on the peers, in preparation for the business network you will plan to subsequently deploy using composer network start (where it tries to start the business network on the peers you configured in your connection profile). That said, I don't know how your connection profile has been set up (ie this being pre v0.15.0 version of Composer, where business network cards are used instead of -p <connectionprofilename> parameter in pre-0.15.0 versions)

Body:
I've successfully deployed a bna on the provided hlfv1 network by Composer. I now want to deploy it on my own network. I've followed the tutorial "Build your first network" for Hyperledger Fabric and added a CA. Now, when trying to deploy a BNA with composer, using composer network deploy -a maintenance-network.bna -p maintenance -i PeerAdmin -s randomString -A admin -S, i get an error:

Error: Error trying deploy. Error: Error trying to instantiate composer runtime. Error: Timeout expired while starting chaincode maintenance-network:0.14.2(networkid:dev,peerid:peer0.org1.example.com,tx:a2ee7c864d656d01315f128ba9c028d5059ef2f9e008f97d2c1ad11fbd6b1013)
Command failed

Does anyone know what causes the error ?

This is the output of docker ps:

CONTAINER ID        IMAGE                        COMMAND                  CREATED             STATUS              PORTS                                              NAMES
b8cf89d35ba5        hyperledger/fabric-peer      "peer node start"        13 minutes ago      Up 13 minutes       0.0.0.0:10051->7051/tcp, 0.0.0.0:10053->7053/tcp   peer1.org2.example.com
492a09998560        hyperledger/fabric-orderer   "orderer"                13 minutes ago      Up 13 minutes       0.0.0.0:7050->7050/tcp                             orderer.example.com
d25c64b188d1        hyperledger/fabric-peer      "peer node start"        13 minutes ago      Up 13 minutes       0.0.0.0:8051->7051/tcp, 0.0.0.0:8053->7053/tcp     peer1.org1.example.com
2e64ba87132e        hyperledger/fabric-peer      "peer node start"        13 minutes ago      Up 13 minutes       0.0.0.0:7051->7051/tcp, 0.0.0.0:7053->7053/tcp     peer0.org1.example.com
55a23706aaf8        hyperledger/fabric-peer      "peer node start"        13 minutes ago      Up 13 minutes       0.0.0.0:9051->7051/tcp, 0.0.0.0:9053->7053/tcp     peer0.org2.example.com
f719beb58fb9        hyperledger/fabric-ca        "sh -c 'fabric-ca-..."   13 minutes ago      Up 13 minutes       0.0.0.0:7054->7054/tcp                             ca_peerOrg1

This is my connection.json:

{
"type": "hlfv1",
"name": "maintenance",
"orderers": [
   { "url" : "grpc://localhost:7050" }
],
"ca": { "url": "http://localhost:7054",
        "name": "ca-org1"
},
"peers": [
        {
            "requestURL": "grpc://localhost:7051",
            "eventURL": "grpc://localhost:7053"
        },
        {
            "requestURL": "grpc://localhost:8051",
            "eventURL": "grpc://localhost:8053"
        }
],
"keyValStore": "/home/vagrant/.composer-credentials",
"channel": "mychannel",
"mspID": "Org1MSP",
"timeout": "1000"
}

I'm using Ubuntu 16.04 and Composer v0.14.2.  Please tell me if you need any more information or files.


问:
PostgreSQL: Column must appear in the GROUP BY clause or be used in an aggregate function
I’m having an issue with a PHP application using PostgreSQL. I have a simple SQL statement that looks like this:

```<code>select count(*) as aggregate from "categories" where "promoter_id" = ? order by "sort_order" asc
</code>```

But it triggers the following error:

SQLSTATE[42803]: Grouping error: 7 ERROR: column "categories.sort_order" must appear in the GROUP BY clause or be used in an aggregate function
  LINE 1: ...om "categories" where "promoter_id" = $1 order by "sort_orde...
  ^ (SQL: select count(*) as aggregate from "categories" where "promoter_id" = 7 order by "sort_order" asc)

The sort_order column contains arbitrary, unsigned integers that are used to “sort” records.

The above statement is issued by Eloquent (Laravel’s ORM) and seems to just be counting records in a table with a WHERE clause, so why is it triggering this error? I don’t really want to group the sort order column in case there are duplicate values (i.e. two records with a sort_order value of 2) but that seems to be the solution the error message is suggestion.

Is there an alternative solution? I’m quite new to PostgreSQL so this seems to be a peculiarity that I’ve not faced with MySQL up to now.

答:
If you can't remove the ORDER BY, can you instead add an extra literal field:</p>

```<code>SELECT count(*) AS aggregate, 0 AS sort_order
FROM "categories"
WHERE "promoter_id" = ?
ORDER BY "sort_order" asc;
</code>```

Body:
I’m having an issue with a PHP application using PostgreSQL. I have a simple SQL statement that looks like this:

select count(*) as aggregate from "categories" where "promoter_id" = ? order by "sort_order" asc

But it triggers the following error:

SQLSTATE[42803]: Grouping error: 7 ERROR: column "categories.sort_order" must appear in the GROUP BY clause or be used in an aggregate function
  LINE 1: ...om "categories" where "promoter_id" = $1 order by "sort_orde...
  ^ (SQL: select count(*) as aggregate from "categories" where "promoter_id" = 7 order by "sort_order" asc)

The sort_order column contains arbitrary, unsigned integers that are used to “sort” records.

The above statement is issued by Eloquent (Laravel’s ORM) and seems to just be counting records in a table with a WHERE clause, so why is it triggering this error? I don’t really want to group the sort order column in case there are duplicate values (i.e. two records with a sort_order value of 2) but that seems to be the solution the error message is suggestion.

Is there an alternative solution? I’m quite new to PostgreSQL so this seems to be a peculiarity that I’ve not faced with MySQL up to now.

Body:
If you can't remove the ORDER BY, can you instead add an extra literal field:

SELECT count(*) AS aggregate, 0 AS sort_order
FROM "categories"
WHERE "promoter_id" = ?
ORDER BY "sort_order" asc;


问:
How can I change the UIButton "glow" color used when "Shows Touch On Highlight" is enabled?
I have a UIButton with "Shows Touch On Highlight" enabled in the storyboard. It applies a "white" glow to the button when clicked.

However, I have a light grey button and would like to change the glow color so that it's more visible.

I've tried setting the background image for the highlighted control state to black, but it doesn't seem to make a different to the glow. I can change the background color of the button---that all works.

What controls the glow color, if anything? Or do I have to do it manually if I need a different color?

答:
Using a setBackgroundImage on the UIButton you can create a following extension that lets you to set a color for any state you want:

```<code>extension UIButton {
    func setBackgroundColor(color: UIColor, for state: UIControlState) {
        let image = UIImage.image(with: color)
        let insets = UIEdgeInsetsMake(0, 0, 0, 0)
        let stretchable = image.resizableImage(withCapInsets: insets, resizingMode: .tile)
        self.setBackgroundImage(stretchable, for: state)
    }
}
</code>```

Than you just need to set a background color for the .highlighted state:

```<code>button.setBackgroundColor(color: UIColor.red, for: .highlighted)
</code>```

I just hope you don't mind getting your hands dirty with code, I'm not really sure how to do the same from storyboards (I'm not even sure you can do it).

Body:
Using a setBackgroundImage on the UIButton you can create a following extension that lets you to set a color for any state you want:

extension UIButton {
    func setBackgroundColor(color: UIColor, for state: UIControlState) {
        let image = UIImage.image(with: color)
        let insets = UIEdgeInsetsMake(0, 0, 0, 0)
        let stretchable = image.resizableImage(withCapInsets: insets, resizingMode: .tile)
        self.setBackgroundImage(stretchable, for: state)
    }
}

Than you just need to set a background color for the .highlighted state:

button.setBackgroundColor(color: UIColor.red, for: .highlighted)

I just hope you don't mind getting your hands dirty with code, I'm not really sure how to do the same from storyboards (I'm not even sure you can do it).


问:
pass userData from callback-begin to callback-end
How to appropriately cache userData that is generated from user's callbackBegin() and send it to user's callbackEnd().

Simple version  (No userData - demo)

I want to create a complex database that support callback.  For MCVE, let's say it is MyArray.

Here is a simple array class that supports callback but no userData.

```<code>#include <iostream>
template<class Derived>class MyArray{           //library - I design it.
    public: void push_back(int s){
        static_cast<Derived*>(this)->callbackBegin(s);
        //do something about array
        static_cast<Derived*>(this)->callbackEnd(s);
    }
    //other fields / functions
};
class Callback : public MyArray<Callback>{      //user's class
    public: void callbackBegin(int s){
        std::cout<<"callbackBegin"<<std::endl;
    }
    public: void callbackEnd(int s){
        std::cout<<"callbackEnd"<<std::endl;
    }
};
int main() {
    Callback c;
    c.push_back(5); //print: callbackBegin callbackEnd
    return 0;
}
</code>```

It works correctly.

The next step : I want to pass some userData from Callback::callbackBegin() to Callback::callbackEnd().

For example, userData is a clock time when Callback::callbackBegin() is called.

My poor solution (void*& userdata : demo)

Here is my attempt to implement it :-

```<code>#include <iostream>
#include <time.h>
template<class Derived>class MyArray{
    public: void push_back(int s){
        void* userData=nullptr;                                 //#
        static_cast<Derived*>(this)->callbackBegin(s,userData); //# ugly
        //do something about array
        static_cast<Derived*>(this)->callbackEnd(s,userData);   //# ugly
    }
};
class Callback : public MyArray<Callback>{
    public: void callbackBegin(int s,void*& userData){          //#
        userData=new clock_t(clock());                          //# danger
        std::cout<<"callbackBegin"<<std::endl;
    }
    public: void callbackEnd(int s,void*& userData){            //#
        clock_t* userDataTyped=static_cast<clock_t*>(userData);
        clock_t clock2=clock();
        clock_t different=clock2 - (*userDataTyped);
        std::cout<<"callbackEnd time(second)="
                 <<((float)different)/CLOCKS_PER_SEC<<std::endl;
        delete userDataTyped;                                   //# danger
    }
};
int main() {
    Callback c;
    c.push_back(5); //print: callbackBegin callbackEnd time(second)=8.5e-05
    return 0;
}
</code>```

It also works correctly, but I believe it is a bad design (at various #) :-

new/delete in 2 places : potential memory leaking.

Strong pointer is preferred, but I don't know how to.

static_cast<clock_t*>(userData) is code-smell, at least for me.

(minor issue) an extra ugly parameter void*&

Question: What are design patterns / C++ magic to avoid such issues, while make MyArray concise, easy to use, maintainable (i.e. not much worse than the Simple version)?

Other notes:

In real cases, <5% of user's callback classes need userData.

Thus, I feel very reluctant to add void&* as an extra parameter.

Clarify: (edited) The minority cases usually need different types of userData e.g. Callback1 need clock_t,  Callback2 need std::string, etc.

Proposed solution should restrain from using std::function<> or virtual function, because the performance is a major concern here.

Thank.

答:
Pass data through a void pointer is a good C solution but (IMHO) not a C++ (specially: not a C++11/c++14/C++17, with auto and std::tuple) good one.

So I suggest to return a value from callbackBegin() and pass the value as first argument to `callbackEnd(); something like

```<code>  auto r = static_cast<Derived*>(this)->callbackBegin(s);

  static_cast<Derived*>(this)->callbackEnd(r, s);
</code>```

Observe (C++11 and newer magic) that using auto as type of the value returned by callbackBegin(), you can return different types from different `callbackBegin().

Bonus suggestion: be more generic in MyArray::push_back(): using variadic templates, there is no need of fix the number and the types of arguments received by callbackBack() and callbackEnd().

Using variadic templates you can modify push_back() as follows

```<code>template <typename ... Args>
void push_back (Args const & ... args)
 {
   auto r = static_cast<Derived*>(this)->callbackBegin(args...);

   static_cast<Derived*>(this)->callbackEnd(r, args...);
 }
</code>```

The following is a full working example with two different callback classes (with different number of arguments and different return types)

```<code>#include <tuple>
#include <iostream>

template <typename derT>
struct myA
 {
   template <typename ... Args>
   void push_back (Args const & ... args)
    {
      auto r = static_cast<derT*>(this)->callbackBegin(args...);

      static_cast<derT*>(this)->callbackEnd(r, args...);
    }
 };

struct cb1 : public myA<cb1>
 {
   int callbackBegin (int s)
    { std::cout << "cb1 b" << std::endl; return s+5; }

   void callbackEnd (int r, int s)
    { std::cout << "cb1 e -" << r << ", " << s << std::endl; }
 };

struct cb2 : public myA<cb2>
 {
   std::tuple<std::string, int> callbackBegin (std::string const & name,
                                               int num)
    { std::cout << "cb2 b" << std::endl; return {name+";", num+1}; }

   void callbackEnd (std::tuple<std::string, int> const &,
                     std::string const & name, int num)
    { std::cout << "cb2 e -" << name << ", " << num << std::endl; }
 };

int main ()
 {
   cb1 c1;
   c1.push_back(5);

   cb2 c2;
   c2.push_back("string arg", 7);

   return 0;
 }
</code>```

Body:
How to appropriately cache userData that is generated from user's callbackBegin() and send it to user's callbackEnd().

Simple version  (No userData - demo)

I want to create a complex database that support callback.  For MCVE, let's say it is MyArray.

Here is a simple array class that supports callback but no userData.

#include <iostream>
template<class Derived>class MyArray{           //library - I design it.
    public: void push_back(int s){
        static_cast<Derived*>(this)->callbackBegin(s);
        //do something about array
        static_cast<Derived*>(this)->callbackEnd(s);
    }
    //other fields / functions
};
class Callback : public MyArray<Callback>{      //user's class
    public: void callbackBegin(int s){
        std::cout<<"callbackBegin"<<std::endl;
    }
    public: void callbackEnd(int s){
        std::cout<<"callbackEnd"<<std::endl;
    }
};
int main() {
    Callback c;
    c.push_back(5); //print: callbackBegin callbackEnd
    return 0;
}

It works correctly.

The next step : I want to pass some userData from Callback::callbackBegin() to Callback::callbackEnd().

For example, userData is a clock time when Callback::callbackBegin() is called.

My poor solution (void*& userdata : demo)

Here is my attempt to implement it :-

#include <iostream>
#include <time.h>
template<class Derived>class MyArray{
    public: void push_back(int s){
        void* userData=nullptr;                                 //#
        static_cast<Derived*>(this)->callbackBegin(s,userData); //# ugly
        //do something about array
        static_cast<Derived*>(this)->callbackEnd(s,userData);   //# ugly
    }
};
class Callback : public MyArray<Callback>{
    public: void callbackBegin(int s,void*& userData){          //#
        userData=new clock_t(clock());                          //# danger
        std::cout<<"callbackBegin"<<std::endl;
    }
    public: void callbackEnd(int s,void*& userData){            //#
        clock_t* userDataTyped=static_cast<clock_t*>(userData);
        clock_t clock2=clock();
        clock_t different=clock2 - (*userDataTyped);
        std::cout<<"callbackEnd time(second)="
                 <<((float)different)/CLOCKS_PER_SEC<<std::endl;
        delete userDataTyped;                                   //# danger
    }
};
int main() {
    Callback c;
    c.push_back(5); //print: callbackBegin callbackEnd time(second)=8.5e-05
    return 0;
}

It also works correctly, but I believe it is a bad design (at various #) :-

new/delete in 2 places : potential memory leaking.

Strong pointer is preferred, but I don't know how to.

static_cast<clock_t*>(userData) is code-smell, at least for me.

(minor issue) an extra ugly parameter void*&

Question: What are design patterns / C++ magic to avoid such issues, while make MyArray concise, easy to use, maintainable (i.e. not much worse than the Simple version)?

Other notes:

In real cases, <5% of user's callback classes need userData.

Thus, I feel very reluctant to add void&* as an extra parameter.

Clarify: (edited) The minority cases usually need different types of userData e.g. Callback1 need clock_t,  Callback2 need std::string, etc.

Proposed solution should restrain from using std::function<> or virtual function, because the performance is a major concern here.

Thank.

Body:
Pass data through a void pointer is a good C solution but (IMHO) not a C++ (specially: not a C++11/c++14/C++17, with auto and std::tuple) good one.

So I suggest to return a value from callbackBegin() and pass the value as first argument to `callbackEnd(); something like

  auto r = static_cast<Derived*>(this)->callbackBegin(s);

  static_cast<Derived*>(this)->callbackEnd(r, s);

Observe (C++11 and newer magic) that using auto as type of the value returned by callbackBegin(), you can return different types from different `callbackBegin().

Bonus suggestion: be more generic in MyArray::push_back(): using variadic templates, there is no need of fix the number and the types of arguments received by callbackBack() and callbackEnd().

Using variadic templates you can modify push_back() as follows

template <typename ... Args>
void push_back (Args const & ... args)
 {
   auto r = static_cast<Derived*>(this)->callbackBegin(args...);

   static_cast<Derived*>(this)->callbackEnd(r, args...);
 }

The following is a full working example with two different callback classes (with different number of arguments and different return types)

#include <tuple>
#include <iostream>

template <typename derT>
struct myA
 {
   template <typename ... Args>
   void push_back (Args const & ... args)
    {
      auto r = static_cast<derT*>(this)->callbackBegin(args...);

      static_cast<derT*>(this)->callbackEnd(r, args...);
    }
 };

struct cb1 : public myA<cb1>
 {
   int callbackBegin (int s)
    { std::cout << "cb1 b" << std::endl; return s+5; }

   void callbackEnd (int r, int s)
    { std::cout << "cb1 e -" << r << ", " << s << std::endl; }
 };

struct cb2 : public myA<cb2>
 {
   std::tuple<std::string, int> callbackBegin (std::string const & name,
                                               int num)
    { std::cout << "cb2 b" << std::endl; return {name+";", num+1}; }

   void callbackEnd (std::tuple<std::string, int> const &,
                     std::string const & name, int num)
    { std::cout << "cb2 e -" << name << ", " << num << std::endl; }
 };

int main ()
 {
   cb1 c1;
   c1.push_back(5);

   cb2 c2;
   c2.push_back("string arg", 7);

   return 0;
 }


问:
SocketIO manual installation for iOS app swift 4 xcode 9
I am having difficulty installing SocketIO for my Swift 4/Xcode 9 app.  I have tried Swift Package Manager and Carthage and both did not work.  Separate threads for those issues.  I do not want to use Cocoapods.

Is there a way to manually install the libraries?  I can drag and drop the Source files successfully however I don't know how to add the SocketIO and Starscream frameworks from the Git downloaded files.  I can figure out how to link the binaries and that stuff myself, just want to know where I can physically extract the two frameworks from in the downloaded file.

答: Did you check in your project folder, the Carthage folder then Build folder then iOS folder and same with the Checkout folder?</p>


问:
Why my Javascript progress bar doesn't work in IE11?
I have a long running script that broke down in a progress bar:

HTML

```<code><div id="progressbar-wrapper">
    <div id="progressbar-outer" style="display: table;margin: 0 auto;background-color: #FFFFFF;border: 5px solid #000000;width: 50%;height: 30px;opacity: 1;z-index: 9998">
        <div id="progressbar" style="float:left;width: 0;height: 30px;background-color:#000000;border: 0;opacity: 1;z-index: 99999">
        </div>
    </div>
    <div id="loading-animation" style="position: fixed;top: 150px;left: 0;height: 120px;width: 100%;font-size: 100px;line-height: 120px;text-align: center;color: #000000;z-index: 9999;">
        ...SAVING...<br /><small>Saving Lines</small>
    </div>
</div>
</code>```

JavaScript

```<code>    var uiprogressbar = {};
    $(function () {

        uiprogressbar = {

            /** initial progress */
            progress: 0,

            /** maximum width of progressbar */
            progress_max: 0,

            /** The inner element of the progressbar (filled box). */
            $progress_bar: $('#progressbar'),

            /** Method to set the progressbar.
             */
            set: function (num) {
                if (this.progress_max && num) {
                    this.progress = num / this.progress_max * 100;
                    console.log('percent: ' + this.progress + '% - ' + num + '/' + this.progress_max);
                    this.$progress_bar.width(String(this.progress) + '%');
                }
            },

            fn_wrap: function (num) {
                setTimeout(function () {
                    this.set(num);
                }, 0);
            }

        };

    });

//PROGRESS BAR ================================================
//max progress bar
uiprogressbar.progress_max = iterations;

var mainGrid = $("#mainGrid").data("kendoGrid");

var i = 0; //partition #
var j = 0; //line #
var linesUpdated = 0; //update complete #

//make the progress bar visable before updating
$("#progressbar-wrapper").css("display", "block");

//then loop through update grid methods
(function innerloop() {

    try {
        //If end
        var testPart = (partitions[i].length - 1); //30 but starts at 0
    } catch (err) {
        //exit loop
        return;
    }

    //Get the length of the partition
    var thisPartitionLength = (partitions[i].length - 1); //30 but starts at 0

    if (thisPartitionLength >= j && successComplete === 2) {

        $.each(mainGrid.dataSource.data(),
            function () {

                if (this.RowSelected === true) {

                    //get id
                    var row = mainGrid.dataSource.getByUid(this.uid);

                    //unselect and turn off dirty
                    row.set("RowSelected", "false");
                    row.set("dirty", "false");
                    linesUpdated++;
                }
            });
        //update line #
        j++;
        //update progressbar
        uiprogressbar.set(linesUpdated);
    }

    if (j <= thisPartitionLength) {
        //loop if not complete with partition
        setTimeout(innerloop, 0);
    } else {
        if (j > thisPartitionLength) {
            //if end of partition reset the line # and increase partition # and continue loop
            i++;
            j = 0;
            setTimeout(innerloop, 0);
        }

        //on complete
        if (linesUpdated === iterations) {

            //Success message
            alert("Saved");
        }
    }
})();
</code>```

Which works perfectly in chrome. But doesn't appear AT ALL in IE11 (which is what my clients use). When i run it in IE it even gives and error

...not responding due to a long-running script.

which was the exact reason i implemented a progress bar. Is there something I'm missing that IE has that Chrome does not? How can i change this to make it work in IE?

答:
OK so IE waits till the function is complete to make changes. I has to strip out the progress bar method into a separate function and wrap it in a timeout:

```<code>function updateProgressBar(){
//PROGRESS BAR ================================================
//max progress bar
uiprogressbar.progress_max = iterations;

var mainGrid = $("#mainGrid").data("kendoGrid");

var i = 0; //partition #
var j = 0; //line #
var linesUpdated = 0; //update complete #

//make the progress bar visable before updating
$("#progressbar-wrapper").css("display", "block");

//then loop through update grid methods
(function innerloop() {

    try {
        //If end
        var testPart = (partitions[i].length - 1); //30 but starts at 0
    } catch (err) {
        //exit loop
        return;
    }

    //Get the length of the partition
    var thisPartitionLength = (partitions[i].length - 1); //30 but starts at 0

    if (thisPartitionLength >= j && successComplete === 2) {

        $.each(mainGrid.dataSource.data(),
            function () {

                if (this.RowSelected === true) {

                    //get id
                    var row = mainGrid.dataSource.getByUid(this.uid);

                    //unselect and turn off dirty
                    row.set("RowSelected", "false");
                    row.set("dirty", "false");
                    linesUpdated++;
                }
            });
        //update line #
        j++;
        //update progressbar
        uiprogressbar.set(linesUpdated);
    }

    if (j <= thisPartitionLength) {
        //loop if not complete with partition
        setTimeout(innerloop, 0);
    } else {
        if (j > thisPartitionLength) {
            //if end of partition reset the line # and increase partition # and continue loop
            i++;
            j = 0;
            setTimeout(innerloop, 0);
        }

        //on complete
        if (linesUpdated === iterations) {

            //Success message
            alert("Saved");
        }
    }
})();
}
</code>```

then call it using:

```<code>        setTimeout(function() {
                updateProgressBar();
            }, 0);
</code>```

Body:
I have a long running script that broke down in a progress bar:

HTML

        ...SAVING...
Saving Lines

JavaScript

    var uiprogressbar = {};
    $(function () {

        uiprogressbar = {

            /** initial progress */
            progress: 0,

            /** maximum width of progressbar */
            progress_max: 0,

            /** The inner element of the progressbar (filled box). */
            $progress_bar: $('#progressbar'),

            /** Method to set the progressbar.
             */
            set: function (num) {
                if (this.progress_max && num) {
                    this.progress = num / this.progress_max * 100;
                    console.log('percent: ' + this.progress + '% - ' + num + '/' + this.progress_max);
                    this.$progress_bar.width(String(this.progress) + '%');
                }
            },

            fn_wrap: function (num) {
                setTimeout(function () {
                    this.set(num);
                }, 0);
            }

        };

    });

//PROGRESS BAR ================================================
//max progress bar
uiprogressbar.progress_max = iterations;

var mainGrid = $("#mainGrid").data("kendoGrid");

var i = 0; //partition #
var j = 0; //line #
var linesUpdated = 0; //update complete #

//make the progress bar visable before updating
$("#progressbar-wrapper").css("display", "block");

//then loop through update grid methods
(function innerloop() {

    try {
        //If end
        var testPart = (partitions[i].length - 1); //30 but starts at 0
    } catch (err) {
        //exit loop
        return;
    }

    //Get the length of the partition
    var thisPartitionLength = (partitions[i].length - 1); //30 but starts at 0

    if (thisPartitionLength >= j && successComplete === 2) {

        $.each(mainGrid.dataSource.data(),
            function () {

                if (this.RowSelected === true) {

                    //get id
                    var row = mainGrid.dataSource.getByUid(this.uid);

                    //unselect and turn off dirty
                    row.set("RowSelected", "false");
                    row.set("dirty", "false");
                    linesUpdated++;
                }
            });
        //update line #
        j++;
        //update progressbar
        uiprogressbar.set(linesUpdated);
    }

    if (j <= thisPartitionLength) {
        //loop if not complete with partition
        setTimeout(innerloop, 0);
    } else {
        if (j > thisPartitionLength) {
            //if end of partition reset the line # and increase partition # and continue loop
            i++;
            j = 0;
            setTimeout(innerloop, 0);
        }

        //on complete
        if (linesUpdated === iterations) {

            //Success message
            alert("Saved");
        }
    }
})();

Which works perfectly in chrome. But doesn't appear AT ALL in IE11 (which is what my clients use). When i run it in IE it even gives and error

...not responding due to a long-running script.

which was the exact reason i implemented a progress bar. Is there something I'm missing that IE has that Chrome does not? How can i change this to make it work in IE?

Body:
OK so IE waits till the function is complete to make changes. I has to strip out the progress bar method into a separate function and wrap it in a timeout:

function updateProgressBar(){
//PROGRESS BAR ================================================
//max progress bar
uiprogressbar.progress_max = iterations;

var mainGrid = $("#mainGrid").data("kendoGrid");

var i = 0; //partition #
var j = 0; //line #
var linesUpdated = 0; //update complete #

//make the progress bar visable before updating
$("#progressbar-wrapper").css("display", "block");

//then loop through update grid methods
(function innerloop() {

    try {
        //If end
        var testPart = (partitions[i].length - 1); //30 but starts at 0
    } catch (err) {
        //exit loop
        return;
    }

    //Get the length of the partition
    var thisPartitionLength = (partitions[i].length - 1); //30 but starts at 0

    if (thisPartitionLength >= j && successComplete === 2) {

        $.each(mainGrid.dataSource.data(),
            function () {

                if (this.RowSelected === true) {

                    //get id
                    var row = mainGrid.dataSource.getByUid(this.uid);

                    //unselect and turn off dirty
                    row.set("RowSelected", "false");
                    row.set("dirty", "false");
                    linesUpdated++;
                }
            });
        //update line #
        j++;
        //update progressbar
        uiprogressbar.set(linesUpdated);
    }

    if (j <= thisPartitionLength) {
        //loop if not complete with partition
        setTimeout(innerloop, 0);
    } else {
        if (j > thisPartitionLength) {
            //if end of partition reset the line # and increase partition # and continue loop
            i++;
            j = 0;
            setTimeout(innerloop, 0);
        }

        //on complete
        if (linesUpdated === iterations) {

            //Success message
            alert("Saved");
        }
    }
})();
}

then call it using:

        setTimeout(function() {
                updateProgressBar();
            }, 0);


问:
SSRS PMT Function producing #ERROR
I am hoping someone can help me here. I am using the PMT function to calculate mortgage payments in SSRS. I am using the following Formula

```<code>=IIF(Note = "Present",-PMT(Rate/12,Term,Balance,0,DueDate.EndOfPeriod),Nothing))
</code>```

The formula works perfectly when Note = Present.  However on all other loans it is producing #ERROR. I don't understand why this is happening.

Is there some other error handling that needs to be done to simply leave the cell blank if the note is not present?

答:
I'm not familiar with PMT but it could be that the values passed to PMT are invalid for loans where Note is not "Present". If this is the case then I would use a SWITCH statement instead. SWITCH will stop at the first expression that evaluates to True, whereas IIF evaluates all expressions, even the expression that does not get used!

try this..

```<code>=SWITCH(
        Note <> "Present", Nothing,
        True, -PMT(Rate/12,Term,Balance,0,DueDate.EndOfPeriod)
        )
</code>```

This way, if note is not "Present" then return nothing and only if it IS "Present" evaluate the PMT function and return its value. The True just acts like an else to save us writing Note = "Present" for the second condition

Title: SSRS PMT Function producing #ERROR

Body:
I am hoping someone can help me here. I am using the PMT function to calculate mortgage payments in SSRS. I am using the following Formula

=IIF(Note = "Present",-PMT(Rate/12,Term,Balance,0,DueDate.EndOfPeriod),Nothing))

The formula works perfectly when Note = Present.  However on all other loans it is producing #ERROR. I don't understand why this is happening.

Is there some other error handling that needs to be done to simply leave the cell blank if the note is not present?

Body:
I'm not familiar with PMT but it could be that the values passed to PMT are invalid for loans where Note is not "Present". If this is the case then I would use a SWITCH statement instead. SWITCH will stop at the first expression that evaluates to True, whereas IIF evaluates all expressions, even the expression that does not get used!

try this..

=SWITCH(
        Note <> "Present", Nothing,
        True, -PMT(Rate/12,Term,Balance,0,DueDate.EndOfPeriod)
        )

This way, if note is not "Present" then return nothing and only if it IS "Present" evaluate the PMT function and return its value. The True just acts like an else to save us writing Note = "Present" for the second condition


答:
SSRS will always evaluate both sides of a conditional expression, no matter what the result of the first parameter boolean test.  This means that

-PMT(Rate/12,Term,Balance,0,DueDate.EndOfPeriod)

must be a valid calculation for rows where Note <> "Present" as well or you will get an expressions error.  I would suggest that probably some of the other fields aren't populated with appropriate "dummy" values in this scenario.

Title: SSRS PMT Function producing #ERROR


问:
Check if a given key already exists in a dictionary and increment it
How do I find out if a key in a dictionary has already been set to a non-None value?

I want to increment the value if there's already one there, or set it to 1 otherwise:

```<code>my_dict = {}

if my_dict[key] is not None:
  my_dict[key] = 1
else:
  my_dict[key] += 1
</code>```

答:
I prefer to do this in one line of code.

```
my_dict = {}

my_dict[some_key] = my_dict.get(some_key, 0) + 1
```

Dictionaries have a function, get, which takes two parameters - the key you want, and a default value if it doesn't exist. I prefer this method to defaultdict as you only want to handle the case where the key doesn't exist in this one line of code, not everywhere.

OwnerDisplayName: Ben

ContentLicense: CC BY-SA 4.0

Body:
How do I find out if a key in a dictionary has already been set to a non-None value?

I want to increment the value if there's already one there, or set it to 1 otherwise:

my_dict = {}

if my_dict[key] is not None:
  my_dict[key] = 1
else:
  my_dict[key] += 1

Body:
I prefer to do this in one line of code.

my_dict = {}

my_dict[some_key] = my_dict.get(some_key, 0) + 1

Dictionaries have a function, get, which takes two parameters - the key you want, and a default value if it doesn't exist. I prefer this method to defaultdict as you only want to handle the case where the key doesn't exist in this one line of code, not everywhere.

OwnerDisplayName: Andrew Wilkinson


问:
Selenium webdriver , Ruby, read children
I would like to read all the link children of this div:

```<code><div class="col-xs-12 check-box-container">
    <a href="/applicant_submissions/5/background_checks/safis">
        <div id="safis" class="col-xs-2 check-box">
            <div class="check-styling pending">
                P
            </div>
        </div>
    </a>
    <a href="/applicant_submissions/5/background_checks/sori">
        <div id="sori" class="col-xs-2 check-box">
            <div class="check-styling passed">
                <i class="glyphicon glyphicon-ok"></i>
            </div>
        </div>
    </a>
    <a href="/applicant_submissions/5/background_checks/nsor">
        <div id="nsor" class="col-xs-2 check-box">
            <div class="check-styling pending-results">
                P
            </div>
        </div>
    </a>
</div>
</code>```

I would like to print out:

safis : P
sori :  ok
nsor : P

This is what I started  doing to see if I have an array that has 3 items, but it always return 0.

```<code>checkResults = driver.find_element(:class,'check-box-container').find_elements(:tag_name =>"a")
puts checkResults.size
</code>```

答:
To get the id and Text Values and print like safis : P sori : ok nsor : P, you can use the following equivalent code block (written in Java) :

```<code>List<WebElement> keyElements = driver.findElements(By.xpath("//div[@class='col-xs-12 check-box-container']/a/div"));
List<String> keys = new ArrayList<String>();
for(WebElement key:keyElements)
    keys.add(key.getAttribute("id"));

List<WebElement> valueElements = driver.findElements(By.xpath("//div[@class='col-xs-12 check-box-container']/a/div/div"));
List<String> values = new ArrayList<String>();
for(WebElement value:valueElements)
    values.add(value.getAttribute("innerHTML"));

for(int i=0; i<keys.size();i++)
    System.out.println(keys.get(i) + " : " + values.get(i));
</code>```

Body:
I would like to read all the link children of this div:

                P

                P

I would like to print out:

safis : P
sori :  ok
nsor : P

This is what I started  doing to see if I have an array that has 3 items, but it always return 0.

checkResults = driver.find_element(:class,'check-box-container').find_elements(:tag_name =>"a")
puts checkResults.size

Body:
To get the id and Text Values and print like safis : P sori : ok nsor : P, you can use the following equivalent code block (written in Java) :

List<WebElement> keyElements = driver.findElements(By.xpath("//div[@class='col-xs-12 check-box-container']/a/div"));
List<String> keys = new ArrayList<String>();
for(WebElement key:keyElements)
    keys.add(key.getAttribute("id"));

List<WebElement> valueElements = driver.findElements(By.xpath("//div[@class='col-xs-12 check-box-container']/a/div/div"));
List<String> values = new ArrayList<String>();
for(WebElement value:valueElements)
    values.add(value.getAttribute("innerHTML"));

for(int i=0; i<keys.size();i++)
    System.out.println(keys.get(i) + " : " + values.get(i));


问:
Non-contiguous array as filter criteria for xlfiltervalues
Common problem, I have worked through all answers I've found and finally got it almost working.

I have a list of discount options, let's call them named range F, down 1 column.
User filters out the discounts they don't want to apply.
I need to unfilter, do work, and refilter as the user selected.

I create an array with only visible cells, by loop and union of ranges. This works correctly, but generates a non-contiguous array usually.

When I run this, I don't get an error. However, the entry below the break in the contiguous array is not refiltered.

Just realised it's the transpose that doesn't like non-contiguous arrays - still need assistance and doubtless others have same issue so leaving as is

What's the easiest, most painless (it's nearly Friday), way to persuade Criteria1 to include the last elements in my non-contiguous array?

```<code>Sub Filters()

'Dimension variables
Dim Rng As Range
Dim i, Lim As Integer
Dim w As Worksheet
Dim Op As Variant

Set w = ActiveSheet

'Set Lim as total number of rows in named range "F" (only 1 cell in use but same effect)
Lim = Range("F").Rows.Count

'Data has header row so skip to row 2
i = 2

'Loop through i up to limit
Do While i <= Lim
    'If the row is not hidden by the filters the user chose

    If Range("F")(i, 1).EntireRow.Hidden = False Then
        'Check if the range is nothing - if it is, union will not work to itself
        'Union requires non-empty arguments

        If Rng Is Nothing Then
            'Set the Rng to include the current cell from "F"
            Set Rng = Range("F")(i, 1)

        Else
            'If Rng has some value, add the current cell to it by Union
            Set Rng = Application.Union(Rng, Range("F")(i, 1))

        End If

    End If

    'Increment i
    i = i + 1

    Loop

    If w.AutoFilter.Filters.Item(1).Operator <> False Then Op = w.AutoFilter.Filters.Item(1).Operator

    'This gives the correct range, but most often non-contiguous
    MsgBox Range("F").Address

    'Remove AutoFilter
    w.AutoFilterMode = False

    'Insert Code Here

    'Put filters back

    'Check for Rng being non-empty (pointless running code if it is)
    If Not IsEmpty(Rng) Then
        'If there is an operator then use the array
        If Op Then
            'Found this option useful here - can transpose the array values which generates an array Criteria1 can use
            'Always xlFilterValues as there will always be more than 2 options
            'Also the options are taken from the worksheet live so won't change between times so specifying them precisely as strings is ok
            Range("F").AutoFilter Field:=1, Criteria1:=Application.Transpose(Rng.Value), _
            Operator:=xlFilterValues
        Else
            'Just filter the range but leave all options available
            Range("F").AutoFilter Field:=1
        End If
    End If

End Sub
</code>```

答:
Answered by using a second counter to count successful entries that should be included as criteria, and writing them to a range in another worksheet.
Then set the range to be that new (contiguous) range in the new worksheet.

Now works like a charm at last. Only took me all day to find syntax that worked with Criteria, and figure that you can only use xlOr for up to 2 criteria, otherwise it's xlfiltervalues...

Final working code as generic as I can get it to be as helpful as possible:

```<code>Sub Filters()

'Dimension variables
Dim Rng As Range
Dim i, j, Lim As Integer
Dim w As Worksheet
Dim Op As Variant

Set w = ActiveSheet

'Set Lim as total number of rows in named range "F" (only 1 cell in use but same effect)
Lim = Range("F").Rows.Count

'Data has header row so skip to row 2
i = 2

'Loop through i up to limit
Do While i <= Lim
    'If the row is not hidden by the filters the user chose

    If Range("F")(i, 1).EntireRow.Hidden = False Then
        'Check if the range is nothing - if it is, union will not work to itself
        'Union requires non-empty arguments

        If Rng Is Nothing Then
            'Set the Rng to include the current cell from "F"
            Set Rng = Range("F")(i, 1)
            Sheets("Sheet2").Range("A75").Value = Range("F")(i, 1).Value
            j = j + 1
        Else
            Sheets("Sheet2").Range("A1").Offset(j, 0).Value = Range("F")(i, 1).Value
            j = j + 1
        End If

    End If

'Increment i
i = i + 1

Loop

'If there's an operator, save it as variable Op (if needed)
If w.AutoFilter.Filters.Item(1).Operator <> False Then Op = w.AutoFilter.Filters.Item(1).Operator

'Remove AutoFilter
w.AutoFilterMode = False

'Insert Code Here

'Pause between the two halves
MsgBox ""

'Put filters back

'Check for Rng being non-empty (pointless running code if it is)
If Not IsEmpty(Rng) Then
    'If there is an operator then use the range
    If Op Then
        'Found this option useful here - can transpose the array values
        'Always xlFilterValues as there will always be more than 2 options
        'Also the options are taken from the worksheet live so won't change between times so specifying them precisely as strings is ok
        Range("F").AutoFilter Field:=1, Criteria1:=Application.Transpose(Sheets("Sheet2").Range("A75").Resize(j, 1).Value), _
        Operator:=xlFilterValues
    Else
        'Just filter the range but leave all options available
        Range("F").AutoFilter Field:=1
    End If
End If

End Sub
</code>```

Body:
Common problem, I have worked through all answers I've found and finally got it almost working.

I have a list of discount options, let's call them named range F, down 1 column.
User filters out the discounts they don't want to apply.
I need to unfilter, do work, and refilter as the user selected.

I create an array with only visible cells, by loop and union of ranges. This works correctly, but generates a non-contiguous array usually.

When I run this, I don't get an error. However, the entry below the break in the contiguous array is not refiltered.

Just realised it's the transpose that doesn't like non-contiguous arrays - still need assistance and doubtless others have same issue so leaving as is

What's the easiest, most painless (it's nearly Friday), way to persuade Criteria1 to include the last elements in my non-contiguous array?

Sub Filters()

'Dimension variables
Dim Rng As Range
Dim i, Lim As Integer
Dim w As Worksheet
Dim Op As Variant

Set w = ActiveSheet

'Set Lim as total number of rows in named range "F" (only 1 cell in use but same effect)
Lim = Range("F").Rows.Count

'Data has header row so skip to row 2
i = 2

'Loop through i up to limit
Do While i <= Lim
    'If the row is not hidden by the filters the user chose

    If Range("F")(i, 1).EntireRow.Hidden = False Then
        'Check if the range is nothing - if it is, union will not work to itself
        'Union requires non-empty arguments

        If Rng Is Nothing Then
            'Set the Rng to include the current cell from "F"
            Set Rng = Range("F")(i, 1)

        Else
            'If Rng has some value, add the current cell to it by Union
            Set Rng = Application.Union(Rng, Range("F")(i, 1))

        End If

    End If

    'Increment i
    i = i + 1

    Loop

    If w.AutoFilter.Filters.Item(1).Operator <> False Then Op = w.AutoFilter.Filters.Item(1).Operator

    'This gives the correct range, but most often non-contiguous
    MsgBox Range("F").Address

    'Remove AutoFilter
    w.AutoFilterMode = False

    'Insert Code Here

    'Put filters back

    'Check for Rng being non-empty (pointless running code if it is)
    If Not IsEmpty(Rng) Then
        'If there is an operator then use the array
        If Op Then
            'Found this option useful here - can transpose the array values which generates an array Criteria1 can use
            'Always xlFilterValues as there will always be more than 2 options
            'Also the options are taken from the worksheet live so won't change between times so specifying them precisely as strings is ok
            Range("F").AutoFilter Field:=1, Criteria1:=Application.Transpose(Rng.Value), _
            Operator:=xlFilterValues
        Else
            'Just filter the range but leave all options available
            Range("F").AutoFilter Field:=1
        End If
    End If

End Sub

Body:
Answered by using a second counter to count successful entries that should be included as criteria, and writing them to a range in another worksheet.
Then set the range to be that new (contiguous) range in the new worksheet.

Now works like a charm at last. Only took me all day to find syntax that worked with Criteria, and figure that you can only use xlOr for up to 2 criteria, otherwise it's xlfiltervalues...

Final working code as generic as I can get it to be as helpful as possible:

Sub Filters()

'Dimension variables
Dim Rng As Range
Dim i, j, Lim As Integer
Dim w As Worksheet
Dim Op As Variant

Set w = ActiveSheet

'Set Lim as total number of rows in named range "F" (only 1 cell in use but same effect)
Lim = Range("F").Rows.Count

'Data has header row so skip to row 2
i = 2

'Loop through i up to limit
Do While i <= Lim
    'If the row is not hidden by the filters the user chose

    If Range("F")(i, 1).EntireRow.Hidden = False Then
        'Check if the range is nothing - if it is, union will not work to itself
        'Union requires non-empty arguments

        If Rng Is Nothing Then
            'Set the Rng to include the current cell from "F"
            Set Rng = Range("F")(i, 1)
            Sheets("Sheet2").Range("A75").Value = Range("F")(i, 1).Value
            j = j + 1
        Else
            Sheets("Sheet2").Range("A1").Offset(j, 0).Value = Range("F")(i, 1).Value
            j = j + 1
        End If

    End If

'Increment i
i = i + 1

Loop

'If there's an operator, save it as variable Op (if needed)
If w.AutoFilter.Filters.Item(1).Operator <> False Then Op = w.AutoFilter.Filters.Item(1).Operator

'Remove AutoFilter
w.AutoFilterMode = False

'Insert Code Here

'Pause between the two halves
MsgBox ""

'Put filters back

'Check for Rng being non-empty (pointless running code if it is)
If Not IsEmpty(Rng) Then
    'If there is an operator then use the range
    If Op Then
        'Found this option useful here - can transpose the array values
        'Always xlFilterValues as there will always be more than 2 options
        'Also the options are taken from the worksheet live so won't change between times so specifying them precisely as strings is ok
        Range("F").AutoFilter Field:=1, Criteria1:=Application.Transpose(Sheets("Sheet2").Range("A75").Resize(j, 1).Value), _
        Operator:=xlFilterValues
    Else
        'Just filter the range but leave all options available
        Range("F").AutoFilter Field:=1
    End If
End If

End Sub


问:
How to combine values of objects with common key in JavaScript?
I'm trying to merge some items in a JSON array, based on one of the keys. I want to group by the 'metric', and then I need to look at all the time/value data in 'rounded_counts', and if the times are the same, the values need to be added together. Here is the source data:

```<code>let sourceData = [
  {
    "metric": "Approved",
    "rounded_counts": [
      { "2017-11-16 15:10:00": 3 },
      { "2017-11-16 15:11:00": 5 }
    ]
  },
  {
    "metric": "Approved",
    "rounded_counts": [
      { "2017-11-16 15:10:00": 28 },
      { "2017-11-16 15:11:00": 28 }
    ]
  },
  {
    "metric": "Quarantine",
    "rounded_counts": [
      { "2017-11-16 15:10:00": 1 },
      { "2017-11-16 15:11:00": 2 }
    ]
  }
];
</code>```

and here is the desired output required for the Highcharts graphing library - notice how the 2 metrics called 'Approved' have had their values merged

Underscore, and/or ES6 can be used - Thanks in advance!

```<code>let chartData = [
  {
    "name": "Approved",
    "data": [
      [ "2017-11-16 15:10:00", 30 ],
      [ "2017-11-16 15:11:00", 33 ]
    ]
  },
  {
    "name": "Quarantine",
    "data": [
      [ "2017-11-16 15:10:00", 1 ],
      [ "2017-11-16 15:11:00", 2 ]
    ]
  }
]
</code>```

答:
Look at something like this :

```<code>[{
      "metric": "Approved",
        "rounded_counts": [
          { "2017-11-16 15:10:00": 3 },
          { "2017-11-16 15:11:00": 5 }
        ]
    },
    ...
].reduce((tmp, x) => {
  const ptr = tmp;

  // look if it exist
  const index = ptr.findIndex(y => y.name === x.metric);

  // It exist
  if (index !== -1) {
    ptr[index].data = addSimilarDatesValues([
      ...ptr[index].data,
      ...x.rounded_counts,
    ]);

    return ptr;
  }

  // it doesn't
  ptr.push({
    name: x.metric,
    data: x.rounded_counts.map(y => [
        Object.keys(y)[0],
        y[Object.keys(y)[0]],
    ]),
  });

  return ptr;
}, []);
</code>```

```<code>/**
 * We have this in entry
 *
 * [
 *   { "2017-11-16 15:10:00": 3 },
 *   { "2017-11-16 15:11:00": 5 },
 *   { "2017-11-16 15:10:00": 28 },
 *   { "2017-11-16 15:11:00": 28 },
 * ]
 *
 * Or this
 *
 * [
 *   [ "2017-11-16 15:10:00", 3 ],
 *   [ "2017-11-16 15:11:00", 5 ],
 * ]
 *
 *
 * WARNING: Here you can have already converted data
 * It happens when we push the first item into the list
 *
 * We return this
 *
 * [
 *   [ "2017-11-16 15:10:00", 31 ],
 *   [ "2017-11-16 15:11:00", 33 ],
 * ]
 *
 */
</code>```

```<code>const addSimilarDatesValues = (array) => {
  return array.reduce((tmp, x) => {
    const ptr = tmp;

    // Handle the already converted data
    const isArray = x instanceof Array;

    const keyToStore = isArray ? x[0] : Object.keys(x)[0];
    const valueToStore = isArray ? x[1] : x[Object.keys(x)[0]];

    // Look if there is a date already in tmp
    const index = ptr.findIndex(y => y[0] === keyToStore);

    // It's not
    if (index === -1) {
      // add a new entry for the date
      return [
        ...ptr,
        [
          keyToStore,
          valueToStore,
        ],
      ];
    }

    // It is - add the value into the already stored one
    ptr[index][1] += valueToStore;

    return ptr;
  }, []);
};
</code>```

const addSimilarDatesValues = (array) => {
  return array.reduce((tmp, x) => {
    const ptr = tmp;
    const isArray = x instanceof Array;

    const keyToStore = isArray ? x[0] : Object.keys(x)[0];
    const valueToStore = isArray ? x[1] : x[Object.keys(x)[0]];

    // Look if there is a date already in tmp
    const index = ptr.findIndex(y => y[0] === keyToStore);

    // It's not
    if (index === -1) {
      // add a new entry for the date
      return [
        ...ptr, [
          keyToStore,
          valueToStore,
        ],
      ];
    }

    // It is - add the value into the already stored one
    ptr[index][1] += valueToStore;

    return ptr;
  }, []);
};

const ret = [{
    "metric": "Approved",
    "rounded_counts": [{
        "2017-11-16 15:10:00": 3
      },
      {
        "2017-11-16 15:11:00": 5
      },
    ]
  },
  {
    "metric": "Approved",
    "rounded_counts": [{
        "2017-11-16 15:10:00": 28
      },
      {
        "2017-11-16 15:11:00": 28
      },
    ]
  },
  {
    "metric": "Quarantine",
    "rounded_counts": [{
        "2017-11-16 15:10:00": 1
      },
      {
        "2017-11-16 15:11:00": 2
      },
    ]
  }
].reduce((tmp, x) => {
  const ptr = tmp;

  // look if it exist
  const index = ptr.findIndex(y => y.name === x.metric);

  // It exist
  if (index !== -1) {
    ptr[index].data = addSimilarDatesValues([
      ...ptr[index].data,
      ...x.rounded_counts,
    ]);

    return ptr;
  }

  // it doesn't
  ptr.push({
    name: x.metric,
    data: x.rounded_counts.map(y => [
      Object.keys(y)[0],
      y[Object.keys(y)[0]],
    ]),
  });

  return ptr;
}, []);

console.log(ret);```

Body:
I'm trying to merge some items in a JSON array, based on one of the keys. I want to group by the 'metric', and then I need to look at all the time/value data in 'rounded_counts', and if the times are the same, the values need to be added together. Here is the source data:

let sourceData = [
  {
    "metric": "Approved",
    "rounded_counts": [
      { "2017-11-16 15:10:00": 3 },
      { "2017-11-16 15:11:00": 5 }
    ]
  },
  {
    "metric": "Approved",
    "rounded_counts": [
      { "2017-11-16 15:10:00": 28 },
      { "2017-11-16 15:11:00": 28 }
    ]
  },
  {
    "metric": "Quarantine",
    "rounded_counts": [
      { "2017-11-16 15:10:00": 1 },
      { "2017-11-16 15:11:00": 2 }
    ]
  }
];

and here is the desired output required for the Highcharts graphing library - notice how the 2 metrics called 'Approved' have had their values merged

Underscore, and/or ES6 can be used - Thanks in advance!

let chartData = [
  {
    "name": "Approved",
    "data": [
      [ "2017-11-16 15:10:00", 30 ],
      [ "2017-11-16 15:11:00", 33 ]
    ]
  },
  {
    "name": "Quarantine",
    "data": [
      [ "2017-11-16 15:10:00", 1 ],
      [ "2017-11-16 15:11:00", 2 ]
    ]
  }
]

Body:
Look at something like this :

[{
      "metric": "Approved",
        "rounded_counts": [
          { "2017-11-16 15:10:00": 3 },
          { "2017-11-16 15:11:00": 5 }
        ]
    },
    ...
].reduce((tmp, x) => {
  const ptr = tmp;

  // look if it exist
  const index = ptr.findIndex(y => y.name === x.metric);

  // It exist
  if (index !== -1) {
    ptr[index].data = addSimilarDatesValues([
      ...ptr[index].data,
      ...x.rounded_counts,
    ]);

    return ptr;
  }

  // it doesn't
  ptr.push({
    name: x.metric,
    data: x.rounded_counts.map(y => [
        Object.keys(y)[0],
        y[Object.keys(y)[0]],
    ]),
  });

  return ptr;
}, []);

/**
 * We have this in entry
 *
 * [
 *   { "2017-11-16 15:10:00": 3 },
 *   { "2017-11-16 15:11:00": 5 },
 *   { "2017-11-16 15:10:00": 28 },
 *   { "2017-11-16 15:11:00": 28 },
 * ]
 *
 * Or this
 *
 * [
 *   [ "2017-11-16 15:10:00", 3 ],
 *   [ "2017-11-16 15:11:00", 5 ],
 * ]
 *
 *
 * WARNING: Here you can have already converted data
 * It happens when we push the first item into the list
 *
 * We return this
 *
 * [
 *   [ "2017-11-16 15:10:00", 31 ],
 *   [ "2017-11-16 15:11:00", 33 ],
 * ]
 *
 */

const addSimilarDatesValues = (array) => {
  return array.reduce((tmp, x) => {
    const ptr = tmp;

    // Handle the already converted data
    const isArray = x instanceof Array;

    const keyToStore = isArray ? x[0] : Object.keys(x)[0];
    const valueToStore = isArray ? x[1] : x[Object.keys(x)[0]];

    // Look if there is a date already in tmp
    const index = ptr.findIndex(y => y[0] === keyToStore);

    // It's not
    if (index === -1) {
      // add a new entry for the date
      return [
        ...ptr,
        [
          keyToStore,
          valueToStore,
        ],
      ];
    }

    // It is - add the value into the already stored one
    ptr[index][1] += valueToStore;

    return ptr;
  }, []);
};

const addSimilarDatesValues = (array) => {
  return array.reduce((tmp, x) => {
    const ptr = tmp;
    const isArray = x instanceof Array;

    const keyToStore = isArray ? x[0] : Object.keys(x)[0];
    const valueToStore = isArray ? x[1] : x[Object.keys(x)[0]];

    // Look if there is a date already in tmp
    const index = ptr.findIndex(y => y[0] === keyToStore);

    // It's not
    if (index === -1) {
      // add a new entry for the date
      return [
        ...ptr, [
          keyToStore,
          valueToStore,
        ],
      ];
    }

    // It is - add the value into the already stored one
    ptr[index][1] += valueToStore;

    return ptr;
  }, []);
};

const ret = [{
    "metric": "Approved",
    "rounded_counts": [{
        "2017-11-16 15:10:00": 3
      },
      {
        "2017-11-16 15:11:00": 5
      },
    ]
  },
  {
    "metric": "Approved",
    "rounded_counts": [{
        "2017-11-16 15:10:00": 28
      },
      {
        "2017-11-16 15:11:00": 28
      },
    ]
  },
  {
    "metric": "Quarantine",
    "rounded_counts": [{
        "2017-11-16 15:10:00": 1
      },
      {
        "2017-11-16 15:11:00": 2
      },
    ]
  }
].reduce((tmp, x) => {
  const ptr = tmp;

  // look if it exist
  const index = ptr.findIndex(y => y.name === x.metric);

  // It exist
  if (index !== -1) {
    ptr[index].data = addSimilarDatesValues([
      ...ptr[index].data,
      ...x.rounded_counts,
    ]);

    return ptr;
  }

  // it doesn't
  ptr.push({
    name: x.metric,
    data: x.rounded_counts.map(y => [
      Object.keys(y)[0],
      y[Object.keys(y)[0]],
    ]),
  });

  return ptr;
}, []);

console.log(ret);


问:
hibernate unique key validation
I have a field, say, user_name, that should be unique in a table.

What is the best way for validating it using Spring/Hibernate validation?

答:
One of the possible solutions is to create custom @UniqueKey constraint (and corresponding validator); and to look-up the existing records in database, provide an instance of EntityManager (or Hibernate Session)to UniqueKeyValidator.

EntityManagerAwareValidator

```<code>public interface EntityManagerAwareValidator {
     void setEntityManager(EntityManager entityManager);
}
</code>```

ConstraintValidatorFactoryImpl

```<code>public class ConstraintValidatorFactoryImpl implements ConstraintValidatorFactory {

    private EntityManagerFactory entityManagerFactory;

    public ConstraintValidatorFactoryImpl(EntityManagerFactory entityManagerFactory) {
        this.entityManagerFactory = entityManagerFactory;
    }

    @Override
    public <T extends ConstraintValidator<?, ?>> T getInstance(Class<T> key) {
        T instance = null;

        try {
            instance = key.newInstance();
        } catch (Exception e) {
            // could not instantiate class
            e.printStackTrace();
        }

        if(EntityManagerAwareValidator.class.isAssignableFrom(key)) {
            EntityManagerAwareValidator validator = (EntityManagerAwareValidator) instance;
            validator.setEntityManager(entityManagerFactory.createEntityManager());
        }

        return instance;
    }
}
</code>```

UniqueKey

```<code>@Constraint(validatedBy={UniqueKeyValidator.class})
@Target({ElementType.TYPE})
@Retention(RUNTIME)
public @interface UniqueKey {

    String[] columnNames();

    String message() default "{UniqueKey.message}";

    Class<?>[] groups() default {};

    Class<? extends Payload>[] payload() default {};

    @Target({ ElementType.TYPE })
    @Retention(RUNTIME)
    @Documented
    @interface List {
        UniqueKey[] value();
    }
}
</code>```

UniqueKeyValidator

```<code>public class UniqueKeyValidator implements ConstraintValidator<UniqueKey, Serializable>, EntityManagerAwareValidator {

    private EntityManager entityManager;

    @Override
    public void setEntityManager(EntityManager entityManager) {
        this.entityManager = entityManager;
    }

    private String[] columnNames;

    @Override
    public void initialize(UniqueKey constraintAnnotation) {
        this.columnNames = constraintAnnotation.columnNames();

    }

    @Override
    public boolean isValid(Serializable target, ConstraintValidatorContext context) {
        Class<?> entityClass = target.getClass();

        CriteriaBuilder criteriaBuilder = entityManager.getCriteriaBuilder();

        CriteriaQuery<Object> criteriaQuery = criteriaBuilder.createQuery();

        Root<?> root = criteriaQuery.from(entityClass);

        List<Predicate> predicates = new ArrayList<Predicate> (columnNames.length);

        try {
            for(int i=0; i<columnNames.length; i++) {
                String propertyName = columnNames[i];
                PropertyDescriptor desc = new PropertyDescriptor(propertyName, entityClass);
                Method readMethod = desc.getReadMethod();
                Object propertyValue = readMethod.invoke(target);
                Predicate predicate = criteriaBuilder.equal(root.get(propertyName), propertyValue);
                predicates.add(predicate);
            }
        } catch (Exception e) {
            e.printStackTrace();
        }

        criteriaQuery.where(predicates.toArray(new Predicate[predicates.size()]));

        TypedQuery<Object> typedQuery = entityManager.createQuery(criteriaQuery);

        List<Object> resultSet = typedQuery.getResultList();

        return resultSet.size() == 0;
    }

}
</code>```

Usage

```<code>@UniqueKey(columnNames={"userName"})
// @UniqueKey(columnNames={"userName", "emailId"}) // composite unique key
//@UniqueKey.List(value = {@UniqueKey(columnNames = { "userName" }), @UniqueKey(columnNames = { "emailId" })}) // more than one unique keys
public class User implements Serializable {

    private String userName;
    private String password;
    private String emailId;

    protected User() {
        super();
    }

    public User(String userName) {
        this.userName = userName;
    }
        ....
}
</code>```

Test

```<code>public void uniqueKey() {
    EntityManagerFactory entityManagerFactory = Persistence.createEntityManagerFactory("default");

    ValidatorFactory validatorFactory = Validation.buildDefaultValidatorFactory();
    ValidatorContext validatorContext = validatorFactory.usingContext();
    validatorContext.constraintValidatorFactory(new ConstraintValidatorFactoryImpl(entityManagerFactory));
    Validator validator = validatorContext.getValidator();

    EntityManager em = entityManagerFactory.createEntityManager();

    User se = new User("abc", poizon);

       Set<ConstraintViolation<User>> violations = validator.validate(se);
    System.out.println("Size:- " + violations.size());

    em.getTransaction().begin();
    em.persist(se);
    em.getTransaction().commit();

        User se1 = new User("abc");

    violations = validator.validate(se1);

    System.out.println("Size:- " + violations.size());
}
</code>```

Title: hibernate unique key validation

Body:
One of the possible solutions is to create custom @UniqueKey constraint (and corresponding validator); and to look-up the existing records in database, provide an instance of EntityManager (or Hibernate Session)to UniqueKeyValidator.

EntityManagerAwareValidator

public interface EntityManagerAwareValidator {
     void setEntityManager(EntityManager entityManager);
}

ConstraintValidatorFactoryImpl

public class ConstraintValidatorFactoryImpl implements ConstraintValidatorFactory {

    private EntityManagerFactory entityManagerFactory;

    public ConstraintValidatorFactoryImpl(EntityManagerFactory entityManagerFactory) {
        this.entityManagerFactory = entityManagerFactory;
    }

    @Override
    public <T extends ConstraintValidator<?, ?>> T getInstance(Class<T> key) {
        T instance = null;

        try {
            instance = key.newInstance();
        } catch (Exception e) {
            // could not instantiate class
            e.printStackTrace();
        }

        if(EntityManagerAwareValidator.class.isAssignableFrom(key)) {
            EntityManagerAwareValidator validator = (EntityManagerAwareValidator) instance;
            validator.setEntityManager(entityManagerFactory.createEntityManager());
        }

        return instance;
    }
}

UniqueKey

@Constraint(validatedBy={UniqueKeyValidator.class})
@Target({ElementType.TYPE})
@Retention(RUNTIME)
public @interface UniqueKey {

    String[] columnNames();

    String message() default "{UniqueKey.message}";

    Class<?>[] groups() default {};

    Class<? extends Payload>[] payload() default {};

    @Target({ ElementType.TYPE })
    @Retention(RUNTIME)
    @Documented
    @interface List {
        UniqueKey[] value();
    }
}

UniqueKeyValidator

public class UniqueKeyValidator implements ConstraintValidator<UniqueKey, Serializable>, EntityManagerAwareValidator {

    private EntityManager entityManager;

    @Override
    public void setEntityManager(EntityManager entityManager) {
        this.entityManager = entityManager;
    }

    private String[] columnNames;

    @Override
    public void initialize(UniqueKey constraintAnnotation) {
        this.columnNames = constraintAnnotation.columnNames();

    }

    @Override
    public boolean isValid(Serializable target, ConstraintValidatorContext context) {
        Class<?> entityClass = target.getClass();

        CriteriaBuilder criteriaBuilder = entityManager.getCriteriaBuilder();

        CriteriaQuery<Object> criteriaQuery = criteriaBuilder.createQuery();

        Root<?> root = criteriaQuery.from(entityClass);

        List<Predicate> predicates = new ArrayList<Predicate> (columnNames.length);

        try {
            for(int i=0; i<columnNames.length; i++) {
                String propertyName = columnNames[i];
                PropertyDescriptor desc = new PropertyDescriptor(propertyName, entityClass);
                Method readMethod = desc.getReadMethod();
                Object propertyValue = readMethod.invoke(target);
                Predicate predicate = criteriaBuilder.equal(root.get(propertyName), propertyValue);
                predicates.add(predicate);
            }
        } catch (Exception e) {
            e.printStackTrace();
        }

        criteriaQuery.where(predicates.toArray(new Predicate[predicates.size()]));

        TypedQuery<Object> typedQuery = entityManager.createQuery(criteriaQuery);

        List<Object> resultSet = typedQuery.getResultList();

        return resultSet.size() == 0;
    }

}

Usage

@UniqueKey(columnNames={"userName"})
// @UniqueKey(columnNames={"userName", "emailId"}) // composite unique key
//@UniqueKey.List(value = {@UniqueKey(columnNames = { "userName" }), @UniqueKey(columnNames = { "emailId" })}) // more than one unique keys
public class User implements Serializable {

    private String userName;
    private String password;
    private String emailId;

    protected User() {
        super();
    }

    public User(String userName) {
        this.userName = userName;
    }
        ....
}

Test

public void uniqueKey() {
    EntityManagerFactory entityManagerFactory = Persistence.createEntityManagerFactory("default");

    ValidatorFactory validatorFactory = Validation.buildDefaultValidatorFactory();
    ValidatorContext validatorContext = validatorFactory.usingContext();
    validatorContext.constraintValidatorFactory(new ConstraintValidatorFactoryImpl(entityManagerFactory));
    Validator validator = validatorContext.getValidator();

    EntityManager em = entityManagerFactory.createEntityManager();

    User se = new User("abc", poizon);

       Set<ConstraintViolation<User>> violations = validator.validate(se);
    System.out.println("Size:- " + violations.size());

    em.getTransaction().begin();
    em.persist(se);
    em.getTransaction().commit();

        User se1 = new User("abc");

    violations = validator.validate(se1);

    System.out.println("Size:- " + violations.size());
}


问:
ReadStream skipping bytes?
I'm writing a keyboard-events parser for Linux, using node.js. It's working somewhat okay, but sometimes it seems like node is skipping a few bytes. I'm using a ReadStream to get the data, handle it, process it, and eventually output it when a separator character is encountered (in my case, \n).

Here is the part of my class that handles the read data:

```<code>// This method is called through this callback:
// this.readStream = fs.createReadStream(this.path);
// this.readStream.on("data", function(a) { self.parse_data(self, a); });

EventParser.prototype.parse_data = function(self, data)
{
  /*
   * Data format :
   * {
   *   0x00 : struct timeval time { long sec (8), long usec (8) }        (8  bytes)
   *   0x08 : __u16 type                                                 (2  bytes)
   *   0x10 : __u16 code                                                 (2  bytes)
   *   0x12 : __s32 value                                                (4  bytes)
   * }                                                                 = (16 bytes)
   */

  var dataBuffer = new Buffer(data);
  var slicedBuffer = dataBuffer.slice(0, 16);
  dataBuffer = dataBuffer.slice(16, dataBuffer.length);

  while (dataBuffer.length > 0 && slicedBuffer.length == 16)
  {
    var type = GetDataType(slicedBuffer),
        code = GetDataCode(slicedBuffer),
        value = GetDataValue(slicedBuffer);

    if (type == CST.EV.KEY)
    { // Key was pressed: KEY event type
      if (code == 42 && value == 1) { self.shift_pressed = true; }
      if (code == 42 && value == 0) { self.shift_pressed = false; }

      console.log(type + "\t" + code + "\t" + value + "\t(" + GetKey(self.shift_pressed, code) + ")")
      // GetKey uses a static array to get the actual character
      // based on whether the shift key is held or not

      if (value == 1)
        self.handle_processed_data(GetKey(self.shift_pressed, code));
      // handle_processed_data adds characters together, and outputs the string when encountering a
      // separator character (in this case, '\n')
    }

    // Take a new slice, and loop.
    slicedBuffer = dataBuffer.slice(0, 16);
    dataBuffer = dataBuffer.slice(16, dataBuffer.length);
  }
}

// My system is in little endian!
function GetDataType(dataBuffer)  { return dataBuffer.readUInt16LE(8);  }
function GetDataCode(dataBuffer)  { return dataBuffer.readUInt16LE(10); }
function GetDataValue(dataBuffer) { return dataBuffer.readInt32LE(12);  }
</code>```

I'm basically filling up the data structure explained at the top using a Buffer. The interesting part is the console.log near the end, which will print everything interesting (related to the KEY event) that passes in our callback! Here is the result of such log, complete with the expected result, and the actual result:

```<code>EventParserConstructor: Listening to /dev/input/event19
/* Expected result: CODE-128 */
/* Note that value 42 is the SHIFT key */
1   42  1   ()
1   46  1   (C)
1   42  0   ()
1   46  0   (c)
1   42  1   ()
1   24  1   (O)
1   42  0   ()
1   24  0   (o)
1   42  1   ()
1   32  1   (D)
1   42  0   ()
1   32  0   (d)
1   42  1   ()
1   18  1   (E)
1   42  0   ()
1   18  0   (e)
1   12  0   (-)
1   2   0   (1)
1   3   1   (2)
1   3   0   (2)
1   9   1   (8)
1   9   0   (8)
1   28  1   (
)
[EventParser_Handler]/event_parser.handle_processed_data: CODE28
/* Actual result: CODE28 */
/* The '-' and '1' events can be seen in the logs, but only */
/* as key RELEASED (value: 0), not key PRESSED */
</code>```

We can clearly see the - and 1 character events passing by, but only as key releases (value: 0), not key presses. The weirdest thing is that most of the time, the events are correctly translated. But 10% of the time, this happens.

Is ReadStream eating up some bytes, occasionally? If yes, what alternative should I be using?

Thanks in advance!

答:
Well, turns out that my loop was rotten.

I was assuming that the data would only come in chunks of 16 bytes... Which obviously isn't always the case. So sometimes, I had packets of <16 bytes being left over and lost between two 'data' event callbacks.

I added this by adding an excessBuffer field to my class and using it to fill my initial slicedBuffer when receiving data.

Title: ReadStream skipping bytes?

Body:
I'm writing a keyboard-events parser for Linux, using node.js. It's working somewhat okay, but sometimes it seems like node is skipping a few bytes. I'm using a ReadStream to get the data, handle it, process it, and eventually output it when a separator character is encountered (in my case, \n).

Here is the part of my class that handles the read data:

// This method is called through this callback:
// this.readStream = fs.createReadStream(this.path);
// this.readStream.on("data", function(a) { self.parse_data(self, a); });

EventParser.prototype.parse_data = function(self, data)
{
  /*
   * Data format :
   * {
   *   0x00 : struct timeval time { long sec (8), long usec (8) }        (8  bytes)
   *   0x08 : __u16 type                                                 (2  bytes)
   *   0x10 : __u16 code                                                 (2  bytes)
   *   0x12 : __s32 value                                                (4  bytes)
   * }                                                                 = (16 bytes)
   */

  var dataBuffer = new Buffer(data);
  var slicedBuffer = dataBuffer.slice(0, 16);
  dataBuffer = dataBuffer.slice(16, dataBuffer.length);

  while (dataBuffer.length > 0 && slicedBuffer.length == 16)
  {
    var type = GetDataType(slicedBuffer),
        code = GetDataCode(slicedBuffer),
        value = GetDataValue(slicedBuffer);

    if (type == CST.EV.KEY)
    { // Key was pressed: KEY event type
      if (code == 42 && value == 1) { self.shift_pressed = true; }
      if (code == 42 && value == 0) { self.shift_pressed = false; }

      console.log(type + "\t" + code + "\t" + value + "\t(" + GetKey(self.shift_pressed, code) + ")")
      // GetKey uses a static array to get the actual character
      // based on whether the shift key is held or not

      if (value == 1)
        self.handle_processed_data(GetKey(self.shift_pressed, code));
      // handle_processed_data adds characters together, and outputs the string when encountering a
      // separator character (in this case, '\n')
    }

    // Take a new slice, and loop.
    slicedBuffer = dataBuffer.slice(0, 16);
    dataBuffer = dataBuffer.slice(16, dataBuffer.length);
  }
}

// My system is in little endian!
function GetDataType(dataBuffer)  { return dataBuffer.readUInt16LE(8);  }
function GetDataCode(dataBuffer)  { return dataBuffer.readUInt16LE(10); }
function GetDataValue(dataBuffer) { return dataBuffer.readInt32LE(12);  }

I'm basically filling up the data structure explained at the top using a Buffer. The interesting part is the console.log near the end, which will print everything interesting (related to the KEY event) that passes in our callback! Here is the result of such log, complete with the expected result, and the actual result:

EventParserConstructor: Listening to /dev/input/event19
/* Expected result: CODE-128 */
/* Note that value 42 is the SHIFT key */
1   42  1   ()
1   46  1   (C)
1   42  0   ()
1   46  0   (c)
1   42  1   ()
1   24  1   (O)
1   42  0   ()
1   24  0   (o)
1   42  1   ()
1   32  1   (D)
1   42  0   ()
1   32  0   (d)
1   42  1   ()
1   18  1   (E)
1   42  0   ()
1   18  0   (e)
1   12  0   (-)
1   2   0   (1)
1   3   1   (2)
1   3   0   (2)
1   9   1   (8)
1   9   0   (8)
1   28  1   (
)
[EventParser_Handler]/event_parser.handle_processed_data: CODE28
/* Actual result: CODE28 */
/* The '-' and '1' events can be seen in the logs, but only */
/* as key RELEASED (value: 0), not key PRESSED */

We can clearly see the - and 1 character events passing by, but only as key releases (value: 0), not key presses. The weirdest thing is that most of the time, the events are correctly translated. But 10% of the time, this happens.

Is ReadStream eating up some bytes, occasionally? If yes, what alternative should I be using?

Thanks in advance!