问:
How to POST multipart binary & non-binary with httr (for Salesforce API)
I'm having some trouble using httr to POST a file to Salesforce's REST API. I thought this SO question might take care of it, but didn't seem to. I have a hunch that this is because Saleforce wants a non-binary part and upload_file creates an object of class form_file that's handled as a binary, but maybe someone has an alternate explanation/solution...

Salesforce asks for the following curl request to insert a new document:

```<code>curl https://yourInstance.salesforce.com/services/data/v23.0/sobjects/Document/ -H
"Authorization: Bearer token" -H "Content-Type: multipart/form-data;
boundary=\"boundary_string\"" --data-binary @newdocument.json
</code>```

with newdocument.json looking like this:

```<code>--boundary_string
Content-Disposition: form-data; name="entity_document";
Content-Type: application/json
{
"Description" : "Marketing brochure for Q1 2011",
"Keywords" : "marketing,sales,update",
"FolderId" : "005D0000001GiU7",
"Name" : "Marketing Brochure Q1",
"Type" : "pdf"
}
--boundary_string
Content-Type: application/pdf
Content-Disposition: form-data; name="Body"; filename="2011Q1MktgBrochure.pdf"
Binary data goes here.
--boundary_string--
</code>```

If I try to generate a similar output using @Jeroen's answer as a helpful guide, I get a Bad Request error:

```<code>library(httr)
library(jsonlite)

url <- "https://[Salesforce Instance]/services/data/v39.0/sobjects/Document/"
header <- add_headers(c(Authorization = "Bearer [Salesforce Key]"))

media <- tempfile()
png(media, width = 800, height = 600)
plot(cars)
dev.off()

metadata <- tempfile()
x <- data.frame(FolderId="a0a1300000ZG7u3", Name="test.png") #Salesforce Record ID and file name
json <- toJSON(unbox(x), pretty=T)
writeLines(json, metadata)

body <- list(entity_document = upload_file(metadata, type = "application/json; charset=UTF-8"),
             Body = upload_file(media, type = "image/png"))

req <- POST(url, header, verbose(), body = body)
</code>```

(verbose output)

```<code>-> POST /services/data/v39.0/sobjects/Document/ HTTP/1.1
-> Host: [Salesforce Instance]
-> User-Agent: libcurl/7.51.0 r-curl/2.3 httr/1.2.1.9000
-> Accept-Encoding: gzip, deflate
-> Accept: application/json, text/xml, application/xml, */*
-> Authorization: Bearer [Salesforce Key]
-> Content-Length: 3720
-> Expect: 100-continue
-> Content-Type: multipart/form-data; boundary=------------------------6525413b2350e313
->
<- HTTP/1.1 100 Continue
>> --------------------------6525413b2350e313
>> Content-Disposition: form-data; name="entity_document"; filename="file1510059b5200f"
>> Content-Type: application/json
>>

>> {
>>     "FolderId": "a0a1300000ZG7u3",
>>     "Name": "test.png"
>>   }

>>
>> --------------------------6525413b2350e313
>> Content-Disposition: form-data; name="Body"; filename="file151001ac96950"
>> Content-Type: image/png
>>

>> ‰PNG
>>

>>
>> --------------------------6525413b2350e313--

<- HTTP/1.1 400 Bad Request
</code>```

with the exception of the filename in the first part, this is pretty close to the desired output, but Salesforce returns the message:

```<code>content(req)

[[1]]
[[1]]$message
[1] "Cannot include more than one binary part"

[[1]]$errorCode
[1] "INVALID_MULTIPART_REQUEST"
</code>```

I tried with just the json but get a slightly different Bad Request:

```<code>body <- list(entity_document= json,
             Body = upload_file(media, type = "image/png"))

-> Content-Type: multipart/form-data; boundary=------------------------ecbd3787f083e4b1
->
<- HTTP/1.1 100 Continue
>> --------------------------ecbd3787f083e4b1
>> Content-Disposition: form-data; name="entity_document"
>>
>> {
>>     "FolderId": "a0a1300000ZG7u3",
>>     "Name": "test.png"
>>   }
>> --------------------------ecbd3787f083e4b1
>> Content-Disposition: form-data; name="Body"; filename="file151001ac96950"
>> Content-Type: image/png
>>

>> ‰PNG
>>

>>
>> --------------------------ecbd3787f083e4b1--

content(req)

[[1]]
[[1]]$message
[1] "Multipart message must include a non-binary part"

[[1]]$errorCode
[1] "INVALID_MULTIPART_REQUEST"
</code>```

Digging into the details, it seems to me that curl either reads and posts the metadata file as a binary if I use upload_file or posts the json without the content type if I post it as character. Is this the only issue? And if so, is there any way to modify the handler to accept the content type?

Any help is much appreciated!

答:
Here's a (temporary) solution based on @Jeroen's latest additions to curl (see Github issue for reference):

```<code>library(curl) #>=2.4 on Cran
library(httr)
library(jsonlite)

url <- "https://[Salesforce Instance]/services/data/v39.0/sobjects/Document/"
header <- add_headers(c(Authorization = "Bearer [Salesforce Key]"))

path <- tempfile()
png(path, width = 800, height = 600)
plot(cars)
dev.off()

media <- upload_file(path)

x  <- data.frame(Name=basename(path),ParentId="[Salesforce Parent ID]",Description="",IsPrivate=FALSE)
x <- as.character(toJSON(unbox(x),pretty=T))
metadata <- form_data(x,"application/json") #new curl function to handle a character body with defined type

body <- list(metadata=metadata,Body=media)

req <- httr:::request(fields=body)
req <- httr:::request_build("POST",url,req,header)

response <- httr:::request_perform(req,new_handle())
</code>```

I put in a request for httr to incorporate this new handling and would imagine that it will be more straightforward to use, i.e. a simple POST(url,header,body=body), once they get around to it.

Hope it helps!

Body:
I'm having some trouble using httr to POST a file to Salesforce's REST API. I thought this SO question might take care of it, but didn't seem to. I have a hunch that this is because Saleforce wants a non-binary part and upload_file creates an object of class form_file that's handled as a binary, but maybe someone has an alternate explanation/solution...

Salesforce asks for the following curl request to insert a new document:

curl https://yourInstance.salesforce.com/services/data/v23.0/sobjects/Document/ -H
"Authorization: Bearer token" -H "Content-Type: multipart/form-data;
boundary=\"boundary_string\"" --data-binary @newdocument.json

with newdocument.json looking like this:

--boundary_string
Content-Disposition: form-data; name="entity_document";
Content-Type: application/json
{
"Description" : "Marketing brochure for Q1 2011",
"Keywords" : "marketing,sales,update",
"FolderId" : "005D0000001GiU7",
"Name" : "Marketing Brochure Q1",
"Type" : "pdf"
}
--boundary_string
Content-Type: application/pdf
Content-Disposition: form-data; name="Body"; filename="2011Q1MktgBrochure.pdf"
Binary data goes here.
--boundary_string--

If I try to generate a similar output using @Jeroen's answer as a helpful guide, I get a Bad Request error:

library(httr)
library(jsonlite)

url <- "https://[Salesforce Instance]/services/data/v39.0/sobjects/Document/"
header <- add_headers(c(Authorization = "Bearer [Salesforce Key]"))

media <- tempfile()
png(media, width = 800, height = 600)
plot(cars)
dev.off()

metadata <- tempfile()
x <- data.frame(FolderId="a0a1300000ZG7u3", Name="test.png") #Salesforce Record ID and file name
json <- toJSON(unbox(x), pretty=T)
writeLines(json, metadata)

body <- list(entity_document = upload_file(metadata, type = "application/json; charset=UTF-8"),
             Body = upload_file(media, type = "image/png"))

req <- POST(url, header, verbose(), body = body)

(verbose output)

-> POST /services/data/v39.0/sobjects/Document/ HTTP/1.1
-> Host: [Salesforce Instance]
-> User-Agent: libcurl/7.51.0 r-curl/2.3 httr/1.2.1.9000
-> Accept-Encoding: gzip, deflate
-> Accept: application/json, text/xml, application/xml, */*
-> Authorization: Bearer [Salesforce Key]
-> Content-Length: 3720
-> Expect: 100-continue
-> Content-Type: multipart/form-data; boundary=------------------------6525413b2350e313
->
<- HTTP/1.1 100 Continue
>> --------------------------6525413b2350e313
>> Content-Disposition: form-data; name="entity_document"; filename="file1510059b5200f"
>> Content-Type: application/json
>>

>> {
>>     "FolderId": "a0a1300000ZG7u3",
>>     "Name": "test.png"
>>   }

>>
>> --------------------------6525413b2350e313
>> Content-Disposition: form-data; name="Body"; filename="file151001ac96950"
>> Content-Type: image/png
>>

>> ‰PNG
>>

>>
>> --------------------------6525413b2350e313--

<- HTTP/1.1 400 Bad Request

with the exception of the filename in the first part, this is pretty close to the desired output, but Salesforce returns the message:

content(req)

[[1]]
[[1]]$message
[1] "Cannot include more than one binary part"

[[1]]$errorCode
[1] "INVALID_MULTIPART_REQUEST"

I tried with just the json but get a slightly different Bad Request:

body <- list(entity_document= json,
             Body = upload_file(media, type = "image/png"))

-> Content-Type: multipart/form-data; boundary=------------------------ecbd3787f083e4b1
->
<- HTTP/1.1 100 Continue
>> --------------------------ecbd3787f083e4b1
>> Content-Disposition: form-data; name="entity_document"
>>
>> {
>>     "FolderId": "a0a1300000ZG7u3",
>>     "Name": "test.png"
>>   }
>> --------------------------ecbd3787f083e4b1
>> Content-Disposition: form-data; name="Body"; filename="file151001ac96950"
>> Content-Type: image/png
>>

>> ‰PNG
>>

>>
>> --------------------------ecbd3787f083e4b1--

content(req)

[[1]]
[[1]]$message
[1] "Multipart message must include a non-binary part"

[[1]]$errorCode
[1] "INVALID_MULTIPART_REQUEST"

Digging into the details, it seems to me that curl either reads and posts the metadata file as a binary if I use upload_file or posts the json without the content type if I post it as character. Is this the only issue? And if so, is there any way to modify the handler to accept the content type?

Any help is much appreciated!

Body:
Here's a (temporary) solution based on @Jeroen's latest additions to curl (see Github issue for reference):

library(curl) #>=2.4 on Cran
library(httr)
library(jsonlite)

url <- "https://[Salesforce Instance]/services/data/v39.0/sobjects/Document/"
header <- add_headers(c(Authorization = "Bearer [Salesforce Key]"))

path <- tempfile()
png(path, width = 800, height = 600)
plot(cars)
dev.off()

media <- upload_file(path)

x  <- data.frame(Name=basename(path),ParentId="[Salesforce Parent ID]",Description="",IsPrivate=FALSE)
x <- as.character(toJSON(unbox(x),pretty=T))
metadata <- form_data(x,"application/json") #new curl function to handle a character body with defined type

body <- list(metadata=metadata,Body=media)

req <- httr:::request(fields=body)
req <- httr:::request_build("POST",url,req,header)

response <- httr:::request_perform(req,new_handle())

I put in a request for httr to incorporate this new handling and would imagine that it will be more straightforward to use, i.e. a simple POST(url,header,body=body), once they get around to it.

Hope it helps!


来源: stackexchange

问:
How do I control which channel sound is played through using MATLAB?
I'm a novice MATLAB user, so apologies if the question is very basic. I need a .wav sound file to be played in a single, specific channel -- let's say the left channel. As it is, my code reads in the sound file, and I add in a column of zeros to nullify the channel I don't want, like so:

```<code>currentDir = pwd;
soundFile = [currentDir '\sound1.wav']; % load the file

[y, Fs] = audioread(soundFile); % read the file in

soundData(:,1) = y(:,1); % keeps sound for the left channel
soundData(:,2) = 0; % nullifies the right channel

sound = audioplayer(soundData,Fs);
play(sound);
</code>```

As it stands, the code currently produces a sound that is full volume in the left speaker, and half volume (but still very much audible) in the right speaker. I have tried this with at least 20 .wav files, with the same result.

In case it's relevant, this happens even when I write in code that explicitly matches the length of the sound variable in 0s, like so:

```<code>[y, Fs] = audioread(soundFile);
silentChannel = zeros(size(y));

soundData(:,1) = y(:,1); % keeps sound for the left channel
soundData(:,2) = silentChannel(:,2); % nullifies the right channel
</code>```

Does anybody know what I'm doing wrong, or have any thoughts?

答:
In MatLab the expected method for playing sound is the method sound(data,Fs)

To control the channel the sound emits on, you'll want to know how sound() reads data.

data is a matrix with the columns representing channels, and with the rows holding the samples of the waveform for a given sampling fequency Fs

here is a simple implementation.

```<code>function treismanwolfe()
    close all
    clear all
    clc
    Fs = 40000;
    tau = 2*pi();
    t = 0:tau/(Fs-1):tau/2;
    left = sin(t).*(sin(t*200)+sin(t*1600));
    left= left/max(abs(left));
    left = left'; %turn column vector into row
    right = sin(t).*(sin(t*800)+sin(t*400));
    right= right/max(abs(right));
    right = right'; %turn column vector into row
    data = [left,right*0]; %multiply either by 0 to nullify
    sound(data,Fs); %so you can hear it.
end
</code>```

I hope this works for you. Enjoy!

ContentLicense: CC BY-SA 3.0

Body:
I'm a novice MATLAB user, so apologies if the question is very basic. I need a .wav sound file to be played in a single, specific channel -- let's say the left channel. As it is, my code reads in the sound file, and I add in a column of zeros to nullify the channel I don't want, like so:

currentDir = pwd;
soundFile = [currentDir '\sound1.wav']; % load the file

[y, Fs] = audioread(soundFile); % read the file in

soundData(:,1) = y(:,1); % keeps sound for the left channel
soundData(:,2) = 0; % nullifies the right channel

sound = audioplayer(soundData,Fs);
play(sound);

As it stands, the code currently produces a sound that is full volume in the left speaker, and half volume (but still very much audible) in the right speaker. I have tried this with at least 20 .wav files, with the same result.

In case it's relevant, this happens even when I write in code that explicitly matches the length of the sound variable in 0s, like so:

[y, Fs] = audioread(soundFile);
silentChannel = zeros(size(y));

soundData(:,1) = y(:,1); % keeps sound for the left channel
soundData(:,2) = silentChannel(:,2); % nullifies the right channel

Does anybody know what I'm doing wrong, or have any thoughts?

Body:
In MatLab the expected method for playing sound is the method sound(data,Fs)

To control the channel the sound emits on, you'll want to know how sound() reads data.

data is a matrix with the columns representing channels, and with the rows holding the samples of the waveform for a given sampling fequency Fs

here is a simple implementation.

function treismanwolfe()
    close all
    clear all
    clc
    Fs = 40000;
    tau = 2*pi();
    t = 0:tau/(Fs-1):tau/2;
    left = sin(t).*(sin(t*200)+sin(t*1600));
    left= left/max(abs(left));
    left = left'; %turn column vector into row
    right = sin(t).*(sin(t*800)+sin(t*400));
    right= right/max(abs(right));
    right = right'; %turn column vector into row
    data = [left,right*0]; %multiply either by 0 to nullify
    sound(data,Fs); %so you can hear it.
end

I hope this works for you. Enjoy!


问:
I want 7 days ahead of current date by using java 7 not java 8
```<code>String s= new java.util.Date().toString();
</code>```

<p>I am using java 7, I want to print one week ahead of this date I have used the calendar class but it always gives me IST 1970 and does not give correct answer and I want that date into string so please help me in this. I know this question is repeated but they cant solve my query?        </p>

答:
Don't use Date, use Calendar:

```<code>Calendar cal = Calendar.getInstance();
cal.add(Calendar.DATE, 7);
System.out.println(cal.getTime());
</code>```

Body:
String s= new java.util.Date().toString();

I am using java 7, I want to print one week ahead of this date I have used the calendar class but it always gives me IST 1970 and does not give correct answer and I want that date into string so please help me in this. I know this question is repeated but they cant solve my query?

Body:
Don't use Date, use Calendar:

Calendar cal = Calendar.getInstance();
cal.add(Calendar.DATE, 7);
System.out.println(cal.getTime());


问:
Optional html class in twig template
I have a simple reusable twig (generic.html.twig) template which look like:

```<code><ul>
    {% for item in list %}
        <li>
            ...
        </li>
    {% endfor %}
</ul>
</code>```

I use it many times in my code like this:

```<code>{% include "@Toto/generic.html.twig" with {"list": toto} %}
</code>```

My problem is that I sometimes want to include a CSS class on the
 generated by my twig template. So sometimes I would like for it to render like this:

```<code><ul class="myclass">
</code>```

while other times I'd like for it to render without the class, like this:

```<code><ul>
</code>```

How do I implement optional classes in my twig template?

答:
I would use something like:

```<code>{% include "@Toto/generic.html.twig" with {"list": toto, "status": true} %}
</code>```

And check against status boolean

```<code><ul {{ status ? 'class="myclass"' : '' }}>
</code>```

Title: Optional html class in twig template

Body:
I have a simple reusable twig (generic.html.twig) template which look like:

    {% for item in list %}

            ...

    {% endfor %}

I use it many times in my code like this:

{% include "@Toto/generic.html.twig" with {"list": toto} %}

My problem is that I sometimes want to include a CSS class on the
 generated by my twig template. So sometimes I would like for it to render like this:

while other times I'd like for it to render without the class, like this:

How do I implement optional classes in my twig template?

Body:
I would use something like:

{% include "@Toto/generic.html.twig" with {"list": toto, "status": true} %}

And check against status boolean

<ul {{ status ? 'class="myclass"' : '' }}>

ContentLicense: CC BY-SA 4.0


问:
Flow - A type that can only result from a function
Using Flow (or typescript out of curiosity), can I create a type that can only result from a specific function? I want to be able to type a string that has been sanitized as something like "SanitizedString". However, if I simply aliased type SanitizedString = string, then I could assign a non-sanitized string to that type.

So instead, I want to type it so it can only come from a return from my sanitizeHtml() function. Does anyone know if this is possible in either type system?

Thanks!

答:
In Typescript, you could do it with intersection types and a "tagging" interface.

```<code>interface Sanitized {
    isSanitized: never;
}

type SanitizedType<T> = T & Sanitized;

function sanitizeString(str: string): SanitizedType<string> {
    return str as SanitizedType<string>;
}

function printSanitizedString(sstr: SanitizedType<string>): void {
    console.log(sstr);
}

printSanitizedString("Hello, world!"); // ERR
printSanitizedString(sanitizeString("Hello, world!")); // OK
</code>```

As we don't actually need the value of isSanitized for anything (we just want it for the typing), we type it is as never so we get errors if we try to use it. Being an intersection type, the return value of sanitizeString(str) is usable wherever a normal string is usable.

Body:
In Typescript, you could do it with intersection types and a "tagging" interface.

interface Sanitized {
    isSanitized: never;
}

type SanitizedType<T> = T & Sanitized;

function sanitizeString(str: string): SanitizedType<string> {
    return str as SanitizedType<string>;
}

function printSanitizedString(sstr: SanitizedType<string>): void {
    console.log(sstr);
}

printSanitizedString("Hello, world!"); // ERR
printSanitizedString(sanitizeString("Hello, world!")); // OK

As we don't actually need the value of isSanitized for anything (we just want it for the typing), we type it is as never so we get errors if we try to use it. Being an intersection type, the return value of sanitizeString(str) is usable wherever a normal string is usable.


问:
REST: should PUT always accept what is previously returned by a GET
Let's consider that our PUT endpoint performs some data validation on the contents of the data. Then, is this scenario (in pseudo code):

data = GET

short latency happens, no update server-side

PUT data

=> always yielding a 200/2xx? Or would it be possible that the data is considered invalid by the PUT endpoint (4xx?)

In other words: should a service allow clients to read (GET) a resource representation that would be itself flagged as invalid (with respect to data validation) when sent on update (PUT)?

UPDATE: Note: this is not about media-types but actual data validation.

答:
When you perform a GET request you're asking for a representation of a resource. When you perform a PUT request, you're asking to replace the targeted resource with the one in the submitted representation.

So, if the same media-type is used for both representations, the server should accept it, but it's perfectly possible to have one media-type for PUT and another for GET.

should the server allow clients to read (GET) a resource that would be
  itself flagged as invalid when sent on update (PUT)?

That is determined by the Content-Type headers. An example is if the server allows clients to get a pretty formatted HTML document when the GET request is performed with Accept: text/html, but the clients have to update that resource with a application/json representation.


问:
How to get more details regarding Python "the specified module could not be found"
When importing a DLL module into Python, sometimes I will get:

```<code>ImportError: DLL load failed: The specified module could not be found.
</code>```

The problem is often:

Missing DLL dependency (commonly a Visual Studio runtime DLL)

DLL or dependency compiled for 32 bit when should be 64 bit

Dependency walker answers this question sometimes. But, sometimes it doesn't, particularly if the issue is a missing Visual Studio runtime DLL.

Is there a way to make Python tell me the name of the missing DLL dependency?

答:
Yes. Run the script_name.py from the shell, (cmd.exe or powershell in Windows) and read the error message(s). The error will show which dependency is missing.

You may need to repeat this process several times, if you are missing more than one.

Any IDE, including IDLE will display an error message in a window, buried in the error message is the name of the missing file.

Body:
When importing a DLL module into Python, sometimes I will get:

ImportError: DLL load failed: The specified module could not be found.

The problem is often:

Missing DLL dependency (commonly a Visual Studio runtime DLL)

DLL or dependency compiled for 32 bit when should be 64 bit

Dependency walker answers this question sometimes. But, sometimes it doesn't, particularly if the issue is a missing Visual Studio runtime DLL.

Is there a way to make Python tell me the name of the missing DLL dependency?


问:
I think my code is all correct but it does not work
I coded this to show me this:

1  + (1/2!) + (1/3!) + … + (1/n!)

  if ( n < 10 )

```<code>#include <iostream>
using namespace std;
int main() {
int n;
float factn=1,m,sum;
cout<<"enter n\n";
cin>>n;
if(n<10&&n>=0){
do{
        factn=factn*n;
        m=1/factn;
        sum=sum+m;
        n--;
    }while(n>=1);
        cout<<sum;
}
else{
    cout<<"error!\n";
}
return 0;

}
</code>```

This code must show this:

( n < 10 )      1  + (1/2!) + (1/3!) + … + (1/n!)

What is the problem?

It returns wrong values :(

答:
There are two problems in the code. First, sum is not initialized, so whatever result comes out won't have any meaning. Second, the loop goes the wrong way. To calculate successive factorials it has to start with 1, then move to 2, then 3, etc.; this loop starts at n, then moves to n-1, then n-2, etc. Change that do... while loop to look like this:

```<code>for (int i = 0; i < n; ++i) {
    // do the calculation for i
}
</code>```

Body:
I coded this to show me this:

1  + (1/2!) + (1/3!) + … + (1/n!)

  if ( n < 10 )

#include <iostream>
using namespace std;
int main() {
int n;
float factn=1,m,sum;
cout<<"enter n\n";
cin>>n;
if(n<10&&n>=0){
do{
        factn=factn*n;
        m=1/factn;
        sum=sum+m;
        n--;
    }while(n>=1);
        cout<<sum;
}
else{
    cout<<"error!\n";
}
return 0;

}

This code must show this:

( n < 10 )      1  + (1/2!) + (1/3!) + … + (1/n!)

What is the problem?

It returns wrong values :(

Body:
There are two problems in the code. First, sum is not initialized, so whatever result comes out won't have any meaning. Second, the loop goes the wrong way. To calculate successive factorials it has to start with 1, then move to 2, then 3, etc.; this loop starts at n, then moves to n-1, then n-2, etc. Change that do... while loop to look like this:

for (int i = 0; i < n; ++i) {
    // do the calculation for i
}


问:
Getting file resource from Jar in Hadoop
I am trying to run a Hadoop application from a jar:

```<code>hadoop jar myJarFile.jar my.class.path.Here /path/to/input /path/to/output
</code>```

In one of the classes in myJarFile.jar, I am attempting to read a resource from the classpath thus:

```<code>public void init() {
    Configuration conf  = new Configuration();
    conf.addResource("resources/myConf.xml");
    log.info("Data element=" + conf.get("data.element"));
    ....
</code>```

In myJarFile.jar, resource/myConf exists:

```<code>[prompt] jar myJarFile.jar
my/class/path/Here.class
...
resources/myConf.xml
</code>```

and the configuration file contains the name/value pair in the proper (Hadoop-style) format. However, whenever I try to run this, it fails to find the myConf.xml file, even though it should be on the classpath.

What am I missing?

答:
I am assuming that the init method belongs to either mapper or reducer class. JVM executing these classes are not the same JVM as driver program and potentially on different machine altogether. So you cannot read local file system from those classes.

You have two options to read this file.

Option 1 (preferred) Use Distributed cache like this:

```<code>JobConf job = new JobConf();
 DistributedCache.addCacheFile(new URI("resources/myConf.xml"),
                               job);
</code>```

Now this file you can use in mapper or reducer init method like this:

```<code>File f = new File("./myConf.xml");
</code>```

Option 2 (not preferred) : Upload file in HDFS and read using HDFS java client api.

```<code> Path pt=new Path("hdfs://<hdfs hostname>:9000/user/john/myConf.xml");
                    FileSystem fs = FileSystem.get(new Configuration());
                    BufferedReader br=new BufferedReader(new InputStreamReader(fs.open(pt)));
</code>```

The reason why this option is not preferred is because for each record that you are mapping or reducing, you are reading data from hdfs so you will have major performance issues.

Body:
I am trying to run a Hadoop application from a jar:

hadoop jar myJarFile.jar my.class.path.Here /path/to/input /path/to/output

In one of the classes in myJarFile.jar, I am attempting to read a resource from the classpath thus:

public void init() {
    Configuration conf  = new Configuration();
    conf.addResource("resources/myConf.xml");
    log.info("Data element=" + conf.get("data.element"));
    ....

In myJarFile.jar, resource/myConf exists:

[prompt] jar myJarFile.jar
my/class/path/Here.class
...
resources/myConf.xml

and the configuration file contains the name/value pair in the proper (Hadoop-style) format. However, whenever I try to run this, it fails to find the myConf.xml file, even though it should be on the classpath.

What am I missing?

Body:
I am assuming that the init method belongs to either mapper or reducer class. JVM executing these classes are not the same JVM as driver program and potentially on different machine altogether. So you cannot read local file system from those classes.

You have two options to read this file.

Option 1 (preferred) Use Distributed cache like this:

JobConf job = new JobConf();
 DistributedCache.addCacheFile(new URI("resources/myConf.xml"),
                               job);

Now this file you can use in mapper or reducer init method like this:

File f = new File("./myConf.xml");

Option 2 (not preferred) : Upload file in HDFS and read using HDFS java client api.

 Path pt=new Path("hdfs://<hdfs hostname>:9000/user/john/myConf.xml");
                    FileSystem fs = FileSystem.get(new Configuration());
                    BufferedReader br=new BufferedReader(new InputStreamReader(fs.open(pt)));

The reason why this option is not preferred is because for each record that you are mapping or reducing, you are reading data from hdfs so you will have major performance issues.


问:
PowerBI and Azure AD Headless Login
I am trying to embed PowerBI dashboards into my customer MVC portal.  My customers don't have AAD accounts, so they can't login to Live when they come to the website, they log into my MVC website with individual authority.

I have registered my App on PowerBI/AAD and have the ClientID and Secret.  I make the call to AAD and get an Authorization Code which I then use to get an Athentication Token which the is returned successfully.

When ever I use the access token to get a dashboard it is continually rejected with a 403 Forbidden.

I have gone through all the samples from Microsoft, but they require a user login prompt.  I have reviewed the ADAL2.0 code which refers to the AcquireToken Method, but this was deprecated in ADAL3 and replaced with AcquireTokenAsync which has different parameters and I am using this in my example below.

Here is the function to get the token:

```<code>    protected AuthenticationResult GetAccessToken()
    {
        string pBiUser = Properties.Settings.Default.PowerBIUser;
        string pBiPwd = Properties.Settings.Default.PowerBIPwd;
        string pBiClientId = Properties.Settings.Default.PowerBIClientId;
        string pBiSecret = Properties.Settings.Default.PowerBIClientSecret;
        TokenCache TC = new TokenCache();
        ClientCredential CC = new ClientCredential(pBiClientId,pBiSecret);
        string AU = Properties.Settings.Default.PowerBIAuthority;
        Microsoft.IdentityModel.Clients.ActiveDirectory.AuthenticationContext authenticationContext
            = new Microsoft.IdentityModel.Clients.ActiveDirectory.AuthenticationContext(AU, TC);
        AuthenticationResult result = authenticationContext.AcquireTokenAsync("https://analysis.windows.net/powerbi/api"
            ,CC).Result;

        if (result == null)
        {
            throw new InvalidOperationException("Failed to obtain the PowerBI token");
        }

        return result;
    }
</code>```

I then take the result token and call.  The response receives the 403:

```<code>    protected PBIDashboards GetDashboards(AuthenticationResult authResult)
    {
        PBIDashboards pbiDashboards = new PBIDashboards();
        var baseAddress = new Uri("https://api.powerbi.com");
        using (var httpClient = new System.Net.Http.HttpClient {BaseAddress = baseAddress})
        {
            httpClient.DefaultRequestHeaders.TryAddWithoutValidation("authorization",
                "Bearer " + authResult.AccessToken);
            using (**var response** = httpClient.GetAsync("v1.0/myorg/dashboards").Result)
            {
                string responseData = response.Content.ReadAsStringAsync().Result;

                //Deserialize JSON string
                pbiDashboards = JsonConvert.DeserializeObject<PBIDashboards>(responseData);

                if (pbiDashboards != null)
                {
                    var gridViewDashboards = pbiDashboards.value.Select(dashboard => new
                    {
                        Id = dashboard.id,
                        DisplayName = dashboard.displayName,
                        EmbedUrl = dashboard.embedUrl
                    });
                }
            }
        }
        return pbiDashboards;
    }
</code>```

答:
After a lot of research, you can make a direct AJAX call to get the token:

```<code>    private async Task<string> GetAccessToken()
    {
        string pBiUser = Properties.Settings.Default.PowerBIUser;
        string pBiPwd = Properties.Settings.Default.PowerBIPwd;
        string pBiClientId = Properties.Settings.Default.PowerBIClientId;
        string pBiSecret = Properties.Settings.Default.PowerBIClientSecret;
        string pBITenant = Properties.Settings.Default.PowerBITenantId;

        string tokenEndpointUri = "https://login.microsoftonline.com/"+pBITenant+"/oauth2/token";

        var content = new FormUrlEncodedContent(new[]
            {
        new KeyValuePair<string, string>("grant_type", "password"),
        new KeyValuePair<string, string>("username", pBiUser),
        new KeyValuePair<string, string>("password", pBiPwd),
        new KeyValuePair<string, string>("client_id", pBiClientId),
        new KeyValuePair<string, string>("client_secret", pBiSecret),
        new KeyValuePair<string, string>("resource", "https://analysis.windows.net/powerbi/api")
        });

        using (var client = new HttpClient())
        {
            HttpResponseMessage res = client.PostAsync(tokenEndpointUri, content).Result;

            string json = await res.Content.ReadAsStringAsync();

            AzureAdTokenResponse tokenRes = JsonConvert.DeserializeObject<AzureAdTokenResponse>(json);

            return tokenRes.AccessToken;
        }
    }
</code>```

Once you have the string AccessToken, you can then call the Dashboards request.

```<code>protected PBIDashboards GetDashboards(string token)
    {
        PBIDashboards pbiDashboards = new PBIDashboards();
        var baseAddress = new Uri("https://api.powerbi.com");
        using (var httpClient = new System.Net.Http.HttpClient {BaseAddress = baseAddress})
        {
            httpClient.DefaultRequestHeaders.TryAddWithoutValidation("authorization",
                "Bearer " + token);
            using (var response = httpClient.GetAsync("v1.0/myorg/dashboards").Result)
            {
                string responseData = response.Content.ReadAsStringAsync().Result;

                //Deserialize JSON string
                pbiDashboards = JsonConvert.DeserializeObject<PBIDashboards>(responseData);

                if (pbiDashboards != null)
                {
                    var gridViewDashboards = pbiDashboards.value.Select(dashboard => new
                    {
                        Id = dashboard.id,
                        DisplayName = dashboard.displayName,
                        EmbedUrl = dashboard.embedUrl
                    });
                }
            }
        }
        return pbiDashboards;
    }
</code>```

This will provide you the list of dashboards and the dashboard Id to call the PowerBI API to build the embeded page in Javascript.  I used hidden input fields to store the access token and embed URL to pass over to the Javascript call.

```<code>// check if the embed url was selected
var embedUrl = document.getElementById('embed').value;
if (embedUrl === "")
    return;

// get the access token.
accessToken = document.getElementById('token').value;

// Embed configuration used to describe the what and how to embed.
// This object is used when calling powerbi.embed.
// You can find more information at https://github.com/Microsoft/PowerBI-JavaScript/wiki/Embed-Configuration-Details.
var config = {
    type: 'dashboard',
    accessToken: accessToken,
    embedUrl: embedUrl
};

// Grab the reference to the div HTML element that will host the dashboard.
var dashboardContainer = document.getElementById('dashboard');

// Embed the dashboard and display it within the div container.
var dashboard = powerbi.embed(dashboardContainer, config);
</code>```

Title: PowerBI and Azure AD Headless Login

Body:
I am trying to embed PowerBI dashboards into my customer MVC portal.  My customers don't have AAD accounts, so they can't login to Live when they come to the website, they log into my MVC website with individual authority.

I have registered my App on PowerBI/AAD and have the ClientID and Secret.  I make the call to AAD and get an Authorization Code which I then use to get an Athentication Token which the is returned successfully.

When ever I use the access token to get a dashboard it is continually rejected with a 403 Forbidden.

I have gone through all the samples from Microsoft, but they require a user login prompt.  I have reviewed the ADAL2.0 code which refers to the AcquireToken Method, but this was deprecated in ADAL3 and replaced with AcquireTokenAsync which has different parameters and I am using this in my example below.

Here is the function to get the token:

    protected AuthenticationResult GetAccessToken()
    {
        string pBiUser = Properties.Settings.Default.PowerBIUser;
        string pBiPwd = Properties.Settings.Default.PowerBIPwd;
        string pBiClientId = Properties.Settings.Default.PowerBIClientId;
        string pBiSecret = Properties.Settings.Default.PowerBIClientSecret;
        TokenCache TC = new TokenCache();
        ClientCredential CC = new ClientCredential(pBiClientId,pBiSecret);
        string AU = Properties.Settings.Default.PowerBIAuthority;
        Microsoft.IdentityModel.Clients.ActiveDirectory.AuthenticationContext authenticationContext
            = new Microsoft.IdentityModel.Clients.ActiveDirectory.AuthenticationContext(AU, TC);
        AuthenticationResult result = authenticationContext.AcquireTokenAsync("https://analysis.windows.net/powerbi/api"
            ,CC).Result;

        if (result == null)
        {
            throw new InvalidOperationException("Failed to obtain the PowerBI token");
        }

        return result;
    }

I then take the result token and call.  The response receives the 403:

    protected PBIDashboards GetDashboards(AuthenticationResult authResult)
    {
        PBIDashboards pbiDashboards = new PBIDashboards();
        var baseAddress = new Uri("https://api.powerbi.com");
        using (var httpClient = new System.Net.Http.HttpClient {BaseAddress = baseAddress})
        {
            httpClient.DefaultRequestHeaders.TryAddWithoutValidation("authorization",
                "Bearer " + authResult.AccessToken);
            using (**var response** = httpClient.GetAsync("v1.0/myorg/dashboards").Result)
            {
                string responseData = response.Content.ReadAsStringAsync().Result;

                //Deserialize JSON string
                pbiDashboards = JsonConvert.DeserializeObject<PBIDashboards>(responseData);

                if (pbiDashboards != null)
                {
                    var gridViewDashboards = pbiDashboards.value.Select(dashboard => new
                    {
                        Id = dashboard.id,
                        DisplayName = dashboard.displayName,
                        EmbedUrl = dashboard.embedUrl
                    });
                }
            }
        }
        return pbiDashboards;
    }

Body:
After a lot of research, you can make a direct AJAX call to get the token:

    private async Task<string> GetAccessToken()
    {
        string pBiUser = Properties.Settings.Default.PowerBIUser;
        string pBiPwd = Properties.Settings.Default.PowerBIPwd;
        string pBiClientId = Properties.Settings.Default.PowerBIClientId;
        string pBiSecret = Properties.Settings.Default.PowerBIClientSecret;
        string pBITenant = Properties.Settings.Default.PowerBITenantId;

        string tokenEndpointUri = "https://login.microsoftonline.com/"+pBITenant+"/oauth2/token";

        var content = new FormUrlEncodedContent(new[]
            {
        new KeyValuePair<string, string>("grant_type", "password"),
        new KeyValuePair<string, string>("username", pBiUser),
        new KeyValuePair<string, string>("password", pBiPwd),
        new KeyValuePair<string, string>("client_id", pBiClientId),
        new KeyValuePair<string, string>("client_secret", pBiSecret),
        new KeyValuePair<string, string>("resource", "https://analysis.windows.net/powerbi/api")
        });

        using (var client = new HttpClient())
        {
            HttpResponseMessage res = client.PostAsync(tokenEndpointUri, content).Result;

            string json = await res.Content.ReadAsStringAsync();

            AzureAdTokenResponse tokenRes = JsonConvert.DeserializeObject<AzureAdTokenResponse>(json);

            return tokenRes.AccessToken;
        }
    }

Once you have the string AccessToken, you can then call the Dashboards request.

protected PBIDashboards GetDashboards(string token)
    {
        PBIDashboards pbiDashboards = new PBIDashboards();
        var baseAddress = new Uri("https://api.powerbi.com");
        using (var httpClient = new System.Net.Http.HttpClient {BaseAddress = baseAddress})
        {
            httpClient.DefaultRequestHeaders.TryAddWithoutValidation("authorization",
                "Bearer " + token);
            using (var response = httpClient.GetAsync("v1.0/myorg/dashboards").Result)
            {
                string responseData = response.Content.ReadAsStringAsync().Result;

                //Deserialize JSON string
                pbiDashboards = JsonConvert.DeserializeObject<PBIDashboards>(responseData);

                if (pbiDashboards != null)
                {
                    var gridViewDashboards = pbiDashboards.value.Select(dashboard => new
                    {
                        Id = dashboard.id,
                        DisplayName = dashboard.displayName,
                        EmbedUrl = dashboard.embedUrl
                    });
                }
            }
        }
        return pbiDashboards;
    }

This will provide you the list of dashboards and the dashboard Id to call the PowerBI API to build the embeded page in Javascript.  I used hidden input fields to store the access token and embed URL to pass over to the Javascript call.

// check if the embed url was selected
var embedUrl = document.getElementById('embed').value;
if (embedUrl === "")
    return;

// get the access token.
accessToken = document.getElementById('token').value;

// Embed configuration used to describe the what and how to embed.
// This object is used when calling powerbi.embed.
// You can find more information at https://github.com/Microsoft/PowerBI-JavaScript/wiki/Embed-Configuration-Details.
var config = {
    type: 'dashboard',
    accessToken: accessToken,
    embedUrl: embedUrl
};

// Grab the reference to the div HTML element that will host the dashboard.
var dashboardContainer = document.getElementById('dashboard');

// Embed the dashboard and display it within the div container.
var dashboard = powerbi.embed(dashboardContainer, config);


问:
How update UI when AsyncTask.onProgressUpdate() finish?
When open Activity I start long (10 sek) process. This process create list of 10 items. And finish after 10 sec. As result the list show (UI update) AFTER 10 seconds.

But I need to show every item right after it create. So, first item must show after 1 second.

So I create AsyncTask for this:

```<code>onCreate() {
 BackgroundTask  backgroundTask  = new BackgroundTask ();
   backgroundTask.execute(newsDetailsList);
}

    private class BackgroundTask  extends AsyncTask<List<NewsDetails>, NewsDetails, Void> {

        @Override
        protected Void doInBackground(List<NewsDetails>... newsDetailsList) {
            List<NewsDetails> passedList = newsDetailsList[0];
            for (NewsDetails newsDetails : passedList) {
                publishProgress(newsDetails);
            }
            return null;
        }

        @Override
        protected void onProgressUpdate(final NewsDetails... passedNewsDetails) {
           super.onProgressUpdate(passedNewsDetails);
           final NewsDetails newsDetails = passedNewsDetails[0];
          // here create UI for new items newsDetails
        }

        @Override
        protected void onPostExecute(Void result) {
            super.onPostExecute(result);
        }
}
</code>```

But UI is updated AFTER onPostExecute() finish (after 10 SECONDS). But I need to update UI after every finish (10 times) method onProgressUpdate().

How I can do this?

答:
create a new class:

```<code>public interface NewsDetailsInterface{
void receiveData(Object object);
}
</code>```

then change your ASyncTask to abstract and implement the interface:

```<code>private abstract class BackgroundTask  extends AsyncTask<List<NewsDetails>,
NewsDetails, Void> implements NewsDetailsInterface{

public abstract receiveData(Object object);

//.. the rest of your task below ..
</code>```

then wherever you are instantiating the ASyncTask, you'll need to recreate it to look like this:

```<code>BackgroundTask  backgroundTask  = new BackgroundTask (){
            @Override
            public void receiveData(Object object) {
                 //do something with the object, like create a new list item
            }
       };
</code>```

now, you can call receiveData every 1 second with your doInBackground, everytime it is called, your interface will do something with that data immediately:

```<code>@Override
    protected Void doInBackground(List<NewsDetails>... newsDetailsList) {
        List<NewsDetails> passedList = newsDetailsList[0];
        for (NewsDetails newsDetails : passedList) {
            receiveData(newsDetails);
        }
        return null;
    }
</code>```

Body:
When open Activity I start long (10 sek) process. This process create list of 10 items. And finish after 10 sec. As result the list show (UI update) AFTER 10 seconds.

But I need to show every item right after it create. So, first item must show after 1 second.

So I create AsyncTask for this:

onCreate() {
 BackgroundTask  backgroundTask  = new BackgroundTask ();
   backgroundTask.execute(newsDetailsList);
}

    private class BackgroundTask  extends AsyncTask<List<NewsDetails>, NewsDetails, Void> {

        @Override
        protected Void doInBackground(List<NewsDetails>... newsDetailsList) {
            List<NewsDetails> passedList = newsDetailsList[0];
            for (NewsDetails newsDetails : passedList) {
                publishProgress(newsDetails);
            }
            return null;
        }

        @Override
        protected void onProgressUpdate(final NewsDetails... passedNewsDetails) {
           super.onProgressUpdate(passedNewsDetails);
           final NewsDetails newsDetails = passedNewsDetails[0];
          // here create UI for new items newsDetails
        }

        @Override
        protected void onPostExecute(Void result) {
            super.onPostExecute(result);
        }
}

But UI is updated AFTER onPostExecute() finish (after 10 SECONDS). But I need to update UI after every finish (10 times) method onProgressUpdate().

How I can do this?

Body:
create a new class:

public interface NewsDetailsInterface{
void receiveData(Object object);
}

then change your ASyncTask to abstract and implement the interface:

private abstract class BackgroundTask  extends AsyncTask<List<NewsDetails>,
NewsDetails, Void> implements NewsDetailsInterface{

public abstract receiveData(Object object);

//.. the rest of your task below ..

then wherever you are instantiating the ASyncTask, you'll need to recreate it to look like this:

BackgroundTask  backgroundTask  = new BackgroundTask (){
            @Override
            public void receiveData(Object object) {
                 //do something with the object, like create a new list item
            }
       };

now, you can call receiveData every 1 second with your doInBackground, everytime it is called, your interface will do something with that data immediately:

@Override
    protected Void doInBackground(List<NewsDetails>... newsDetailsList) {
        List<NewsDetails> passedList = newsDetailsList[0];
        for (NewsDetails newsDetails : passedList) {
            receiveData(newsDetails);
        }
        return null;
    }


问:
making a loop to display buttons
I am trying to make a loop that will display some images and add an event listener to each image which, when clicked will assign the appropriate value to humanGoal. I have:

```<code>var humanGoal;

function displayPicker(round){
    for(var i = 0; i <= round; i++){
        document.write('<img src=img/die' + i + '.png id="' + 'picker' + i + '">');
        document.getElementById('picker'+i).addEventListener("click", function () {
            humanGoal = i;
            document.write('you picked ' + humanGoal );
        });
    }
}
</code>```

why does humanGoal always === round+1, instead of the variable i from the for loop?

答:
The humanGoal variable is being overwrited with every for loop iteration and holds the round + 1 value at the end. Different words speaking - it will always display a wrong index.

Solution: apply same class to the each img element, bind a click event listener and display the actual index by passing i variable inside the Array#forEach function.

function displayPicker(round){
    for (var i = 0; i <= round; i++){
      document.write('');
    }
    var elems = document.getElementsByClassName('img');
        Array.from(elems).forEach((v,i) => v.addEventListener('click', function() {
          console.log(`You picked ${i}`);
        }));
}

displayPicker(5);```

Title: making a loop to display buttons

Body:
I am trying to make a loop that will display some images and add an event listener to each image which, when clicked will assign the appropriate value to humanGoal. I have:

var humanGoal;

function displayPicker(round){
    for(var i = 0; i <= round; i++){
        document.write('');
        document.getElementById('picker'+i).addEventListener("click", function () {
            humanGoal = i;
            document.write('you picked ' + humanGoal );
        });
    }
}

why does humanGoal always === round+1, instead of the variable i from the for loop?

Body:
The humanGoal variable is being overwrited with every for loop iteration and holds the round + 1 value at the end. Different words speaking - it will always display a wrong index.

Solution: apply same class to the each img element, bind a click event listener and display the actual index by passing i variable inside the Array#forEach function.

function displayPicker(round){
    for (var i = 0; i <= round; i++){
      document.write('<img src=img/die' + i + '.png id="' + 'picker' + i + '" class="img">');
    }
    var elems = document.getElementsByClassName('img');
        Array.from(elems).forEach((v,i) => v.addEventListener('click', function() {
          console.log(`You picked ${i}`);
        }));
}

displayPicker(5);


问:
How can I get the updated price from this site?
So I am making a basic finance site as a project but I can't figure out how to get the new price after I get the original price and do stuff based on the new price.

Here's what I have now

```<code>function getPrice() {
    $.ajax({
        url: 'http://finance.google.com/finance/info?client=ig&q=' + $("#stock").val(),
        dataType: 'jsonp',
        success: function(json) {
            $("#stockprice").html(json[0]['l']);
        }
    });
}

$("#getstock").click(getPrice);
</code>```

I just need to get the updated price, then I'll go from there.

For example, if the user types in 'AMD' then the JSON would look like this

```<code>// [ { "id": "327" ,"t" : "AMD" ,"e" : "NASDAQ" ,"l" : "13.74" ,"l_fix" : "13.74" ,"l_cur" : "13.74" ,"s": "0" ,"ltt":"3:04PM EDT" ,"lt" : "Mar 29, 3:04PM EDT" ,"lt_dts" : "2017-03-29T15:04:22Z" ,"c" : "+0.05" ,"c_fix" : "0.05" ,"cp" : "0.37" ,"cp_fix" : "0.37" ,"ccol" : "chg" ,"pcls_fix" : "13.69" } ]
</code>```

答:
Use setInterval() to poll the server for a new price.

This will check it every 5000ms (5 seconds):

```<code>setInterval(getPrice, 5000);
</code>```

Snippet:

function getPrice() {
  if($('#stock').val()) {
    $.ajax({
      url: 'https://finance.google.com/finance/info?client=ig&q=' + $("#stock").val(),
      dataType: 'jsonp',
      success: function(json) {
        $("#stockprice").html(json[0]['l']);
        //do something with the new price
      }
    });
  }
}

getPrice();
setInterval(getPrice, 5000);
$('#stock').change(getPrice);  //get new price immediately when the input has changed```
<pre class="snippet-code-html lang-html prettyprint-override"><code><script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<input type="text" id="stock">
<div id="stockprice"></div></code>```

Body:
So I am making a basic finance site as a project but I can't figure out how to get the new price after I get the original price and do stuff based on the new price.

Here's what I have now

function getPrice() {
    $.ajax({
        url: 'http://finance.google.com/finance/info?client=ig&q=' + $("#stock").val(),
        dataType: 'jsonp',
        success: function(json) {
            $("#stockprice").html(json[0]['l']);
        }
    });
}

$("#getstock").click(getPrice);

I just need to get the updated price, then I'll go from there.

For example, if the user types in 'AMD' then the JSON would look like this

// [ { "id": "327" ,"t" : "AMD" ,"e" : "NASDAQ" ,"l" : "13.74" ,"l_fix" : "13.74" ,"l_cur" : "13.74" ,"s": "0" ,"ltt":"3:04PM EDT" ,"lt" : "Mar 29, 3:04PM EDT" ,"lt_dts" : "2017-03-29T15:04:22Z" ,"c" : "+0.05" ,"c_fix" : "0.05" ,"cp" : "0.37" ,"cp_fix" : "0.37" ,"ccol" : "chg" ,"pcls_fix" : "13.69" } ]

Body:
Use setInterval() to poll the server for a new price.

This will check it every 5000ms (5 seconds):

setInterval(getPrice, 5000);

Snippet:

function getPrice() {
  if($('#stock').val()) {
    $.ajax({
      url: 'https://finance.google.com/finance/info?client=ig&q=' + $("#stock").val(),
      dataType: 'jsonp',
      success: function(json) {
        $("#stockprice").html(json[0]['l']);
        //do something with the new price
      }
    });
  }
}

getPrice();
setInterval(getPrice, 5000);
$('#stock').change(getPrice);  //get new price immediately when the input has changed

<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<input type="text" id="stock">
<div id="stockprice"></div>


问:
How do you manage the namespaces of your extension methods?
Do you use a global, catchall namespace for all of your extension methods, or do you put the extension methods in the same namespace as the class(es) they extend?

Or do you use some other method, like an application or library-specific namespace?

I ask because I have a need to extend System.Security.Principal.IIdentity, and putting the extension method in the System.Security.Principal namespace seems to make sense, but I've never seen it done this way.

答:
If you put them in a higher namespace than your current, they will be visible automatically.

So if you have namespaces for projects like:

```<code>AdventureWorksInc.Web
AdventureWorksInc.Logic
AdventureWorksInc.DataAccess
</code>```

Then declare your extension directly in:

```<code>namespace AdventureWorksInc
{
   public static class HtmlHelpers
   {
       public static string AutoCloseHtmlTags(this string html)
       {
           //...
       }

   }
}
</code>```

This extension method will show up whenever you are writing code in any sub name space of AdventureWorksInc without the need for a using statement.

However, the above extension demonstrates a possible downside.  Due to the fact that it operates on strings, it will now show up as an extension method for all strings, including those that aren't really HTML. This is actually not an issue with namespace scoping, but simply a misuse of an extension method.  This should be a regular static that requires a standard parameter so the call is explicit.

Generally well designed extension methods with appropriately typed parameters will not show up on types that it would never apply.

ContentLicense: CC BY-SA 2.5

Body:
If you put them in a higher namespace than your current, they will be visible automatically.

So if you have namespaces for projects like:

AdventureWorksInc.Web
AdventureWorksInc.Logic
AdventureWorksInc.DataAccess

Then declare your extension directly in:

namespace AdventureWorksInc
{
   public static class HtmlHelpers
   {
       public static string AutoCloseHtmlTags(this string html)
       {
           //...
       }

   }
}

This extension method will show up whenever you are writing code in any sub name space of AdventureWorksInc without the need for a using statement.

However, the above extension demonstrates a possible downside.  Due to the fact that it operates on strings, it will now show up as an extension method for all strings, including those that aren't really HTML. This is actually not an issue with namespace scoping, but simply a misuse of an extension method.  This should be a regular static that requires a standard parameter so the call is explicit.

Generally well designed extension methods with appropriately typed parameters will not show up on types that it would never apply.


问:
Creating multiple column dimension from csv
I'm trying to make a pie chart using multiple columns from a csv file, I can produce a pie chart but it only use the last value d.gre. What am I doing wrong?

Code is below

```<code>d3.csv("elecVotes.csv", function (data) {

var ndx = crossfilter(data);
var partysDim = ndx.dimension(function(d) { return +d.rep, +d.dem, +d.lib, +d.ind, +d.gre;})
var partys = partysDim.group();

var pie = dc.pieChart('#chart-pie');

pie
    .width(180)
    .height(180)
    .radius(80)
    .dimension(partysDim)
    .group(partys)
    .renderLabel(true)
    .innerRadius(10)
    .transitionDuration(500)
    .colorAccessor(function (d, i) { return d.value; });

    dc.renderAll();
});
</code>```

electVotes.csv

state, rep,dem,lib,ind,gre
Alabama,1314431,725704,44211,20276,9341
New York,5655,54444,65666,2355,12225
Texas,4355,543234,12321,12331,45644

答:
There are a couple of problems here. On the JavaScript level, the comma "operator" just evaluates both sides of the comma and returns the second. So the value of

```<code>1,2,3,4,5
</code>```

is just 5. So that explains the result you're currently getting.

The other problem is more conceptual. Crossfilter is not designed to display each column in a group. I think the main reason is that there would be no way to filter by political party, since each region or state has values for every party. You would need data at the voter level to filter by party.

Given that restriction, you definitely won't be able to filter by clicking on the pie chart. However, with a little work, you can have the pie chart display the column sums as bins of a group.

As Ethan says, maybe it's better to transform your data, but this answer shows how to produce a group which rotates the data on the fly.

Body:
I'm trying to make a pie chart using multiple columns from a csv file, I can produce a pie chart but it only use the last value d.gre. What am I doing wrong?

Code is below

d3.csv("elecVotes.csv", function (data) {

var ndx = crossfilter(data);
var partysDim = ndx.dimension(function(d) { return +d.rep, +d.dem, +d.lib, +d.ind, +d.gre;})
var partys = partysDim.group();

var pie = dc.pieChart('#chart-pie');

pie
    .width(180)
    .height(180)
    .radius(80)
    .dimension(partysDim)
    .group(partys)
    .renderLabel(true)
    .innerRadius(10)
    .transitionDuration(500)
    .colorAccessor(function (d, i) { return d.value; });

    dc.renderAll();
});

electVotes.csv

state, rep,dem,lib,ind,gre
Alabama,1314431,725704,44211,20276,9341
New York,5655,54444,65666,2355,12225
Texas,4355,543234,12321,12331,45644

Body:
There are a couple of problems here. On the JavaScript level, the comma "operator" just evaluates both sides of the comma and returns the second. So the value of

1,2,3,4,5

is just 5. So that explains the result you're currently getting.

The other problem is more conceptual. Crossfilter is not designed to display each column in a group. I think the main reason is that there would be no way to filter by political party, since each region or state has values for every party. You would need data at the voter level to filter by party.

Given that restriction, you definitely won't be able to filter by clicking on the pie chart. However, with a little work, you can have the pie chart display the column sums as bins of a group.

As Ethan says, maybe it's better to transform your data, but this answer shows how to produce a group which rotates the data on the fly.


问:
Best method for dynamically building URL with Flask url_for
I have to create an URL in JavaScript with url_for because I should use whole table row as a link which i cannot do it in HTML. Sample below:

```<code>{% for x in last_orders %}
<tr id="x">
    <td>something here</td>
    <td>something here</td>
</tr>
{% endfor %}
</code>```

And Flask:

```<code>@app.route("/some/page/<int:id>/", methods=['POST', 'GET'])
def xxx_page(id):
</code>```

I can make table row like a link by using Jquery function .click() but with this method I cannot use url_for in proper way.

I saw in another topic that I can send variables with Post but I dont want to change my URL system because this is more user friendly.

Maybe I can create dummy URL with url_for (/some/page/0) and then change that string with JavaScript but I am not sure this method is the best.

Edit: My method is like this:

```<code>$(".row").click(function() {
    var id = $(this).attr("id");
    var where = `{{ url_for('xxx_page', id=0) }}`;
    where = where.slice(0,-2).concat(id + "/");
    window.location = where;
  });
</code>```

答:
If the elements of last_orders contain the prefix used in the xxx_page function(s), then you can just make an a tag within the td.

```<code><td><a href={{ url_for('{}_page'.format(x)) }}>something here</a></td>
</code>```

EDIT: After rereading your question, you're looking to make the entire cell clickable. There are a couple options in JavaScript. You can listen to clicks on all the td elements, and then trigger a click on their child a.

```<code># Don't actually use an anonymous function. Define it elsewhere.
$('body').off('click.order')
    .on('click.order', 'td', function(e) {
        $(this).find('a').trigger('click');
    });
</code>```

OR (and I like this option much less than the first one) you could set a data element on the td elements with the address.

```<code><td data-url='{{ url_for('{}_page'.format(x)) }}'>something here</td>
</code>```

Then in your click listener, do this.

```<code>window.location.href = $(this).attr('data-url');
</code>```

Body:
I have to create an URL in JavaScript with url_for because I should use whole table row as a link which i cannot do it in HTML. Sample below:

{% for x in last_orders %}

    something here
    something here

{% endfor %}

And Flask:

@app.route("/some/page/<int:id>/", methods=['POST', 'GET'])
def xxx_page(id):

I can make table row like a link by using Jquery function .click() but with this method I cannot use url_for in proper way.

I saw in another topic that I can send variables with Post but I dont want to change my URL system because this is more user friendly.

Maybe I can create dummy URL with url_for (/some/page/0) and then change that string with JavaScript but I am not sure this method is the best.

Edit: My method is like this:

$(".row").click(function() {
    var id = $(this).attr("id");
    var where = `{{ url_for('xxx_page', id=0) }}`;
    where = where.slice(0,-2).concat(id + "/");
    window.location = where;
  });

Body:
If the elements of last_orders contain the prefix used in the xxx_page function(s), then you can just make an a tag within the td.

<td><a href={{ url_for('{}_page'.format(x)) }}>something here</a></td>

EDIT: After rereading your question, you're looking to make the entire cell clickable. There are a couple options in JavaScript. You can listen to clicks on all the td elements, and then trigger a click on their child a.

# Don't actually use an anonymous function. Define it elsewhere.
$('body').off('click.order')
    .on('click.order', 'td', function(e) {
        $(this).find('a').trigger('click');
    });

OR (and I like this option much less than the first one) you could set a data element on the td elements with the address.

<td data-url='{{ url_for('{}_page'.format(x)) }}'>something here</td>

Then in your click listener, do this.

window.location.href = $(this).attr('data-url');


问:
Using antcontrib <if> task via maven-antrun-plugin
My maven java project uses the maven-antrun-plugin to execute a deploy.xml ant script that deploys my app. The deploy.xml uses the <if> task and this seems to be causing the problem;

[INFO] Executing tasks

[taskdef] Could not load definitions from resource net/sf/antcontrib/antlib.xml. It could not be found.

deploy:

[INFO] ------------------------------------------------------------------------

[ERROR] BUILD ERROR

[INFO] ------------------------------------------------------------------------

[INFO] An Ant BuildException has occured: The following error occurred while executing this line:

E:\My_Workspace\xxxxxx\xxxxxx\xxxxxxx\deploy.xml:24: Problem: failed to create task or type if

Cause: The name is undefined.

Action: Check the spelling.

Action: Check that any custom tasks/types have been declared.

Action: Check that any <presetdef>/<macrodef> declarations have taken place.

Here is the antrun plugin config from my pom;

```<code><plugin>
    <inherited>false</inherited>
    <groupId>org.apache.maven.plugins</groupId>
    <artifactId>maven-antrun-plugin</artifactId>
    <executions>
        <execution>
            <id>remote-deploy</id>
            <phase>install</phase>
            <configuration>
                <tasks>
                    <taskdef resource="net/sf/antcontrib/antcontrib.properties" classpathref="maven.plugin.classpath"/>

                        <property name="compile_classpath" refid="maven.compile.classpath" />
                        <property name="runtime_classpath" refid="maven.runtime.classpath" />
                        <property name="plugin_classpath" refid="maven.plugin.classpath" />

                        <echo message="compile classpath: ${compile_classpath}"/>
                        <echo message="runtime classpath: ${runtime_classpath}"/>
                        <echo message="plugin classpath: ${plugin_classpath}"/>

                        <ant antfile="${basedir}/deploy.xml">
                            <target name="deploy" />
                        </ant>
                </tasks>
            </configuration>
            <goals>
                <goal>run</goal>
            </goals>
        </execution>
    </executions>
    <dependencies>
        <dependency>
            <groupId>ant-contrib</groupId>
            <artifactId>ant-contrib</artifactId>
            <version>1.0b3</version>
        </dependency>
        <dependency>
            <groupId>org.apache.ant</groupId>
            <artifactId>ant</artifactId>
            <version>1.7.1</version>
        </dependency>
        <dependency>
            <groupId>org.apache.ant</groupId>
            <artifactId>ant-jsch</artifactId>
            <version>1.7.1</version>
        </dependency>
    </dependencies>
</plugin>
</code>```

.. and here is the relevant section from my deploy.xml;

```<code><target name="deploy" if="deploy">
    <if>    <!-- line 24 -->
        <and>
</code>```

Why I look in my maven repo I can see ant-contrib/ant-contrib/1.0b3/ant-contrib-1.0b3.jar and when I look inside the jar I can see net/sf/antcontrib/antcontrib.properties so no problem there.

When I check the values of maven.compile.classpath, maven.compile.classpath and maven.compile.classpath I can't see any reference to antcontrib, could this be the problem? Why don't they appear when antcontrib is defined as a dependancy?

答:
another solution would be: keep the ant-contrib-1.0b3.jar to a path and then define it like this

```<code><property name="runningLocation" location="" />
<taskdef resource="net/sf/antcontrib/antcontrib.properties">
    <classpath>
        <pathelement location="${runningLocation}/ant-contrib-1.0b3.jar" />
    </classpath>
</taskdef>
</code>```

then

```<code><target name="doSomething">
    <if>
        <equals arg1="${someProp}" arg2="YES" />
        <then>
            <echo message="It is YES" />
        </then>
        <else>
            <echo message="It is not YES" />
        </else>
    </if>
</target>
</code>```

I put full code example here which you can download https://www.surasint.com/run-ant-with-if-from-maven/

Body:
My maven java project uses the maven-antrun-plugin to execute a deploy.xml ant script that deploys my app. The deploy.xml uses the <if> task and this seems to be causing the problem;

[INFO] Executing tasks

[taskdef] Could not load definitions from resource net/sf/antcontrib/antlib.xml. It could not be found.

deploy:

[INFO] ------------------------------------------------------------------------

[ERROR] BUILD ERROR

[INFO] ------------------------------------------------------------------------

[INFO] An Ant BuildException has occured: The following error occurred while executing this line:

E:\My_Workspace\xxxxxx\xxxxxx\xxxxxxx\deploy.xml:24: Problem: failed to create task or type if

Cause: The name is undefined.

Action: Check the spelling.

Action: Check that any custom tasks/types have been declared.

Action: Check that any <presetdef>/<macrodef> declarations have taken place.

Here is the antrun plugin config from my pom;

<plugin>
    <inherited>false</inherited>
    <groupId>org.apache.maven.plugins</groupId>
    <artifactId>maven-antrun-plugin</artifactId>
    <executions>
        <execution>
            <id>remote-deploy</id>
            <phase>install</phase>
            <configuration>
                <tasks>
                    <taskdef resource="net/sf/antcontrib/antcontrib.properties" classpathref="maven.plugin.classpath"/>

                        <property name="compile_classpath" refid="maven.compile.classpath" />
                        <property name="runtime_classpath" refid="maven.runtime.classpath" />
                        <property name="plugin_classpath" refid="maven.plugin.classpath" />

                        <echo message="compile classpath: ${compile_classpath}"/>
                        <echo message="runtime classpath: ${runtime_classpath}"/>
                        <echo message="plugin classpath: ${plugin_classpath}"/>

                        <ant antfile="${basedir}/deploy.xml">
                            <target name="deploy" />
                        </ant>
                </tasks>
            </configuration>
            <goals>
                <goal>run</goal>
            </goals>
        </execution>
    </executions>
    <dependencies>
        <dependency>
            <groupId>ant-contrib</groupId>
            <artifactId>ant-contrib</artifactId>
            <version>1.0b3</version>
        </dependency>
        <dependency>
            <groupId>org.apache.ant</groupId>
            <artifactId>ant</artifactId>
            <version>1.7.1</version>
        </dependency>
        <dependency>
            <groupId>org.apache.ant</groupId>
            <artifactId>ant-jsch</artifactId>
            <version>1.7.1</version>
        </dependency>
    </dependencies>
</plugin>

.. and here is the relevant section from my deploy.xml;

<target name="deploy" if="deploy">
    <if>
        <and>

Why I look in my maven repo I can see ant-contrib/ant-contrib/1.0b3/ant-contrib-1.0b3.jar and when I look inside the jar I can see net/sf/antcontrib/antcontrib.properties so no problem there.

When I check the values of maven.compile.classpath, maven.compile.classpath and maven.compile.classpath I can't see any reference to antcontrib, could this be the problem? Why don't they appear when antcontrib is defined as a dependancy?

Body:
another solution would be: keep the ant-contrib-1.0b3.jar to a path and then define it like this

<property name="runningLocation" location="" />
<taskdef resource="net/sf/antcontrib/antcontrib.properties">
    <classpath>
        <pathelement location="${runningLocation}/ant-contrib-1.0b3.jar" />
    </classpath>
</taskdef>

then

<target name="doSomething">
    <if>
        <equals arg1="${someProp}" arg2="YES" />
        <then>
            <echo message="It is YES" />
        </then>
        <else>
            <echo message="It is not YES" />
        </else>
    </if>
</target>

I put full code example here which you can download https://www.surasint.com/run-ant-with-if-from-maven/


问:
Disable Cloudflare error pages and show the actual error page
I want to know what the actual error is. I was able to hide it temporary, and it gave me a database connection error, so I tweaked the username and password. Now it's back to an error page.

How do I disable this error page entirely? I tried development mode, but it is still showing the actual error.

Besides, the error isn't entirely true:

```<code># systemctl status nginx
nginx.service - A high performance web server and a reverse proxy server
Loaded: loaded (/lib/systemd/system/nginx.service; enabled)
Active: active (running) since Tue 2017-03-28 20:44:47 UTC; 11min ago
</code>```

答:
Your app errors will continue to show when possible. However the error above is 521, meaning cloudflare could not even reach your server for any sort of reply.

More on that here: https://support.cloudflare.com/hc/en-us/articles/200171916-Error-521-Web-server-is-down

Body:
I want to know what the actual error is. I was able to hide it temporary, and it gave me a database connection error, so I tweaked the username and password. Now it's back to an error page.

How do I disable this error page entirely? I tried development mode, but it is still showing the actual error.

Besides, the error isn't entirely true:

# systemctl status nginx
nginx.service - A high performance web server and a reverse proxy server
Loaded: loaded (/lib/systemd/system/nginx.service; enabled)
Active: active (running) since Tue 2017-03-28 20:44:47 UTC; 11min ago


问:
Compare two Cells and Return Highest Value from third cells
Need help please. I am working on report which shows different names in coloumn A. I want to compare the two cells within the same coloumn and then display the highest value from COL B  into COL C:</p>

```<code>          COL A     COL B          COL C (OUTPUT RESULT REQUIRED)
Row 1     USA        $3             $7
Row 2     USA        $7             -
Row 3     Italy      $1             $1
Row 4     France     $9             $9
Row 5     France     $2             -
Row 6     France     $4             -
</code>```

答:
For certain 'flavors' of Excel 2016 (e.g. Excel for Android phones, Excel Mobile, Excel 2016 w/ Office 365, Excel 2016 for Mac, Excel Online, Excel for iPad, Excel for iPhone, Excel for Android tablet), pair up the newer MAXIFS with a COUNTIF.

```<code>=IF(COUNTIF(A$2:A2, A2)=1, MAXIFS(B:B, A:A, A2), " - ")
</code>```

Body:
Need help please. I am working on report which shows different names in coloumn A. I want to compare the two cells within the same coloumn and then display the highest value from COL B  into COL C:

          COL A     COL B          COL C (OUTPUT RESULT REQUIRED)
Row 1     USA        $3             $7
Row 2     USA        $7             -
Row 3     Italy      $1             $1
Row 4     France     $9             $9
Row 5     France     $2             -
Row 6     France     $4             -

Body:
For certain 'flavors' of Excel 2016 (e.g. Excel for Android phones, Excel Mobile, Excel 2016 w/ Office 365, Excel 2016 for Mac, Excel Online, Excel for iPad, Excel for iPhone, Excel for Android tablet), pair up the newer MAXIFS with a COUNTIF.

=IF(COUNTIF(A$2:A2, A2)=1, MAXIFS(B:B, A:A, A2), " - ")


问:
Java repeat part of a program with if and boolean operators
Hello I'm fairly new to java and I had troubles in a little test game.
So this is just a part of the code, I want that the user can repeat the part as often as he like with an while operater.

The code is here:

```<code>else if (a == 6){
        boolean InGame = true;
        while ( InGame );

        System.out.println("Glückspiel: Wer näher an der zufälligen Zahl ist gewinnt! 1-100");
        System.out.println("Spieler Eins");
        double playerOne = scan.nextDouble();
        System.out.println("Spieler Zwei");
        double playerTwo = scan.nextDouble();

        double randomValue = Math.random() * 100.0;

        // Math.abs
        double spacingOne = Math.abs(playerOne - randomValue);
        double spacingTwo = Math.abs(playerTwo - randomValue);
        System.out.println("Die Random Zahl war " + randomValue);

        if (spacingOne < spacingTwo) {
            System.out.println("Spieler Eins hat gewonnen!");
        }

        if (spacingOne > spacingTwo) {
            System.out.println("Spieler Zwei hat gewonnen!");
        }

        if (spacingOne == spacingTwo) {
            System.out.println("Unentschieden!");
        }
        System.out.println("Wenn du nochmal spielen willst schreibe 'ja' wenn nicht 'nein'");
        String PlayAgain = scan.nextLine();
        if  (PlayAgain == "nein");
        boolean inGame = false;
</code>```

Well I have never worked alot with booleans due to me being new in java.
Would nice if you could help me out.

答:
You are missing the scope of your while.

```<code>while(condition) {
    //statement(s)
}
</code>```

Currently all you have is an endless loop with your while because you haven't fed it any statements and your condition will therefore stay true.

Body:
Hello I'm fairly new to java and I had troubles in a little test game.
So this is just a part of the code, I want that the user can repeat the part as often as he like with an while operater.

The code is here:

else if (a == 6){
        boolean InGame = true;
        while ( InGame );

        System.out.println("Glückspiel: Wer näher an der zufälligen Zahl ist gewinnt! 1-100");
        System.out.println("Spieler Eins");
        double playerOne = scan.nextDouble();
        System.out.println("Spieler Zwei");
        double playerTwo = scan.nextDouble();

        double randomValue = Math.random() * 100.0;

        // Math.abs
        double spacingOne = Math.abs(playerOne - randomValue);
        double spacingTwo = Math.abs(playerTwo - randomValue);
        System.out.println("Die Random Zahl war " + randomValue);

        if (spacingOne < spacingTwo) {
            System.out.println("Spieler Eins hat gewonnen!");
        }

        if (spacingOne > spacingTwo) {
            System.out.println("Spieler Zwei hat gewonnen!");
        }

        if (spacingOne == spacingTwo) {
            System.out.println("Unentschieden!");
        }
        System.out.println("Wenn du nochmal spielen willst schreibe 'ja' wenn nicht 'nein'");
        String PlayAgain = scan.nextLine();
        if  (PlayAgain == "nein");
        boolean inGame = false;

Well I have never worked alot with booleans due to me being new in java.
Would nice if you could help me out.

Body:
You are missing the scope of your while.

while(condition) {
    //statement(s)
}

Currently all you have is an endless loop with your while because you haven't fed it any statements and your condition will therefore stay true.


问:
Filtering by group and keeping all instances where condition is met
I found an example of something similar

Essentially, I need to keep all items of a group where a user equal to some factor.

For example here is my initial data frame.

```<code>data <- data.frame(user = c("a","a",'b',"b",'c',"c","a","a","a","d","d","d"),
                   invoiceNum =c(1,1,1,1,1,1,2,2,2,2,2,2))
</code>```

I need to keep all invoices which have user d.

The output would look like:

```<code>  user invoiceNum
1    a          2
2    a          2
3    a          2
4    d          2
5    d          2
6    d          2
</code>```

I tried writing the following code but it does not work and gives me the following

```<code>data%>% group_by(invoiceNum)%>%dplyr::filter(user == "d")

    user invoiceNum
  <fctr>      <dbl>
1      d          2
2      d          2
3      d          2
</code>```

答:
We can use %in%

```<code>data %>%
     group_by(invoiceNum) %>%
     filter('d' %in% user)
#    user invoiceNum
#  <fctr>      <dbl>
#1      a          2
#2      a          2
#3      a          2
#4      d          2
#5      d          2
#6      d          2
</code>```

Body:
I found an example of something similar

Essentially, I need to keep all items of a group where a user equal to some factor.

For example here is my initial data frame.

data <- data.frame(user = c("a","a",'b',"b",'c',"c","a","a","a","d","d","d"),
                   invoiceNum =c(1,1,1,1,1,1,2,2,2,2,2,2))

I need to keep all invoices which have user d.

The output would look like:

  user invoiceNum
1    a          2
2    a          2
3    a          2
4    d          2
5    d          2
6    d          2

I tried writing the following code but it does not work and gives me the following

data%>% group_by(invoiceNum)%>%dplyr::filter(user == "d")

    user invoiceNum
  <fctr>      <dbl>
1      d          2
2      d          2
3      d          2

Body:
We can use %in%

data %>%
     group_by(invoiceNum) %>%
     filter('d' %in% user)
#    user invoiceNum
#  <fctr>      <dbl>
#1      a          2
#2      a          2
#3      a          2
#4      d          2
#5      d          2
#6      d          2


问:
Common libraries in a large team
Assume you have five products, and all of them use one or more of the company's internal libraries, written by individual developers.

It sounds simple but in practice, I found it to be very difficult to maintain.

How do you deal with the following scenarios:

A developer unintentionally introduces a bug and breaks everything in production.

Every library has to mature, That means the API needs to evolve, so how do you deploy the updated version to production if every developer needs to update/test their code while they are extremely busy on other projects? Is this a resource and time issue?

Version control, deployment,and usage. Would you store this in one global location or force each project to use, say, svn:externals to "tie" a library?

I've found that it is extremely hard to come up with a good strategy. My own pet theory is this:

Each common library has to have a super-thorough set of tests or else it should never be common, even if it means someone else duplicates the effort. Duplicate untested code is better than common untested code (you break only one project).

Each common library has to have a dedicated maintainer (can be offset by a really good test suite in a smaller team).

Each project should check out the version of the library that is known to work with it. This means a developer does not have to get pulled away to update API usage, as the common code gets updated. Which it will be. Every non-trivial piece of code evolves over months and years.

Thank you for your thoughts on this!

答:
I don't agree with this:

Duplicate untested code is better than
  common untested code (you break only
  one project).

If you are all equally likely to create bugs by implementing the same thing, then you'll all have to fix potentially different bugs in each instance of the "duplicate" library.

It also seems that it'd be much faster/cheaper to write the library once and, instead of having multiple other teams write the same thing, have some resources allocated to testing.

Now to solve your actual problem: I'd mimic what we do with real third-party libraries. We use a particular version until we're ready, or compelled to upgrade. I don't upgrade everything just because I can--there has to be a reason.

Once I see that reason (bug fix, new feature, etc.), then I upgrade with the risk that the new library may have new bugs or breaking changes.

So, you're library project would continue development as necessary, without impacting individual teams until they were ready to "upgrade".

You could publish releases or peg/branches/tag svn to help with all this.

If all teams have access to the bug tracker, they could easily see what known issues exist in the upgrade-candidate before they upgrade, too. Or, you could maintain that list yourself.

@Brian Clapper provides some excellent guidelines for how to run your library as a project in his answer.

OwnerDisplayName: Andrei

Title: Common libraries in a large team

LastEditorDisplayName: Roger Lipscombe

OwnerDisplayName: Michael Haren

LastEditorDisplayName: Michael Haren


问:
What is the best way to deal with JSON object?
I have a big string that represents JSON feed. My app downloads this feed from remote web service.

Questions:

1) Once I download JSON feed, where should I store it? Right now I am storing it in app Preferences and it works fine. I am just interested if there is any reason not to do that, or if there are better/faster options, like Internal Storage or something else?

2) When I am about to show data from this feed in my activity, I do something like this:

```<code>JSONObject jsonObj = new JSONObject(json_string);
JSONArray jsonArr = jsonObj.getJSONArray("root");
for (int m = 0; m < jsonArr.length(); m++) {
    ....
}
</code>```

The problem is, the first line that parses JSON feed is sort of expensive. At my current size feed (that might grow in the future) it takes maybe half a second to complete, not much, but still a problem. For example, I click button to call activity (to show data) and this 1/2 sec pause is noticeable and not good.

To avoid this pause, I should probably parse JSON immediately after feed is downloaded. Then question is, where should I keep parsed JSON object?

i) I can't save JSON object to preferences since only primitive data can be stored there.

ii) Should I do parsing every time my app starts, and make my parsed JSON objects (I have more of them) global (on application level) so I can access them from all of my activities?

iii) Or, I believe my 3rd option would be to declare JSON objests static so they can be easy accessed from other activities?

What is the best way to do this?

THX.

答:
If speed is truly a problem, an easy way to significantly speed up parsing (as well as writing out of) JSON data would be to use Jackson for parsing JSON data. Compared to org.json library (which Android SDK ships with) it is at least 3 - 5 times faster if you just want parse to Maps or Lists (http://www.cowtowncoder.com/blog/archives/2009/02/entry_204.html).
But if you can bind it to Java objects it is yet faster and uses less memory as well.

If you want to save JSON data it is typically just serialized as files, or as BLOBs in databases; but unless you really have to, it's better to just hold on to Java objects created from JSON data.

Body:
I have a big string that represents JSON feed. My app downloads this feed from remote web service.

Questions:

1) Once I download JSON feed, where should I store it? Right now I am storing it in app Preferences and it works fine. I am just interested if there is any reason not to do that, or if there are better/faster options, like Internal Storage or something else?

2) When I am about to show data from this feed in my activity, I do something like this:

JSONObject jsonObj = new JSONObject(json_string);
JSONArray jsonArr = jsonObj.getJSONArray("root");
for (int m = 0; m < jsonArr.length(); m++) {
    ....
}

The problem is, the first line that parses JSON feed is sort of expensive. At my current size feed (that might grow in the future) it takes maybe half a second to complete, not much, but still a problem. For example, I click button to call activity (to show data) and this 1/2 sec pause is noticeable and not good.

To avoid this pause, I should probably parse JSON immediately after feed is downloaded. Then question is, where should I keep parsed JSON object?

i) I can't save JSON object to preferences since only primitive data can be stored there.

ii) Should I do parsing every time my app starts, and make my parsed JSON objects (I have more of them) global (on application level) so I can access them from all of my activities?

iii) Or, I believe my 3rd option would be to declare JSON objests static so they can be easy accessed from other activities?

What is the best way to do this?

THX.


问:
python function for list of lists n long, with each element 0-m
I need to make a function so that I can put in two parameters, an order, and a max, and return a list of all of the lists 'order' long and with each element ranging from 0 to 'max'. I suspect I may need to use recursion, but I am getting lost in this.

so order = 2 max = 3 should return

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

and order=4, max=5 should return

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

Thanks for the help

答:
Note that in general, @Prune's answer is the weapon of choice, here.

As for recursion: The requested list can be constructed recursively as

The list of length 1 is the list of all 1-element lists with elements from the initial set:

[1] -> [[1]]

[1, 2] -> [[1], [2]]

[1, 2, 3] -> [[1], [2], [3]]

In Python:

l1 = [[item] for item in range(0, max + 1)]

The list ln1 of length n + 1 consists of the cartesian product of  ln of length n  with l1 with the elements joined by list concatenation.

In Python:

ln1 = [a + b for a in combine(base, n - 1) for b in combine(base, 1)]

```<code>def combinations(base, n):
    if n == 0:
        return []
    elif n == 1:
        return [[item] for item in base]
    else:
        return [a + b for a in combine(base, n - 1) for b in combine(base, 1)]
</code>```

itertools.combinations_with_replacements() is both faster and more memory efficient. It's also an existing wheel rather than a new one.

Body:
I need to make a function so that I can put in two parameters, an order, and a max, and return a list of all of the lists 'order' long and with each element ranging from 0 to 'max'. I suspect I may need to use recursion, but I am getting lost in this.

so order = 2 max = 3 should return

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

and order=4, max=5 should return

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

Thanks for the help

Body:
Note that in general, @Prune's answer is the weapon of choice, here.

As for recursion: The requested list can be constructed recursively as

The list of length 1 is the list of all 1-element lists with elements from the initial set:

[1] -> [[1]]

[1, 2] -> [[1], [2]]

[1, 2, 3] -> [[1], [2], [3]]

In Python:

l1 = [[item] for item in range(0, max + 1)]

The list ln1 of length n + 1 consists of the cartesian product of  ln of length n  with l1 with the elements joined by list concatenation.

In Python:

ln1 = [a + b for a in combine(base, n - 1) for b in combine(base, 1)]

def combinations(base, n):
    if n == 0:
        return []
    elif n == 1:
        return [[item] for item in base]
    else:
        return [a + b for a in combine(base, n - 1) for b in combine(base, 1)]

itertools.combinations_with_replacements() is both faster and more memory efficient. It's also an existing wheel rather than a new one.


问:
Error 1064 - In statement
I am trying to show the average price of products bought by customers from ‘Tucson’, however this query returns null even though there are two customers that have placed orders from Tuscon.

```<code>select AVG(product_price) from product where product_id in
(select product_id from orderline where order_id in
(select order_id from ordertable where cust_id in
(Select cust_id from customer where city = 'Tuscon')))
</code>```

答:
fom is not a recognized keyword. The MySQL parser doesn't know what to do with that, so it throws an error about "invalid syntax".

Consider using join operations in place of nested IN subqueries. If we are guaranteed:

product_id is unique in product table

order_id is unique in ordertable table

cust_id is unique in customer table

then we can get an equivalent result set, the average of the price of distinct products that were ordered...

```<code>SELECT AVG(p.product_price)
  FROM ( SELECT l.product_id
           FROM orderline l
           JOIN ordertable o
             ON o.order_id = l.order_id
           JOIN customer c
             ON c.cust_id = o.cust_id
          WHERE c.city = 'Tuscon'
          GROUP BY l.product_id
       ) q
  JOIN product p
    ON p.product_id = l.product_id
</code>```

If we want that "average price" of all products ordered (a different result,  with the average taking into account the number of times a product was ordered...then we could use a query like this:

```<code>SELECT AVG(p.product_price)
  FROM product p
  JOIN orderline l
    ON l.product_id = p.product_id
  JOIN ordertable o
    ON o.order_id = l.order_id
  JOIN customer c
    ON c.cust_id = o.cust_id
 WHERE c.city = 'Tuscon'
</code>```

Title: Error 1064 - In statement

Body:
I am trying to show the average price of products bought by customers from ‘Tucson’, however this query returns null even though there are two customers that have placed orders from Tuscon.

select AVG(product_price) from product where product_id in
(select product_id from orderline where order_id in
(select order_id from ordertable where cust_id in
(Select cust_id from customer where city = 'Tuscon')))

Body:
fom is not a recognized keyword. The MySQL parser doesn't know what to do with that, so it throws an error about "invalid syntax".

Consider using join operations in place of nested IN subqueries. If we are guaranteed:

product_id is unique in product table

order_id is unique in ordertable table

cust_id is unique in customer table

then we can get an equivalent result set, the average of the price of distinct products that were ordered...

SELECT AVG(p.product_price)
  FROM ( SELECT l.product_id
           FROM orderline l
           JOIN ordertable o
             ON o.order_id = l.order_id
           JOIN customer c
             ON c.cust_id = o.cust_id
          WHERE c.city = 'Tuscon'
          GROUP BY l.product_id
       ) q
  JOIN product p
    ON p.product_id = l.product_id

If we want that "average price" of all products ordered (a different result,  with the average taking into account the number of times a product was ordered...then we could use a query like this:

SELECT AVG(p.product_price)
  FROM product p
  JOIN orderline l
    ON l.product_id = p.product_id
  JOIN ordertable o
    ON o.order_id = l.order_id
  JOIN customer c
    ON c.cust_id = o.cust_id
 WHERE c.city = 'Tuscon'