问:
How to use Sprite Kit setCenterRect in combination with flipping node through xScale?
I hope someone can explain to me how the centerRect works and if it's bugged or not.

IMAGE PIPE (64x64)

STEP 1: CREATE PIPE

```<code>SKSpriteNode *node = [SKSpriteNode spriteNodeWithImageNamed:@"Pipe"];
[self addChild:node];
</code>```

STEP 2: DEFINE CENTER RECT

```<code>Origin (4.0, 32.0) Size( 56.0, 28.0)
</code>```

As stated in the documentation:

(1)The rectangle is in the unit coordinate space. The default value is
  (0,0)-(1.0,1.0), which indicates that the entire texture is stretched
  to fill the sprite. If a different rectangle is specified, then the
  rectangle’s coordinates are used to break the texture into a 3x3 grid.
  The four corners of this grid are applied without performing any
  scaling. The upper- and lower-middle parts are scaled horizontally,
  and (2) the left- and right-middle parts are scaled vertically. The center
  is scaled in both directions.

How can you figure out the unit coordinate space?

If the left and right middle parts are scaled vertically and the center scaled in both directions the code becomes:

```<code>SKSpriteNode *node = [SKSpriteNode spriteNodeWithImageNamed:@"Pipe"];
[node setCenterRect:CGRectMake(4.0/64.0, 32.0/64.0, 56.0/64.0, 28.0/64.0)];
[node setYScale:4.0];
[self addChild:node];
</code>```

Result

Weird the outcome is not what I expected, I don't want the top part to stretch, only the bottom part. Perhaps that has to do with the unit coordinate space?? I presume a flipped coordinate space.

STEP 3: LETS TRY AGAIN WITH REVERSED COORDINATES

```<code>SKSpriteNode *node = [SKSpriteNode spriteNodeWithImageNamed:@"Pipe"];
[node setCenterRect:CGRectMake(8.0/64.0, 8.0/64.0, 56.0/64.0, 28.0/64.0)];
[node setYScale:4.0];
[self addChild:node];
</code>```

Result

Not really what I expected, but at least now the proper part got stretched. So I guess that worked, but maybe someone can shine some light on why.

STEP 4: FIX APPEARANCE

```<code>[node setCenterRect:CGRectMake(8.0/64.0, 8.0/64.0, 56.0/64.0, 22.0/64.0)];
</code>```

STEP 5: LETS FLIP

So far, so good. We got the bottom pipe, now let's create the top pipe by first flipping it vertically.

```<code>    SKSpriteNode *node = [SKSpriteNode spriteNodeWithImageNamed:@"Pipe"];
    [node setCenterRect:CGRectMake(8.0/64.0, 8.0/64.0, 56.0/64.0, 22.0/64.0)];
    [node setYScale:-4.0];
    [self addChild:node];
</code>```

Result

Wooaah! It got all messed up?!?!! Let's take a step back and only flip it horizontally.

```<code>    SKSpriteNode *node = [SKSpriteNode spriteNodeWithImageNamed:@"Pipe"];
    [node setCenterRect:CGRectMake(8.0/64.0, 8.0/64.0, 56.0/64.0, 22.0/64.0)];
    [node setXScale:-1.0];
    [node setYScale:4.0];
    [self addChild:node];
</code>```

Result

Okay, that's really messed up. I have no idea how this works??

STEP 6: CUSTOM SCRIPT

I hope someone can tell me how the centerRect works in combination with the xScales, but for now I am creating a different sprite node and do the flip there (which is not ideal).

```<code>- (SKSpriteNode *)spriteNodeWithFlippedImageNamed:(NSString *)name
{
    UIImage     *image      = [UIImage imageNamed:name];
    CGImageRef  imageRef    = image.CGImage;
    float       scale       = [[UIScreen mainScreen] scale];
    CGSize      size        = CGSizeMake(image.size.width, image.size.height);

    //begin context
    UIGraphicsBeginImageContextWithOptions(size, NO, scale);
    CGContextRef context = UIGraphicsGetCurrentContext();

    //flip image
    CGContextTranslateCTM(context, 0, size.height);
    CGContextScaleCTM(context, -1.0, -1.0);

    //draw tiling image
    CGContextDrawTiledImage(context, (CGRect){CGPointZero, CGSizeMake(size.width, size.height)}, imageRef);
    UIImage *newImage = UIGraphicsGetImageFromCurrentImageContext();

    UIGraphicsEndImageContext();

    //create node
    SKTexture       *texture    = [SKTexture textureWithCGImage:newImage.CGImage];
    SKSpriteNode    *node       = [SKSpriteNode spriteNodeWithTexture:texture size:size];

    return node;
}
</code>```

SUMMARY QUESTIONS

How can you figure out the unit coordinate space?

How can you use the setCenterRect methode in combination with flipping the sprite?

答:
I found that inverting the CGRect (shape) when I know I'm flipping the spritenode seems to work -- notice the larger "y" value and negative sign for the "height" in the CGRect when we want the pipe flipped (i.e., pointing "Down")

** Updated for Swift, not Objective-C as originally noted above **

```<code>enum PipeDirection: Int {
    case Up = 1
    case Down = -1
}
</code>```

...

```<code>// Scale pipe larger from center area only (i.e., don't scale pipe "caps")
if pipeDirection == .Up {
    pipe.centerRect = CGRect(x: 0, y: 0.2, width: 1.0, height: 0.4)
} else {
    pipe.centerRect = CGRect(x: 0, y: 0.8, width: 1.0, height: -0.4)
}
pipe.yScale = CGFloat(pipeDirection.rawValue) * 1.5
</code>```

Body:
I hope someone can explain to me how the centerRect works and if it's bugged or not.

IMAGE PIPE (64x64)

STEP 1: CREATE PIPE

SKSpriteNode *node = [SKSpriteNode spriteNodeWithImageNamed:@"Pipe"];
[self addChild:node];

STEP 2: DEFINE CENTER RECT

Origin (4.0, 32.0) Size( 56.0, 28.0)

As stated in the documentation:

(1)The rectangle is in the unit coordinate space. The default value is
  (0,0)-(1.0,1.0), which indicates that the entire texture is stretched
  to fill the sprite. If a different rectangle is specified, then the
  rectangle’s coordinates are used to break the texture into a 3x3 grid.
  The four corners of this grid are applied without performing any
  scaling. The upper- and lower-middle parts are scaled horizontally,
  and (2) the left- and right-middle parts are scaled vertically. The center
  is scaled in both directions.

How can you figure out the unit coordinate space?

If the left and right middle parts are scaled vertically and the center scaled in both directions the code becomes:

SKSpriteNode *node = [SKSpriteNode spriteNodeWithImageNamed:@"Pipe"];
[node setCenterRect:CGRectMake(4.0/64.0, 32.0/64.0, 56.0/64.0, 28.0/64.0)];
[node setYScale:4.0];
[self addChild:node];

Result

Weird the outcome is not what I expected, I don't want the top part to stretch, only the bottom part. Perhaps that has to do with the unit coordinate space?? I presume a flipped coordinate space.

STEP 3: LETS TRY AGAIN WITH REVERSED COORDINATES

SKSpriteNode *node = [SKSpriteNode spriteNodeWithImageNamed:@"Pipe"];
[node setCenterRect:CGRectMake(8.0/64.0, 8.0/64.0, 56.0/64.0, 28.0/64.0)];
[node setYScale:4.0];
[self addChild:node];

Result

Not really what I expected, but at least now the proper part got stretched. So I guess that worked, but maybe someone can shine some light on why.

STEP 4: FIX APPEARANCE

[node setCenterRect:CGRectMake(8.0/64.0, 8.0/64.0, 56.0/64.0, 22.0/64.0)];

STEP 5: LETS FLIP

So far, so good. We got the bottom pipe, now let's create the top pipe by first flipping it vertically.

    SKSpriteNode *node = [SKSpriteNode spriteNodeWithImageNamed:@"Pipe"];
    [node setCenterRect:CGRectMake(8.0/64.0, 8.0/64.0, 56.0/64.0, 22.0/64.0)];
    [node setYScale:-4.0];
    [self addChild:node];

Result

Wooaah! It got all messed up?!?!! Let's take a step back and only flip it horizontally.

    SKSpriteNode *node = [SKSpriteNode spriteNodeWithImageNamed:@"Pipe"];
    [node setCenterRect:CGRectMake(8.0/64.0, 8.0/64.0, 56.0/64.0, 22.0/64.0)];
    [node setXScale:-1.0];
    [node setYScale:4.0];
    [self addChild:node];

Result

Okay, that's really messed up. I have no idea how this works??

STEP 6: CUSTOM SCRIPT

I hope someone can tell me how the centerRect works in combination with the xScales, but for now I am creating a different sprite node and do the flip there (which is not ideal).

- (SKSpriteNode *)spriteNodeWithFlippedImageNamed:(NSString *)name
{
    UIImage     *image      = [UIImage imageNamed:name];
    CGImageRef  imageRef    = image.CGImage;
    float       scale       = [[UIScreen mainScreen] scale];
    CGSize      size        = CGSizeMake(image.size.width, image.size.height);

    //begin context
    UIGraphicsBeginImageContextWithOptions(size, NO, scale);
    CGContextRef context = UIGraphicsGetCurrentContext();

    //flip image
    CGContextTranslateCTM(context, 0, size.height);
    CGContextScaleCTM(context, -1.0, -1.0);

    //draw tiling image
    CGContextDrawTiledImage(context, (CGRect){CGPointZero, CGSizeMake(size.width, size.height)}, imageRef);
    UIImage *newImage = UIGraphicsGetImageFromCurrentImageContext();

    UIGraphicsEndImageContext();

    //create node
    SKTexture       *texture    = [SKTexture textureWithCGImage:newImage.CGImage];
    SKSpriteNode    *node       = [SKSpriteNode spriteNodeWithTexture:texture size:size];

    return node;
}

SUMMARY QUESTIONS

How can you figure out the unit coordinate space?

How can you use the setCenterRect methode in combination with flipping the sprite?

Body:
I found that inverting the CGRect (shape) when I know I'm flipping the spritenode seems to work -- notice the larger "y" value and negative sign for the "height" in the CGRect when we want the pipe flipped (i.e., pointing "Down")

** Updated for Swift, not Objective-C as originally noted above **

enum PipeDirection: Int {
    case Up = 1
    case Down = -1
}

...

// Scale pipe larger from center area only (i.e., don't scale pipe "caps")
if pipeDirection == .Up {
    pipe.centerRect = CGRect(x: 0, y: 0.2, width: 1.0, height: 0.4)
} else {
    pipe.centerRect = CGRect(x: 0, y: 0.8, width: 1.0, height: -0.4)
}
pipe.yScale = CGFloat(pipeDirection.rawValue) * 1.5


来源: stackexchange

问:
Is WCF ready for real world?
As I read here http://arunatennakoon.blogspot.com/2010/11/things-i-learn-new-this-week.html

```<code>Friday, November 12, 2010
Things I learn new this week
1. Never ever use WCF.
---------------------

here is why
1. IIS 7 doesn't support .svc file format by default. So you need to
</code>```

install some extension files. so it's
  lot of work for a new product.

```<code>2. I found it very hard to configure security settings. when i
</code>```

tried to configure for the first time
  it threw all kind of errors.

```<code>3. After installing WCF in IIS, sometimes it's trowing an exception
</code>```

that refers to the temp directory. To
  solve this problem you have to re
  compile the application and
  re-distribute

```<code>and a lot more...
</code>```

So would you take the risk to use WCF ?

I'd like to hear about real world examples with hundred to billions of hit per year.

答: It is definitely ready for real world. Even Microsoft uses it in its products, for example MS Dynamics CRM services are now done in WCF.</p>

ContentLicense: CC BY-SA 2.5

Title: Is WCF ready for real world?

Body:
As I read here http://arunatennakoon.blogspot.com/2010/11/things-i-learn-new-this-week.html

Friday, November 12, 2010
Things I learn new this week
1. Never ever use WCF.
---------------------

here is why
1. IIS 7 doesn't support .svc file format by default. So you need to

install some extension files. so it's
  lot of work for a new product.

2. I found it very hard to configure security settings. when i

tried to configure for the first time
  it threw all kind of errors.

3. After installing WCF in IIS, sometimes it's trowing an exception

that refers to the temp directory. To
  solve this problem you have to re
  compile the application and
  re-distribute

and a lot more...

So would you take the risk to use WCF ?

I'd like to hear about real world examples with hundred to billions of hit per year.


问:
How to replace character at even position by ( and odd position by )
Is it possible to write down a regular expression such that the first $ sign will be replaced by a (, the second with a ), the third with a (, etc ?

For instance, the string

```<code>This is an $example$ of what I want, $ 1+1=2 $ and $ 2+2=4$.
</code>```

should become

```<code>This is an (example) of what I want, ( 1+1=2 ) and ( 2+2=4).
</code>```

答:
Sort of an indirect solution, but in some languages, you can use a callback function for the replacement. You can then cycle through the options in that function. This would also work with more than two options. For example, in Python:

```<code>>>> text = "This is an $example$ of what I want, $ 1+1=2 $ and $ 2+2=4$."
>>> options = itertools.cycle(["(", ")"])
>>> re.sub(r"\$", lambda m: next(options), text)
'This is an (example) of what I want, ( 1+1=2 ) and ( 2+2=4).'
</code>```

Or, if those always appear in pairs, as it seems to be the case in your example, you could match both $ and everything in between, and then replace the $ and reuse the stuff in between using a group reference \1; but again, not all languages support those:

```<code>>>> re.sub(r"\$(.*?)\$", r"(\1)", text)
'This is an (example) of what I want, ( 1+1=2 ) and ( 2+2=4).'
</code>```

ContentLicense: CC BY-SA 3.0

Body:
Is it possible to write down a regular expression such that the first $ sign will be replaced by a (, the second with a ), the third with a (, etc ?

For instance, the string

This is an $example$ of what I want, $ 1+1=2 $ and $ 2+2=4$.

should become

This is an (example) of what I want, ( 1+1=2 ) and ( 2+2=4).

Body:
Sort of an indirect solution, but in some languages, you can use a callback function for the replacement. You can then cycle through the options in that function. This would also work with more than two options. For example, in Python:

>>> text = "This is an $example$ of what I want, $ 1+1=2 $ and $ 2+2=4$."
>>> options = itertools.cycle(["(", ")"])
>>> re.sub(r"\$", lambda m: next(options), text)
'This is an (example) of what I want, ( 1+1=2 ) and ( 2+2=4).'

Or, if those always appear in pairs, as it seems to be the case in your example, you could match both $ and everything in between, and then replace the $ and reuse the stuff in between using a group reference \1; but again, not all languages support those:

>>> re.sub(r"\$(.*?)\$", r"(\1)", text)
'This is an (example) of what I want, ( 1+1=2 ) and ( 2+2=4).'


问:
How to tell mod_rewrite to only rewrite when specific urls are being entered?
I am having an issue with my .htaccess / .php files
I set up my web project in a way that it's split into 3 levels:

base level (mywebsite.com)

pages (mywebsite.com/news)

subpages/articles (mywebsite.com/news/123)

And all three are working as expected, here's my .htaccess:

```<code>RewriteEngine On
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule ^([^/]+)/?$ index.php?page=$1 [L]
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule ^([^/]+)/([^/]+)/?$ index.php?page=$1&sub=$2 [L]
</code>```

I have to admit, I am not very good with the Regular Expressions for .htaccess/mod_rewrite as it is something I have done very rarely up to this point.

However my issue now is, that people dont get sent to a 404 error page if the page id (see $1) is not valid, like people can technically enter mywebsite.com/asdasdasd/ and it'll bring them (obviously) to the index.php, now my question is, can this be done some way in the .htaccess or should I just use php to check if the id they entered is valid or not? I did see that there's a thing called rewriteMap but I dont want to change the httpd.conf

Can anyone help?

答:
can this be done some way in the .htaccess or should I just use php
  to check if the id they entered is valid or not?

I don't think this is programming problem but logical one.

Apache doesn't know what pages are valid /news /contact /help etc.

PHP knows what pages are valid

So you have only two options

a) Specify every single possible site in .htaccess which is terrible practice

b) Check in PHP is page valid then throw 404 which is only one reasonable solution.

Body:
I am having an issue with my .htaccess / .php files
I set up my web project in a way that it's split into 3 levels:

base level (mywebsite.com)

pages (mywebsite.com/news)

subpages/articles (mywebsite.com/news/123)

And all three are working as expected, here's my .htaccess:

RewriteEngine On
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule ^([^/]+)/?$ index.php?page=$1 [L]
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule ^([^/]+)/([^/]+)/?$ index.php?page=$1&sub=$2 [L]

I have to admit, I am not very good with the Regular Expressions for .htaccess/mod_rewrite as it is something I have done very rarely up to this point.

However my issue now is, that people dont get sent to a 404 error page if the page id (see $1) is not valid, like people can technically enter mywebsite.com/asdasdasd/ and it'll bring them (obviously) to the index.php, now my question is, can this be done some way in the .htaccess or should I just use php to check if the id they entered is valid or not? I did see that there's a thing called rewriteMap but I dont want to change the httpd.conf

Can anyone help?


问:
Improve switch statement in PHP or suggest an alternative workaround
I am trying to improve the below switch statement. What's happening here is that the code is called multiple times based on an x amount of tokens found, so the below code runs once per token.

If the $post->ID is not found then a notification is sent to that token and the id gets added in the database.

This works however at some point it's stopping after around 40% of tokens checked presumably because the ID is found? Since I am on wordpress, I used the update_option to store the id in a table but perhaps an alternative approach can be used?

```<code>$os = $this->os;
switch ($os) {

    case "iOS":
        $iOS_pastPushSavedID = get_option( 'iOS_pastPushSavedID',  $default = false);
        if($post->ID != $iOS_pastPushSavedID) {
            update_option( 'iOS_pastPushSavedID', $post->ID, no);
            $sendPush = true;
            //$title = ($os . '_New Push = ' . ' storedID: ' . $iOS_pastPushSavedID . ' / postID: ' . $post->ID);
        } else {
            //$title = ($os . '_Duplicate Push = ' . ' storedID: ' . $iOS_pastPushSavedID . ' / postID: ' . $post->ID);
            $sendPush = false;
        }
    break;

    case "Android":
        $android_pastPushSavedID = get_option( 'android_pastPushSavedID',  $default = false);
        if($post->ID != $android_pastPushSavedID) {
            //$title = ($os . '_New Push = ' . ' storedID: ' . $android_pastPushSavedID . ' / postID: ' . $post->ID);
            update_option( 'android_pastPushSavedID', $post->ID, no);
            $sendPush = true;
        } else {
            //$title = ($os . '_Duplicate Push = ' . ' storedID: ' . $android_pastPushSavedID . ' / postID: ' . $post->ID);
            $sendPush = false;
        }
    break;

    case "Fire OS":
        $fireos_pastPushSavedID = get_option( 'fireos_pastPushSavedID',  $default = false);
        if($post->ID != $fireos_pastPushSavedID) {
            //$title = ($os . '_New Push = ' . ' storedID: ' . $fireos_pastPushSavedID . ' / postID: ' . $post->ID);
            update_option( 'fireos_pastPushSavedID', $post->ID, no);
            $sendPush = true;
        } else {
            //$title = ($os . '_Duplicate Push = ' . ' storedID: ' . $fireos_pastPushSavedID . ' / postID: ' . $post->ID);
            $sendPush = false;
        }
    break;

    case "Safari":
        $safari_pastPushSavedID = get_option( 'safari_pastPushSavedID',  $default = false);
        if($post->ID != $safari_pastPushSavedID) {
            //$title = ($os . '_New Push = ' . ' storedID: ' . $safari_pastPushSavedID . ' / postID: ' . $post->ID);
            update_option( 'safari_pastPushSavedID', $post->ID, no);
            $sendPush = true;

        } else {
            //$title = ($os . '_Duplicate Push = ' . ' storedID: ' . $safari_pastPushSavedID . ' / postID: ' . $post->ID);
            $sendPush = false;
        }
    break;

    case "Chrome":
        $chrome_pastPushSavedID = get_option( 'chrome_pastPushSavedID',  $default = false);
        if($post->ID != $chrome_pastPushSavedID) {
            //$title = ($os . '_New Push = ' . ' storedID: ' . $chrome_pastPushSavedID . ' / postID: ' . $post->ID);
            update_option( 'chrome_pastPushSavedID', $post->ID, no);
            $sendPush = true;
        } else {
            //$title = ($os . '_Duplicate Push = ' . ' storedID: ' . $chrome_pastPushSavedID . ' / postID: ' . $post->ID);
            $sendPush = false;
        }
    break;

    case "Firefox":
        $firefox_pastPushSavedID = get_option( 'firefox_pastPushSavedID',  $default = false);
        if($post->ID != $firefox_pastPushSavedID) {
            //$title = ($os . '_New Push = ' . ' storedID: ' . $firefox_pastPushSavedID . ' / postID: ' . $post->ID);
            update_option( 'firefox_pastPushSavedID', $post->ID, no);
            $sendPush = true;

        } else {
        //$title = ($os . '_Duplicate Push = ' . ' storedID: ' . $firefox_pastPushSavedID . ' / postID: ' . $post->ID);
            $sendPush = false;
        }
    break;

    default:
        $sendPush = false;
}
</code>```

答:
You can do it like this. You can shorten your code like this.</p>

```<code>$optionName='';//added some default values
$sendPush = false;;//added some default values
switch ($os) {

    case "iOS":
        $optionName='iOS_pastPushSavedID';
    break;

    case "Android":
        $optionName='android_pastPushSavedID';
    break;

    case "Fire OS":
        $optionName='fireos_pastPushSavedID';
    break;

    case "Safari":
        $optionName='safari_pastPushSavedID';
    break;

    case "Chrome":
        $optionName='chrome_pastPushSavedID';
    break;

    case "Firefox":
        $optionName='firefox_pastPushSavedID';
    break;

    default:
        $sendPush = false;
}
//this is operation which is common when $optionName is not empty.
if(!empty($optionName))
{
    $optionData = get_option($optionName,  $default = false);
    if($post->ID != $optionData) {
        update_option( $optionData, $post->ID, no);
        $sendPush = true;
    } else {
        $sendPush = false;
    }
}
</code>```

Body:
I am trying to improve the below switch statement. What's happening here is that the code is called multiple times based on an x amount of tokens found, so the below code runs once per token.

If the $post->ID is not found then a notification is sent to that token and the id gets added in the database.

This works however at some point it's stopping after around 40% of tokens checked presumably because the ID is found? Since I am on wordpress, I used the update_option to store the id in a table but perhaps an alternative approach can be used?

$os = $this->os;
switch ($os) {

    case "iOS":
        $iOS_pastPushSavedID = get_option( 'iOS_pastPushSavedID',  $default = false);
        if($post->ID != $iOS_pastPushSavedID) {
            update_option( 'iOS_pastPushSavedID', $post->ID, no);
            $sendPush = true;
            //$title = ($os . '_New Push = ' . ' storedID: ' . $iOS_pastPushSavedID . ' / postID: ' . $post->ID);
        } else {
            //$title = ($os . '_Duplicate Push = ' . ' storedID: ' . $iOS_pastPushSavedID . ' / postID: ' . $post->ID);
            $sendPush = false;
        }
    break;

    case "Android":
        $android_pastPushSavedID = get_option( 'android_pastPushSavedID',  $default = false);
        if($post->ID != $android_pastPushSavedID) {
            //$title = ($os . '_New Push = ' . ' storedID: ' . $android_pastPushSavedID . ' / postID: ' . $post->ID);
            update_option( 'android_pastPushSavedID', $post->ID, no);
            $sendPush = true;
        } else {
            //$title = ($os . '_Duplicate Push = ' . ' storedID: ' . $android_pastPushSavedID . ' / postID: ' . $post->ID);
            $sendPush = false;
        }
    break;

    case "Fire OS":
        $fireos_pastPushSavedID = get_option( 'fireos_pastPushSavedID',  $default = false);
        if($post->ID != $fireos_pastPushSavedID) {
            //$title = ($os . '_New Push = ' . ' storedID: ' . $fireos_pastPushSavedID . ' / postID: ' . $post->ID);
            update_option( 'fireos_pastPushSavedID', $post->ID, no);
            $sendPush = true;
        } else {
            //$title = ($os . '_Duplicate Push = ' . ' storedID: ' . $fireos_pastPushSavedID . ' / postID: ' . $post->ID);
            $sendPush = false;
        }
    break;

    case "Safari":
        $safari_pastPushSavedID = get_option( 'safari_pastPushSavedID',  $default = false);
        if($post->ID != $safari_pastPushSavedID) {
            //$title = ($os . '_New Push = ' . ' storedID: ' . $safari_pastPushSavedID . ' / postID: ' . $post->ID);
            update_option( 'safari_pastPushSavedID', $post->ID, no);
            $sendPush = true;

        } else {
            //$title = ($os . '_Duplicate Push = ' . ' storedID: ' . $safari_pastPushSavedID . ' / postID: ' . $post->ID);
            $sendPush = false;
        }
    break;

    case "Chrome":
        $chrome_pastPushSavedID = get_option( 'chrome_pastPushSavedID',  $default = false);
        if($post->ID != $chrome_pastPushSavedID) {
            //$title = ($os . '_New Push = ' . ' storedID: ' . $chrome_pastPushSavedID . ' / postID: ' . $post->ID);
            update_option( 'chrome_pastPushSavedID', $post->ID, no);
            $sendPush = true;
        } else {
            //$title = ($os . '_Duplicate Push = ' . ' storedID: ' . $chrome_pastPushSavedID . ' / postID: ' . $post->ID);
            $sendPush = false;
        }
    break;

    case "Firefox":
        $firefox_pastPushSavedID = get_option( 'firefox_pastPushSavedID',  $default = false);
        if($post->ID != $firefox_pastPushSavedID) {
            //$title = ($os . '_New Push = ' . ' storedID: ' . $firefox_pastPushSavedID . ' / postID: ' . $post->ID);
            update_option( 'firefox_pastPushSavedID', $post->ID, no);
            $sendPush = true;

        } else {
        //$title = ($os . '_Duplicate Push = ' . ' storedID: ' . $firefox_pastPushSavedID . ' / postID: ' . $post->ID);
            $sendPush = false;
        }
    break;

    default:
        $sendPush = false;
}

Body:
You can do it like this. You can shorten your code like this.

$optionName='';//added some default values
$sendPush = false;;//added some default values
switch ($os) {

    case "iOS":
        $optionName='iOS_pastPushSavedID';
    break;

    case "Android":
        $optionName='android_pastPushSavedID';
    break;

    case "Fire OS":
        $optionName='fireos_pastPushSavedID';
    break;

    case "Safari":
        $optionName='safari_pastPushSavedID';
    break;

    case "Chrome":
        $optionName='chrome_pastPushSavedID';
    break;

    case "Firefox":
        $optionName='firefox_pastPushSavedID';
    break;

    default:
        $sendPush = false;
}
//this is operation which is common when $optionName is not empty.
if(!empty($optionName))
{
    $optionData = get_option($optionName,  $default = false);
    if($post->ID != $optionData) {
        update_option( $optionData, $post->ID, no);
        $sendPush = true;
    } else {
        $sendPush = false;
    }
}


问:
ajax best practice
let's say i have the following HTML page.

```<code><A panel to display list of items>
  Item A
  Item B
  Item C
  ...

<A panel to display details about item>
  Details on item X:
</code>```

I want to write the page so that whenever the user clicks on one of the items, the detail about the selected item will show up on the bottom panel.

However, few problems that I want to solve are:

How should I prevent duplicate requests. (like, user presses links to item A and B before the detail of item A returns from the server).

If I want to display "detail is now loading...", where should I put the code?

答:
About duplicate requests, I'd keep the last XMLHttpRequest object inside a lastRequest variable. Whenever I'm sending a new request I'd check this variable. If it exists, call lastRequest.abort(). I'd also check in your success callback that the request object is the same as your lastRequest, otherwise ignore it. In jQuery this would look like:

```<code>var lastRequest;

// Your click handler
$(".items").click(function () {
   if (lastRequest) lastRequest.abort();
   lastRequest = $.ajax({..., success: function (data, status, request) {
      if (request != lastRequest) return; // Ignore, it was aborted

      // Code to show the detail about the selected item
   }});

   // Code to show the in-progress message
});
</code>```

Title: ajax best practice

Body:
let's say i have the following HTML page.

  Item A
  Item B
  Item C
  ...

  Details on item X:

I want to write the page so that whenever the user clicks on one of the items, the detail about the selected item will show up on the bottom panel.

However, few problems that I want to solve are:

How should I prevent duplicate requests. (like, user presses links to item A and B before the detail of item A returns from the server).

If I want to display "detail is now loading...", where should I put the code?

Body:
About duplicate requests, I'd keep the last XMLHttpRequest object inside a lastRequest variable. Whenever I'm sending a new request I'd check this variable. If it exists, call lastRequest.abort(). I'd also check in your success callback that the request object is the same as your lastRequest, otherwise ignore it. In jQuery this would look like:

var lastRequest;

// Your click handler
$(".items").click(function () {
   if (lastRequest) lastRequest.abort();
   lastRequest = $.ajax({..., success: function (data, status, request) {
      if (request != lastRequest) return; // Ignore, it was aborted

      // Code to show the detail about the selected item
   }});

   // Code to show the in-progress message
});


问:
How to global a js var in a function?
It is possible to global a variable inside a function, if not, how can I access a var in function b from function a.</p>

```<code>var money;
var moneyInput = document.getElementById('input');

function check(){
if (moneyInput.value == "") {
    money = 100;
}

function hit() {
    document.write(money) // will this money var be 100 or undefined?
}
</code>```

答:
Just declare that variable outside function and then use it inside of that function.

P.S Please, post some code that you tried already.

let a = 5;
let b = 0; // Declare global variable

function printAB(_b) {
  b = _b; // Set new value through this function
  console.log(a, b);
}

function printBC() {
  let c = 7;
  console.log(b, c); // Get b variable
}

printBC(); // 0, 7 // b = 0
printAB(2); // 5, 2
printBC(); // 2, 7 // b = 2```

Edit

With code you provided, answer is simple. Variable money can be equal 100 or be undefined, that depends if function hit will be called before function check.

Title: How to global a js var in a function?

Body:
It is possible to global a variable inside a function, if not, how can I access a var in function b from function a.

var money;
var moneyInput = document.getElementById('input');

function check(){
if (moneyInput.value == "") {
    money = 100;
}

function hit() {
    document.write(money) // will this money var be 100 or undefined?
}

Body:
Just declare that variable outside function and then use it inside of that function.

P.S Please, post some code that you tried already.

let a = 5;
let b = 0; // Declare global variable

function printAB(_b) {
  b = _b; // Set new value through this function
  console.log(a, b);
}

function printBC() {
  let c = 7;
  console.log(b, c); // Get b variable
}

printBC(); // 0, 7 // b = 0
printAB(2); // 5, 2
printBC(); // 2, 7 // b = 2

Edit

With code you provided, answer is simple. Variable money can be equal 100 or be undefined, that depends if function hit will be called before function check.


问:
Use both WCF service and Web Api in same Service fabric reliable services
I haven't had much luck finding a way of using the WCFCommunicationListener as well as HttpListner(OwinCommunicationListner) inside same Reliable service. I Want to use two different listeners one that provide the Soap functionality that I can achieve using WCFCommunicationListener and other will simple Web Api consumption that what pretty much OwinCommunicationListner provides. I don't want to use the WcfCommunicationListener for my REST functionalities, I want to consume my REST apis as Web Api. </p>

答:
I will run two of them on two separated services. Using Docker for WCF and Owin for Web API.
If the problem you have is trying to share code then just have a shared library outside of the two services.

An sample on WCF on Docker here https://blogs.msdn.microsoft.com/webdev/2017/02/20/lets-try-wcf-self-hosted-services-in-a-container/


答: If you assign a value to an undeclared variable in a function it will be created as a global variable.</p>

Title: How to global a js var in a function?


答:
You should declare the variable outside of the function scope:</p>

```<code>var myGlobalVar = "foo";

function a(){
   var myLocalVar = 'bar';
   alert(myGlobalVar); //shows foo
   alert(myLocalVar); //shows bar
}

function b(){
   var myLocalVar = 'baz';
   alert(myGlobalVar); //shows foo too
   alert(myLocalVar); //shows baz
}
</code>```

Title: How to global a js var in a function?

Body:
You should declare the variable outside of the function scope:

var myGlobalVar = "foo";

function a(){
   var myLocalVar = 'bar';
   alert(myGlobalVar); //shows foo
   alert(myLocalVar); //shows bar
}

function b(){
   var myLocalVar = 'baz';
   alert(myGlobalVar); //shows foo too
   alert(myLocalVar); //shows baz
}


问:
When copy text from git-bash window through mouse selection, how to suppress ^C(ctrl+C) prints in git-bash
I'm using git-bash.exe (git-for-windows MING64 MinTTY) running on Windows 7(not from CMD).

When I select text on git bash to copy, it always trigger ctrl+C （which will display ^C in the next command line, it's a little painful）.

e.g.： When I left click down to select “git --version”, then left click up, in the next command line it outputs “^C”.

```<code>$ git --version

git version 2.9.2.windows.1

$^C
</code>```

Has anyone ever encounted this issue?

And how to suppress the abhorring ^C prints?

I download the exe file from https://github.com/git-for-windows/git/releases.

I tried the older versions, the results are same.

答: Because YouDaoDic.exe is watching the text you selected and trying to translate them, so a interrupt appears. You correct this problem by close YouDaoDic.exe</p>

Body:
I'm using git-bash.exe (git-for-windows MING64 MinTTY) running on Windows 7(not from CMD).

When I select text on git bash to copy, it always trigger ctrl+C （which will display ^C in the next command line, it's a little painful）.

e.g.： When I left click down to select “git --version”, then left click up, in the next command line it outputs “^C”.

$ git --version

git version 2.9.2.windows.1

$^C

Has anyone ever encounted this issue?

And how to suppress the abhorring ^C prints?

I download the exe file from https://github.com/git-for-windows/git/releases.

I tried the older versions, the results are same.


答:
Assign a variable without using var, let, or const

```<code>var foo = 'bar';

function fn() {
  console.log(foo);
  bar = 'xyz';
}

fn()

console.log(bar)
</code>```

Repl: https://repl.it/languages/javascript

Title: How to global a js var in a function?

Body:
Assign a variable without using var, let, or const

var foo = 'bar';

function fn() {
  console.log(foo);
  bar = 'xyz';
}

fn()

console.log(bar)

Repl: https://repl.it/languages/javascript


问:
Android Google map version-2 show direction and Google map icon
In my Android application my map screen shows direction and Google map when click marker on the map. I use the following in my application.

XML:

```<code><fragment
    android:id="@+id/map"
    android:name="com.google.android.gms.maps.MapFragment"
    android:layout_width="match_parent"
    android:layout_height="match_parent" />
</code>```

In code:

```<code>GoogleMap googleMap = ((MapFragment) getFragmentManager().findFragmentById(
        R.id.map)).getMap();
</code>```

I have marked the direction and Google map icon marked in blue color. please see the image of my map screen.

How to hide direction and Google map icon from map fragment?

答:
It's Called Map toolbar

You can enable and disable the toolbar by calling UiSettings.setMapToolbarEnabled(boolean).

Body:
In my Android application my map screen shows direction and Google map when click marker on the map. I use the following in my application.

XML:

<fragment
    android:id="@+id/map"
    android:name="com.google.android.gms.maps.MapFragment"
    android:layout_width="match_parent"
    android:layout_height="match_parent" />

In code:

GoogleMap googleMap = ((MapFragment) getFragmentManager().findFragmentById(
        R.id.map)).getMap();

I have marked the direction and Google map icon marked in blue color. please see the image of my map screen.

How to hide direction and Google map icon from map fragment?


问:
How to install openmpi from Macports on Sierra and/or check if openmpi is already installed
I am trying to install openmpi from Macports on Sierra 10.12.5. It seems that it is a straight forward command:

```<code>sudo port install openmpi
</code>```

When I do this, I get the error:

```<code>sudo: port: command not found
</code>```

I gathered from similar threads that this may be due to openmpi already being installed. How can I check if it is installed, and if so, uninstall it so that I can reinstall it using Macports with the above command? Any thoughts would be great. Thanks!

答:
By default, the port command is installed at /opt/local/bin/port.  The installer normally modifies your PATH environment variable to include '/opt/local/bin' so that you can launch stuff installed by MacPorts just by entering the name of the command.  I think you should re-do the MacPorts installation.  Follow:

https://www.macports.org/install.php

You almost certainly want to use the macOS package installer.  You may have to restart Terminal for the new PATH to take effect.

Body:
I am trying to install openmpi from Macports on Sierra 10.12.5. It seems that it is a straight forward command:

sudo port install openmpi

When I do this, I get the error:

sudo: port: command not found

I gathered from similar threads that this may be due to openmpi already being installed. How can I check if it is installed, and if so, uninstall it so that I can reinstall it using Macports with the above command? Any thoughts would be great. Thanks!


问:
Python3 request - Post request with Form Data
I'm trying to send a POST Request with form data to some form. I'm using requests package.

```<code>#!/bin/python3.6
import requests

FFF_search = 'https://www.fff.fr/la-vie-des-clubs/resultats'
data = {'address':75000}
session = requests.session()
r = session.post(FFF_search, data=data, headers={'User-Agent':'test'})
print(r.text)
</code>```

This gives me the result page where no result is found.

Maybe my problem is more about the data I'm sending.
Here's the POST request as it must be done on the website (Chrome dev tools).

答:
You should consider several issues:

Your's headers dict is not valid. There is no 'User-Agnet' that called test. You should use only valid headers headers. Try to send all the headers you see in the network tab.

Your's data us clearly wrong. You should send the described Form Data ad a dictionary and pass it with data=data, as you do (but you do it with a wrong data). Maybe the data you are passing now is the params?

Try to send the exact request like your's browser sending (with the same params and headers), and see the results you are receiving, with paying attention to the issues above.

Body:
I'm trying to send a POST Request with form data to some form. I'm using requests package.

#!/bin/python3.6
import requests

FFF_search = 'https://www.fff.fr/la-vie-des-clubs/resultats'
data = {'address':75000}
session = requests.session()
r = session.post(FFF_search, data=data, headers={'User-Agent':'test'})
print(r.text)

This gives me the result page where no result is found.

Maybe my problem is more about the data I'm sending.
Here's the POST request as it must be done on the website (Chrome dev tools).


问:
How to trigger event on dynamically generated elements (in mootools)
Example to demonstrate the issue can be found here:

http://jsfiddle.net/Byyu2/

As you can see only the first "Add" button triggers an event. The dynamically generated button does not. This is understandable as on page load these elements have not been created.

So what do I need to change to enable dynamically generated elements to also be registered to an event?

Thanks for looking.

答:
The answer mentioned is quite old. If you can, upgrade to MooTools 1.3 instead of 1.2. In MooTools More, you will find the Element.Delegation package. The package handles delegation for all MooTools native events, except focus, blur, mouseenter and mouseleave.

You will find an updated JS Fiddle here: http://jsfiddle.net/Byyu2/1/


问:
How can I write out correctly the download status in C# console app?
I have the following code, and it is working correctly except writing out the status of the download.

```<code>using System;
using System.Collections.Generic;
using System.Linq;
using System.Net;
using System.Text;
using System.Threading;

namespace ConsoleApplication1
{
    class Program
    {

        static void clear()
        {

            Thread.Sleep(1500);
            Console.SetCursorPosition(0, 0);

        }

        static void Main(string[] args)
        {
            var client = new WebClient();

            client.DownloadProgressChanged += (o, e) =>
            {

                Console.Write(e.ProgressPercentage + "% ");
                clear();

            };

            client.DownloadFileAsync(new Uri("http://XXX"), "file");

            Console.ReadKey();

        }
    }
}
</code>```

With the code many new lines will be inserted and the status of the download will not be updated and printed out.

答:
For what Thread.Sleep? Remove it.

If you want to preserve the content of the console then save cursor coordinates and set it each time.

```<code>using (var client = new WebClient())
{
    int left = Console.CursorLeft;
    int top = Console.CursorTop;

    client.DownloadProgressChanged += (o, e) =>
    {
        Console.SetCursorPosition(left, top);
        Console.Write(e.ProgressPercentage + "% ");
    };

    client.DownloadFileAsync(...);
    Console.ReadKey();
}
</code>```

Body:
I have the following code, and it is working correctly except writing out the status of the download.

using System;
using System.Collections.Generic;
using System.Linq;
using System.Net;
using System.Text;
using System.Threading;

namespace ConsoleApplication1
{
    class Program
    {

        static void clear()
        {

            Thread.Sleep(1500);
            Console.SetCursorPosition(0, 0);

        }

        static void Main(string[] args)
        {
            var client = new WebClient();

            client.DownloadProgressChanged += (o, e) =>
            {

                Console.Write(e.ProgressPercentage + "% ");
                clear();

            };

            client.DownloadFileAsync(new Uri("http://XXX"), "file");

            Console.ReadKey();

        }
    }
}

With the code many new lines will be inserted and the status of the download will not be updated and printed out.

Body:
For what Thread.Sleep? Remove it.

If you want to preserve the content of the console then save cursor coordinates and set it each time.

using (var client = new WebClient())
{
    int left = Console.CursorLeft;
    int top = Console.CursorTop;

    client.DownloadProgressChanged += (o, e) =>
    {
        Console.SetCursorPosition(left, top);
        Console.Write(e.ProgressPercentage + "% ");
    };

    client.DownloadFileAsync(...);
    Console.ReadKey();
}


问:
Is Method local variable will garbage collected if stored in static storage?
I am creating a client class, which will connect to different type of database. Following is the code snippet what I am trying to do.

```<code>public class Client{
    private static Map<ApplicationTypeEnum, Connection> connectionPool = new HashMap<>();

    public void init() throws Exception {

        try {
           Connection con1 = getConnection(someparams...);
           connectionPool.put("app-1",con1)
           Connection con2 = getConnection(someparams...);
           connectionPool.put("app-2",con2)
        } catch (Exception pe) {
            throw pe;
        }
    }
}
</code>```

Now the Connection object are local to init, so is there any chance that the Connectionobjects will be garbage collected when control is out of init method.

答:
Is Method local variable will garbage collected if stored in static
  storage?

A variable is never garbage collected.

Only objects are garbage collected.

An object is illegible to be collected when it is not referenced by another other living object.
 The object may be referenced by a static or an instance field. It doesn't matter for the GC.

But as a side note, static fields are not eligible to the GC.

In your actual code, the Connections you create in the init() method are referenced by the connectionPool static map.

So as the Connections are referenced by at least one living object, these are not eligible to be collected.

Body:
I am creating a client class, which will connect to different type of database. Following is the code snippet what I am trying to do.

public class Client{
    private static Map<ApplicationTypeEnum, Connection> connectionPool = new HashMap<>();

    public void init() throws Exception {

        try {
           Connection con1 = getConnection(someparams...);
           connectionPool.put("app-1",con1)
           Connection con2 = getConnection(someparams...);
           connectionPool.put("app-2",con2)
        } catch (Exception pe) {
            throw pe;
        }
    }
}

Now the Connection object are local to init, so is there any chance that the Connectionobjects will be garbage collected when control is out of init method.


问:
Leaflet data format
Comment after original question and reworking of the posting. My code now works, but I still don't understand why what should be an array of arrays is not but works.

Making a map using Leaflet via Ruby on Rails. Problem getting an array which is stored as a string to be understood by JavaScript (complete code at https://github.com/MtnBiker/historical-streets-la). Part of the code streets.js. The console.logs near the end is where the question is about:

```<code>"use strict";

function makeMap() {
// Map tile URLs
var hamlin1908url = 'https://api.mapbox.com/styles/v1/mtnbiker/cj3gnezpq00152rt5o6g3kyqp/tiles/256/{z}/{x}/{y}?access_token=pk.eyJ1IjoibXRuYmlrZXIiLCJhIjoiNmI5ZmZjMzAyNzJhY2Q0N2ZlN2E1ZTdkZjBiM2I1MTUifQ.6R3ptz9ejWpxcdZetLLRqg',
  Hill1928aws =    'https://crores.s3.amazonaws.com/tiles/1928Hills/{z}/{x}/{y}.png',
  baistDetailAws = 'https://crores.s3.amazonaws.com/tiles/baistDetail/{z}/{x}/{y}.png',
  baistKMaws     = "https://crores.s3.amazonaws.com/tiles/bkm/{z}/{x}/{y}.png",
  rueger1902aws  = "https://crores.s3.amazonaws.com/tiles/1902rueger/{z}/{x}/{y}.png",
  woods1908url   = "https://crores.s3.amazonaws.com/tiles/1908woods/{z}/{x}/{y}.png",
  // sanborn1894km1aURL = "//knobby.ws/crorestiles/sanborn1894km1a/{z}/{x}/{y}.png",
  sanborn1888km1aURL = "https://crores.s3.amazonaws.com/tiles/1888SanbornKM1a/{z}/{x}/{y}.png",
  sanborn1894km1aURL = "https://crores.s3.amazonaws.com/tiles/1894SanbornKM1a/{z}/{x}/{y}.png",
  osmUrl    = 'https://{s}.tile.openstreetmap.org/{z}/{x}/{y}.png',
      esriUrl   = 'https://server.arcgisonline.com/ArcGIS/rest/services/World_Imagery/MapServe\
  r/tile/{z}/{y}/{x}',
  googleUrl = 'http://www.google.cn/maps/vt?lyrs=s@189&gl=cn&x={x}&y={y}&z={z}'
  // bingUrl = "baseMapUrl = new L.BingLayer('AtGe6-aWfp_sv8DMsQeQBgTVE0AaVI2WcT42hmv12YSO-PPROsm9_UvdRyL91jav, {type: 'Road'});"
  // bingUrl = "http://bing.com/maps/default.aspx?cp=34.05~118.25&lvl=12&style=r",
  // bingUrl = "https://dev.virtualearth.net/REST/v1/ Imagery/Map/resourcePath?queryParameters&key=AtGe6-aWfp_sv8DMsQeQBgTVE0AaVI2WcT42hmv12YSO-PPROsm9_UvdRyL91jav"

// Links for attribution
var osmLink  = '<a href="https://openstreetmap.org">OpenStreetMap</a>',
  osmCopy = '<a href="https://www.openstreetmap.org/copyright">OpenStreetMap</a>',
  mapboxCopy = '<a href="https://www.mapbox.com/map-feedback/">Mapbox</a>',
  esriLink = '<a href="https://www.esri.com/">Esri</a>',
  mbLink   = '<a href="https://mapbox.com/">OpenStreetMap</a>',
  rumseyLink = '<a href="http://www.davidrumsey.com">The David Rumsey Map Collection</a>',
  csunLink = "",
  bigBlogMapLink = 'http://www.bigmapblog.com'

// Attribution
  var osmAttrib = '© ' + osmLink + ' Contributors',
  esriAttrib = 'i-cubed, USDA, USGS, AEX, GeoEye, Getmapping, Aerogrid, IGN, IGP, UPR-EGP,\
and the GIS User Community & '+ esriLink,
  mapboxAttrib = '© ' + mapboxCopy + '©' + osmCopy,
  mwAttrib ='https://thinkwhere.wordpress.com',
  rumseyAttrib = rumseyLink,
  csunAttrib = csunLink,
  bigBlogMapAttrib = bigBlogMapLink,
  hamlinAttrib = ""

// Putting together as a Leaftlet tileLayer. First variable is the URL of the tiles
var rueger1902Map       = L.tileLayer(rueger1902aws,    {attribution: mapboxAttrib}),
    osmMap      = L.tileLayer(osmUrl,       {attribution: osmAttrib}),
    esriMap     = L.tileLayer(esriUrl,      {attribution: esriAttrib}),
    // bing        = L.tileLayer(bingUrl), // This approach doesn't seem to work, but the following does. bing is easier to read than OSM because many major street names don't show up in OSM
    bing = L.tileLayer.bing('AtGe6-aWfp_sv8DMsQeQBgTVE0AaVI2WcT42hmv12YSO-PPROsm9_UvdRyL91jav'),
    google      = L.tileLayer(googleUrl,      {attribution: 'Google'}),
    hill1928 = L.tileLayer(Hill1928aws,  {attribution: bigBlogMapAttrib}),
    baistDetail = L.tileLayer(baistDetailAws, {attribution: rumseyAttrib}),
    baistKM     = L.tileLayer(baistKMaws,   {attribution: rumseyAttrib}),
    rueger1902  = L.tileLayer(rueger1902aws),
    hamlin1908   = L.tileLayer(hamlin1908url),
    woods1908    = L.tileLayer(woods1908url,  {attribution: rumseyAttrib}),
    sanborn1894km1a = L.tileLayer(sanborn1894km1aURL,  {attribution: csunAttrib}),
    sanborn1888km1a = L.tileLayer(sanborn1888km1aURL,  {attribution: csunAttrib})

var overlayLayers = {
  "<span style='color: blue'>1921 Baist detail</span>"   : baistDetail,
  "<span style='color: blue'>1921 Baist Key Map</span>"  : baistKM,
  "1928 Hill"    : hill1928,
  "woods1908"    : woods1908,
  "1908 Hamlin"  : hamlin1908,
  "1902 Rueger"  : rueger1902,
  "1894 Sanborn" : sanborn1894km1a,
  "1888 Sanborn" : sanborn1888km1a
};
var baseLayers = {
  "<span style='color: green'>Bing</span>"               : bing,
  "<span style='color: orange'>OSM Street</span>"        : osmMap,
  "<span style='color: green' >ESRI Satellite</span>"    : esriMap,
  "<span style='color: green' >Google Satellite</span>"  : google
}
var map = L.map('map').setView([34.05, -118.25], 13,);
console.log("95. typeof gon.streetExtentArray: " + typeof gon.streetExtentArray);
var streetExtentArray = gon.streetExtentArray;
console.log("99. typeof streetExtentArray = gon.streetExtentArray: " + typeof streetExtentArray);
var arrayStreetExtent = JSON.parse(streetExtentArray); // using intermediary for testing
console.log("121. arrayStreetExtent: " + arrayStreetExtent + ". typeOf: "+ arrayStreetExtent.typeOf);
map.fitBounds(arrayStreetExtent); // zooms to area of interest
L.polyline(arrayStreetExtent).addTo(map);
L.tileLayer.bing('AtGe6-aWfp_sv8DMsQeQBgTVE0AaVI2WcT42hmv12YSO-PPROsm9_UvdRyL91jav').addTo(map);
L.control.layers( baseLayers, overlayLayers, {collapsed:true} ).addTo(map);
}  // end makeMap
</code>```

From Chrome console

```<code>95. typeof gon.streetExtentArray: string
99. typeof streetExtentArray = gon.streetExtentArray: string
121. arrayStreetExtent: 34.073492888603404,-118.28553155064584,34.07285302899903,-118.28437283635142,34.06673857126311,-118.27029660344125,34.061
</code>```

The arrayStreetExtent is displayed a one-dimensional array when it should look like [[34, -118],[34.1, -118.2]]. But map.fitBounds(arrayStreetExtent) interprets it correctly and the LINESTRING of coordinates displays correctly.

A mystery to me, but it works.

答:
map.fitBounds expects an L.LatLngBounds object, or an array made of pairs of coordinates.

You are trying to use the array input, but  as a string instead of an array.

Therefore 2 easy solutions:

Either transform your string into an array in Ruby before you pass it to gon.

Or parse the string in JavaScript: JSON.parse(streetExtentArray)

Title: Leaflet data format

Body:
Comment after original question and reworking of the posting. My code now works, but I still don't understand why what should be an array of arrays is not but works.

Making a map using Leaflet via Ruby on Rails. Problem getting an array which is stored as a string to be understood by JavaScript (complete code at https://github.com/MtnBiker/historical-streets-la). Part of the code streets.js. The console.logs near the end is where the question is about:

"use strict";

function makeMap() {
// Map tile URLs
var hamlin1908url = 'https://api.mapbox.com/styles/v1/mtnbiker/cj3gnezpq00152rt5o6g3kyqp/tiles/256/{z}/{x}/{y}?access_token=pk.eyJ1IjoibXRuYmlrZXIiLCJhIjoiNmI5ZmZjMzAyNzJhY2Q0N2ZlN2E1ZTdkZjBiM2I1MTUifQ.6R3ptz9ejWpxcdZetLLRqg',
  Hill1928aws =    'https://crores.s3.amazonaws.com/tiles/1928Hills/{z}/{x}/{y}.png',
  baistDetailAws = 'https://crores.s3.amazonaws.com/tiles/baistDetail/{z}/{x}/{y}.png',
  baistKMaws     = "https://crores.s3.amazonaws.com/tiles/bkm/{z}/{x}/{y}.png",
  rueger1902aws  = "https://crores.s3.amazonaws.com/tiles/1902rueger/{z}/{x}/{y}.png",
  woods1908url   = "https://crores.s3.amazonaws.com/tiles/1908woods/{z}/{x}/{y}.png",
  // sanborn1894km1aURL = "//knobby.ws/crorestiles/sanborn1894km1a/{z}/{x}/{y}.png",
  sanborn1888km1aURL = "https://crores.s3.amazonaws.com/tiles/1888SanbornKM1a/{z}/{x}/{y}.png",
  sanborn1894km1aURL = "https://crores.s3.amazonaws.com/tiles/1894SanbornKM1a/{z}/{x}/{y}.png",
  osmUrl    = 'https://{s}.tile.openstreetmap.org/{z}/{x}/{y}.png',
      esriUrl   = 'https://server.arcgisonline.com/ArcGIS/rest/services/World_Imagery/MapServe\
  r/tile/{z}/{y}/{x}',
  googleUrl = 'http://www.google.cn/maps/vt?lyrs=s@189&gl=cn&x={x}&y={y}&z={z}'
  // bingUrl = "baseMapUrl = new L.BingLayer('AtGe6-aWfp_sv8DMsQeQBgTVE0AaVI2WcT42hmv12YSO-PPROsm9_UvdRyL91jav, {type: 'Road'});"
  // bingUrl = "http://bing.com/maps/default.aspx?cp=34.05~118.25&lvl=12&style=r",
  // bingUrl = "https://dev.virtualearth.net/REST/v1/ Imagery/Map/resourcePath?queryParameters&key=AtGe6-aWfp_sv8DMsQeQBgTVE0AaVI2WcT42hmv12YSO-PPROsm9_UvdRyL91jav"

// Links for attribution
var osmLink  = 'OpenStreetMap',
  osmCopy = 'OpenStreetMap',
  mapboxCopy = 'Mapbox',
  esriLink = 'Esri',
  mbLink   = 'OpenStreetMap',
  rumseyLink = 'The David Rumsey Map Collection',
  csunLink = "",
  bigBlogMapLink = 'http://www.bigmapblog.com'

// Attribution
  var osmAttrib = '© ' + osmLink + ' Contributors',
  esriAttrib = 'i-cubed, USDA, USGS, AEX, GeoEye, Getmapping, Aerogrid, IGN, IGP, UPR-EGP,\
and the GIS User Community & '+ esriLink,
  mapboxAttrib = '© ' + mapboxCopy + '©' + osmCopy,
  mwAttrib ='https://thinkwhere.wordpress.com',
  rumseyAttrib = rumseyLink,
  csunAttrib = csunLink,
  bigBlogMapAttrib = bigBlogMapLink,
  hamlinAttrib = ""

// Putting together as a Leaftlet tileLayer. First variable is the URL of the tiles
var rueger1902Map       = L.tileLayer(rueger1902aws,    {attribution: mapboxAttrib}),
    osmMap      = L.tileLayer(osmUrl,       {attribution: osmAttrib}),
    esriMap     = L.tileLayer(esriUrl,      {attribution: esriAttrib}),
    // bing        = L.tileLayer(bingUrl), // This approach doesn't seem to work, but the following does. bing is easier to read than OSM because many major street names don't show up in OSM
    bing = L.tileLayer.bing('AtGe6-aWfp_sv8DMsQeQBgTVE0AaVI2WcT42hmv12YSO-PPROsm9_UvdRyL91jav'),
    google      = L.tileLayer(googleUrl,      {attribution: 'Google'}),
    hill1928 = L.tileLayer(Hill1928aws,  {attribution: bigBlogMapAttrib}),
    baistDetail = L.tileLayer(baistDetailAws, {attribution: rumseyAttrib}),
    baistKM     = L.tileLayer(baistKMaws,   {attribution: rumseyAttrib}),
    rueger1902  = L.tileLayer(rueger1902aws),
    hamlin1908   = L.tileLayer(hamlin1908url),
    woods1908    = L.tileLayer(woods1908url,  {attribution: rumseyAttrib}),
    sanborn1894km1a = L.tileLayer(sanborn1894km1aURL,  {attribution: csunAttrib}),
    sanborn1888km1a = L.tileLayer(sanborn1888km1aURL,  {attribution: csunAttrib})

var overlayLayers = {
  "1921 Baist detail"   : baistDetail,
  "1921 Baist Key Map"  : baistKM,
  "1928 Hill"    : hill1928,
  "woods1908"    : woods1908,
  "1908 Hamlin"  : hamlin1908,
  "1902 Rueger"  : rueger1902,
  "1894 Sanborn" : sanborn1894km1a,
  "1888 Sanborn" : sanborn1888km1a
};
var baseLayers = {
  "Bing"               : bing,
  "OSM Street"        : osmMap,
  "ESRI Satellite"    : esriMap,
  "Google Satellite"  : google
}
var map = L.map('map').setView([34.05, -118.25], 13,);
console.log("95. typeof gon.streetExtentArray: " + typeof gon.streetExtentArray);
var streetExtentArray = gon.streetExtentArray;
console.log("99. typeof streetExtentArray = gon.streetExtentArray: " + typeof streetExtentArray);
var arrayStreetExtent = JSON.parse(streetExtentArray); // using intermediary for testing
console.log("121. arrayStreetExtent: " + arrayStreetExtent + ". typeOf: "+ arrayStreetExtent.typeOf);
map.fitBounds(arrayStreetExtent); // zooms to area of interest
L.polyline(arrayStreetExtent).addTo(map);
L.tileLayer.bing('AtGe6-aWfp_sv8DMsQeQBgTVE0AaVI2WcT42hmv12YSO-PPROsm9_UvdRyL91jav').addTo(map);
L.control.layers( baseLayers, overlayLayers, {collapsed:true} ).addTo(map);
}  // end makeMap

From Chrome console

95. typeof gon.streetExtentArray: string
99. typeof streetExtentArray = gon.streetExtentArray: string
121. arrayStreetExtent: 34.073492888603404,-118.28553155064584,34.07285302899903,-118.28437283635142,34.06673857126311,-118.27029660344125,34.061

The arrayStreetExtent is displayed a one-dimensional array when it should look like [[34, -118],[34.1, -118.2]]. But map.fitBounds(arrayStreetExtent) interprets it correctly and the LINESTRING of coordinates displays correctly.

A mystery to me, but it works.


答:
You can assign a value to the global object ( window in browsers):

function a(){
  window.test="test";
}
function b(){
 console.log(test);
}
a(),b();```

Title: How to global a js var in a function?


问:
SVG - how can I draw a brush stain?
I'm working with paperjs's library, and I need to draw a little brush stain with svg path's directions.

Is there any way to do that?

答:
I have made an Path animation with javascript (also running on IE) You can also
animate your image in this way.

For the rotation of your brush stain, take the next points of the path and rotate your brush stain with transform:rotate(degree,x,y)

  <!DOCTYPE html>

    <meta charset="utf-8">
    <meta name="viewport" content="width=device-width">
    <title>Nürburgring Animation</title>
    <meta name="author" content="Frank Wisniewski">
    <meta name="publisher" content="Frank Wisniewski">
    <meta name="copyright" content="Frank Wisniewski">
    <meta name="description" content="Auf dieser Seite wird eine kleine Animation des Nürburgrings um Adenau dargestellt. Die Animation wurde komplett in Javascript und SVG erstellt.">
    <meta name="keywords" content="SVG, Animation, Webdesign, Adenau, Nürburgring, Eifel, Frank, Wisniewski, Programmierung, Grafik, Gestaltung, Kunst">
    <meta name="page-topic" content="Forschung Technik">
    <meta name="page-type" content="Karte Plan">
    <meta name="audience" content="Alle, Erwachsene, Fans"><meta http-equiv="content-language" content="de">
    <meta name="robots" content="index, follow">
    <meta name="DC.Creator" content="Frank Wisniewski">
    <meta name="DC.Publisher" content="Frank Wisniewski">
    <meta name="DC.Rights" content="Frank Wisniewski">
    <meta name="DC.Description" content="Auf dieser Seite wird eine kleine Animation des Nürburgrings um Adenau dargestellt. Die Animation wurde komplett in Javascript und SVG rtstellt.">
    <meta name="DC.Language" content="de">

(c) Frank Wisniewski
Lohmühlenstraße 2
53518 Adenau

  ```

Title: SVG - how can I draw a brush stain?

Body:
I have made an Path animation with javascript (also running on IE) You can also
animate your image in this way.

For the rotation of your brush stain, take the next points of the path and rotate your brush stain with transform:rotate(degree,x,y)

  <!DOCTYPE html>
  <html>
  <head>
    <meta charset="utf-8">
    <meta name="viewport" content="width=device-width">
    <title>Nürburgring Animation</title>
    <meta name="author" content="Frank Wisniewski">
    <meta name="publisher" content="Frank Wisniewski">
    <meta name="copyright" content="Frank Wisniewski">
    <meta name="description" content="Auf dieser Seite wird eine kleine Animation des Nürburgrings um Adenau dargestellt. Die Animation wurde komplett in Javascript und SVG erstellt.">
    <meta name="keywords" content="SVG, Animation, Webdesign, Adenau, Nürburgring, Eifel, Frank, Wisniewski, Programmierung, Grafik, Gestaltung, Kunst">
    <meta name="page-topic" content="Forschung Technik">
    <meta name="page-type" content="Karte Plan">
    <meta name="audience" content="Alle, Erwachsene, Fans"><meta http-equiv="content-language" content="de">
    <meta name="robots" content="index, follow">
    <meta name="DC.Creator" content="Frank Wisniewski">
    <meta name="DC.Publisher" content="Frank Wisniewski">
    <meta name="DC.Rights" content="Frank Wisniewski">
    <meta name="DC.Description" content="Auf dieser Seite wird eine kleine Animation des Nürburgrings um Adenau dargestellt. Die Animation wurde komplett in Javascript und SVG rtstellt.">
    <meta name="DC.Language" content="de">

    <style>
      body{font-family:"Calibri", "Helvetica", sans-serif;}
      .content{width:300px;margin-left:auto;margin-right:auto;}
      #svgG{width:200px;margin-left:auto;margin-right:auto;}
      svg{width:200px;height:200px;overflow:hidden;}
      h1,p{text-align:center;}
      p{font-size:8px;}
      .p10{font-size:14px;font-weight:bold;}
    </style>
  </head>
  <body>
    <div class="content">
    <div id="svgG"></div>
    <hr>
    <p>(c) Frank Wisniewski<br>Lohmühlenstraße 2</br>53518 Adenau</p>

    </div>
  <script>
  /* Programm und Grafiken sind geistiges Eigentum von Frank Wisniewski, Lohmühlenstraße 2, 53518 Adenau und dürfen ohne Genehemigung nicht genutzt werden */

      var carCount = 8;
      var i;
      var colors = ["Black", "Navy", "Blue", "BlueViolet", "CornFlowerBlue","Red", "LimeGreen", "IndianRed", "Sienna"];
      var svg = document.createElementNS("http://www.w3.org/2000/svg", "svg");
      var _create = function (type){return document.createElementNS("http://www.w3.org/2000/svg", type);}
      var _set = function (el,par){for (key in par) {el.setAttribute(key.replace('X','-'),par[key]);}svg.appendChild(el);}
      with(svg){
        setAttribute('width', '250');
        setAttribute('height', '250');
        setAttribute("viewBox", "0 0 250 250");
        setAttributeNS("http://www.w3.org/2000/xmlns/", "xmlns:xlink", "http://www.w3.org/1999/xlink");
      }
      svg.setAttributeNS("http://www.w3.org/2000/xmlns/", "xmlns:xlink", "http://www.w3.org/1999/xlink");
      svgG.appendChild(svg);
      var adenaubullet = _create("circle");
      _set(adenaubullet,{r:7,fill:'#f00',stroke:'#f00',cx:110,cy:8,strokeXwidth:1});
      var pfad = _create("path");
      pfad.setAttribute("d","M23.748,97.732c-4.235-2.956-3.875-3.774,0.149-6.424c4.415-2.912,9.246-4.657,13.445-7.991c3.775-2.997,6.616-6.559,8.157-11.154c0.658-1.969,0.469-3.708,0.928-5.656c0.49-2.073,2.818-3.084,2.289-5.231c-1.943-7.859,12.718-12.905,15.122-20.157c3.09-9.145-16.734-9.687-5.879-15.675c3.809-2.103,3.375-6.84,6.656-9.057c4.651-3.144,8.367,1.576,11.515,4.158c3.215,2.642,3.816-0.669,7.024-1.456c3.189-0.786,10.073,3.112,11.988-0.465c1.826-3.412,1.65-7.33,6.191-8.478c4.341-1.098,8.877-0.364,12.739-3.081c1.894-1.331,6.225-6.532,8.439-2.986c2.437,3.904-0.348,10.177,0.854,14.706c2.772,10.454,17.172,9.7,25.21,10.781c9.04,1.215,17.95,12.277,26.751,6.006c3.794-2.695,4.927-5.525,10.095-6.125c1.264-0.15,7.907-1.917,7.61,0.729c-0.316,2.853-6.305,5.333-8.338,6.711c-4.479,3.022-0.753,6.298,1.884,2.81c3.211-4.251,8.561-3.146,12.597-5.729c3.836-2.448,4.706-5.857,5.413-9.774c1.985-10.859,17.365-0.166,21.786,3.753c4.462,3.959,0.835,6.313,1.039,10.839c0.191,3.879,3.526,1.893,5.27,4.377c1.404,1.99,0.811,7.445-1.462,8.753c-3.792,2.168-6.586-2.64-9.273,2.805c-1.183,2.4-3.285,4.19-3.92,6.858c-0.735,3.091,1.969,7.785-0.122,10.477c-1.086,0.723-2.258,1.257-3.517,1.6c-1.907,1.228-3.592,3.089-5.258,4.608c-2.656,2.422-4.04,5.798-6.476,8.439c-3.986,4.336-10.271,6.805-16.063,7.526c-1.563,0.396-3.123,0.396-4.681,0c-2.271-0.944-1.521-3.241-4.827-2.771c-2.364,0.319-6.657,3.103-4.31,5.873c3.164,3.744,14.496,4.718,10.232,11.852c-4.087,6.844-13.375,9.795-19.857,13.7c-7.564,4.557-15.104,9.15-22.606,13.8c-7.321,4.53-16.081,8.639-22.572,14.298c-4.59,4.036-7.287,12.104-12.4,15.145c-2.264,1.35-1.265,4.361-4.132,5.722c-2.816,1.335-5.621-0.041-7.605-2.184c-0.949-1.027-2.493-4.413-4.188-2.536c-2.399,2.652-5.102,5.234-8.833,5.743c-3.432,0.466-6.206-1.944-9.507-1.572c-3.674,0.413-5.729-0.104-7.561-3.373c-1.255-2.242-3.559-3.075-5.613-4.396c-3.346-2.152-5.549-4.272-8.34-7.002c-5.066-4.96-13.847-9.133-14.34-17.222c-0.215-3.656,2.038-7.426,2.341-11.079c0.397-4.697-0.287-9.311-1.945-13.715c-1.431-3.801-3.489-7.284-4.994-11.039C29.209,99.368,26.926,99.928,23.748,97.732");
      _set(pfad,{fill:'none',stroke:'#666',strokeXwidth:6});
      var bordstein=pfad.cloneNode(true);
      _set(bordstein,{stroke:'#ddd',strokeXwidth:4});
      var grandprix = _create("path");
      grandprix.setAttribute("d","M32.246,245.125c-2.99-2.644,4.779-6.693,6.57-8.077c3.212-2.479,6.842-4.163,5.87-8.961c-0.891-4.404,1.944-8.48,3.929-12.302c1.225-2.359,2.457-4.719,3.468-7.177c1.085-2.64,0.846-3.498-1.781-4.92c-2.916-1.579-8.019-3.264-4.406-7.271c3.643-4.035,7.452-7.957,11.752-11.297c3.277-2.547,7.475-2.651,11.457-3.249c1.722-0.26,13.399-0.733,13.39-2.918c-0.015-3.294,6.497-2.777,8.654-3.153c1.517-0.266,5.267-1.056,5.688,1.308c0.445,2.497-1.268,3.257-2.928,4.664c-7.362,6.223-15.047,12.292-22.803,18.019c-0.534,0.395-8.754,5.805-8.457,3.525c0.423-3.213,5.225-8.695,1.275-11.084c-2.188-1.332-4.133-0.486-6.367,0.376c-1.574,0.607-5.299,1.734-6.084,3.411c-0.74,1.58,0.625,3.774,2.29,3.882c1.022,0.069,3.515-1.991,3.427,0.323c-0.094,2.511,0.521,5.18-0.138,7.646c-0.792,2.955-2.661,5.646-4.08,8.322c-0.9,1.696-3.023,4.913-2.296,7.02c0.89,2.563,4.673,2.549,5.777,4.88c1.078,2.279-4.431,3.46-5.976,4.184c-2.971,1.387-5.743,2.851-8.27,4.98c-1.822,1.534-3.684,3.438-5.079,5.381C35.841,244.419,34.963,247.523,32.246,245.125");
      _set(grandprix,{fill:'none', stroke:'#000', strokeXwidth:4});
      var grandprixbordstein=grandprix.cloneNode(true);
      _set(grandprixbordstein,{stroke:'#f00',strokeXwidth:3});
      var myText=_create("text");
      with (myText){
        setAttribute("font-family", "Arial, sans-serif");
        setAttribute("font-weight", "bold");
        setAttribute("font-style", "italic");
        setAttribute("text-anchor", "middle");
      }
      var myTextNode = document.createTextNode("");
      myText.appendChild(myTextNode);
      var nordschleife=myText.cloneNode(true);
      _set(nordschleife,{x:120,y:77,fontXsize:16});
      nordschleife.textContent="NORDSCHLEIFE";
      var grandprixtext=nordschleife.cloneNode(true);
      _set(grandprixtext,{x:110,y:220,fontXsize:16});
      grandprixtext.textContent="GRAND-PRIX";
      var grandprixtext1=nordschleife.cloneNode(true);
      _set(grandprixtext1,{x:110,y:240,fontXsize:16});
       grandprixtext1.textContent="STRECKE";
      var adenautext=nordschleife.cloneNode(true);
      _set(adenautext,{x:165,y:14,fontXsize:16});
      adenautext.textContent="ADENAU";
      var roundSquare=[];
      var mySquare=_create("rect");
      var roundBullet=[];
      var roundBulletText=[];
      for (i=1;i <= carCount;i++){

        roundBullet[i]=adenaubullet.cloneNode(true);
        _set(roundBullet[i],{r:5,strokeXwidth:0,fill:colors[i],stroke:colors[i],cx:180,cy:120+i*5*3});

        roundSquare[i]=mySquare.cloneNode(true);
        _set(roundSquare[i],{x:203,y:113+i*5*3,fill:'#ddd',stroke:'none',height:13,width:30});

        roundBulletText[i]=adenautext.cloneNode(true);
        _set(roundBulletText[i],{x:210,y:125+i*5*3,fontXsize:14,fontXstyle:'normal'});
        roundBulletText[i].textContent="0";
      }
      var lapsText=nordschleife.cloneNode(true);
      _set(lapsText,{x:217,y:122,fontXsize:14,fontXstyle:'normal'});
      lapsText.textContent="LAPS";
      var cars = [];
      var step=[];
      var laps=[];
      var len = pfad.getTotalLength();
      var speed = 1.5;
      var pos = [];
      var pt;
      var repeater;
      var lapPos = [];
      var carProto = _create("circle");
      with (carProto){
        setAttribute("r", 3);
        setAttribute("stroke-width", "1");
      }
      for(i = 1; i <= carCount; i++){
        cars[i]=carProto.cloneNode(true);
        pos[i]=i*5+750;
        laps[i]=0;
        lapPos[i]=750;
        pt=pfad.getPointAtLength(len/1000*pos[i])
        _set(cars[i],{cx:pt.x,cy:pt.y,stroke:colors[i],fill:colors[i]});
        step[i]=speed+Math.random()/1;
      }
      var animate=function(){
        for(i = 1; i <= carCount; i++){
          pos[i]+=step[i];
          lapPos[i]+=step[i];
          if(pos[i]>1000){
            pos[i]=1;
            step[i]=speed+Math.random()/2;
          }
          if (lapPos[i]>1750){
            lapPos[i]=750;
            laps[i]++;
            roundBulletText[i].textContent=laps[i];
          }
          pt=pfad.getPointAtLength(len/1000*pos[i])
          cars[i].setAttribute("cx", pt.x);
          cars[i].setAttribute("cy", pt.y);
        }
        //repeater = requestAnimationFrame(animate);
        repeater = setTimeout(animate,1000/60);
      }
      animate();

  </script>
  </body>
  </html>


问:
pandas dataframe select row by full multiindex entry and some column entry
I have a multi indexed DataFrame in pandas and i would like to select a row by the following condition:

Let's say we have columns 'a','b','c' and indicies 'i1','i2'

```<code>print(df)

           a   b   c
i1  i2
10 2.0    10  34   ..
   2.0    11  45   ..
   2.0    12  36   ..
20 2.0    10  15   ..
   2.0    18  34   ..
   2.0    16  46   ..
</code>```

Now I would like to select for each unique muliindex entry the row where column 'a' becomes maximal. So I wrote

```<code>for entry in df.index.unique():
    max_a = df.loc[entry,'a'].max()
</code>```

and now I would like to select that row and append it to another dataframe, let's say dfout

```<code>dfout=dfout.append(df[(df.index.values == entry) & (df['fi'] == max_a)])
</code>```

This raises invalid type comparison, probably because I try to compare tuples, not sure...
Can anyone explain to me, how I would be able to select exactly that row the correct way? Maybe there is even a much nicer way to select all these max('a') rows for all unique entries of df.index.

edit:

df.index.values is of type numpy.ndarray

entry is of type tuple

Maybe this helps for answering my question.

答:
You have a problem with your data in that you want to identify rows with the maximum a per unique index item but your index isn't unique.

I would typically go about it like this

```<code>df.loc[df.groupby(['i1', 'i2']).a.idxmax()]
</code>```

But look at the idxmax results

```<code>df.groupby(level=['i1', 'i2']).a.idxmax()

i1  i2
10  2.0    (10, 2.0)
20  2.0    (20, 2.0)
Name: a, dtype: object
</code>```

Since the index isn't unique, the loc call will just return all of them again.

```<code>df.loc[df.groupby(level=['i1', 'i2']).a.idxmax()]

         a   b   c
i1 i2
10 2.0  10  34  ..
   2.0  11  45  ..
   2.0  12  36  ..
20 2.0  10  15  ..
   2.0  18  34  ..
   2.0  16  46  ..
</code>```

So... we need to make a unique index so this technique will work

Option 1

reset_index

I could have assigned the dataframe with the reset index to a new variable and used loc but I know that my new index will be the same as positions so I went ahead and used iloc

```<code>df.iloc[df.reset_index().groupby(['i1', 'i2']).a.idxmax()]

         a   b   c
i1 i2
10 2.0  12  36  ..
20 2.0  18  34  ..
</code>```

Option 2

cumcount

Add another level to the existing index to make it unique.

```<code>d1 = df.set_index(df.groupby(level=['i1', 'i2']).cumcount(), append=True)
d1.loc[d1.groupby(level=['i1', 'i2']).a.idxmax()].reset_index(-1, drop=True)

         a   b   c
i1 i2
10 2.0  12  36  ..
20 2.0  18  34  ..
</code>```

In my opinion, option 1 is prettier.

Body:
I have a multi indexed DataFrame in pandas and i would like to select a row by the following condition:

Let's say we have columns 'a','b','c' and indicies 'i1','i2'

print(df)

           a   b   c
i1  i2
10 2.0    10  34   ..
   2.0    11  45   ..
   2.0    12  36   ..
20 2.0    10  15   ..
   2.0    18  34   ..
   2.0    16  46   ..

Now I would like to select for each unique muliindex entry the row where column 'a' becomes maximal. So I wrote

for entry in df.index.unique():
    max_a = df.loc[entry,'a'].max()

and now I would like to select that row and append it to another dataframe, let's say dfout

dfout=dfout.append(df[(df.index.values == entry) & (df['fi'] == max_a)])

This raises invalid type comparison, probably because I try to compare tuples, not sure...
Can anyone explain to me, how I would be able to select exactly that row the correct way? Maybe there is even a much nicer way to select all these max('a') rows for all unique entries of df.index.

edit:

df.index.values is of type numpy.ndarray

entry is of type tuple

Maybe this helps for answering my question.

Body:
You have a problem with your data in that you want to identify rows with the maximum a per unique index item but your index isn't unique.

I would typically go about it like this

df.loc[df.groupby(['i1', 'i2']).a.idxmax()]

But look at the idxmax results

df.groupby(level=['i1', 'i2']).a.idxmax()

i1  i2
10  2.0    (10, 2.0)
20  2.0    (20, 2.0)
Name: a, dtype: object

Since the index isn't unique, the loc call will just return all of them again.

df.loc[df.groupby(level=['i1', 'i2']).a.idxmax()]

         a   b   c
i1 i2
10 2.0  10  34  ..
   2.0  11  45  ..
   2.0  12  36  ..
20 2.0  10  15  ..
   2.0  18  34  ..
   2.0  16  46  ..

So... we need to make a unique index so this technique will work

Option 1

reset_index

I could have assigned the dataframe with the reset index to a new variable and used loc but I know that my new index will be the same as positions so I went ahead and used iloc

df.iloc[df.reset_index().groupby(['i1', 'i2']).a.idxmax()]

         a   b   c
i1 i2
10 2.0  12  36  ..
20 2.0  18  34  ..

Option 2

cumcount

Add another level to the existing index to make it unique.

d1 = df.set_index(df.groupby(level=['i1', 'i2']).cumcount(), append=True)
d1.loc[d1.groupby(level=['i1', 'i2']).a.idxmax()].reset_index(-1, drop=True)

         a   b   c
i1 i2
10 2.0  12  36  ..
20 2.0  18  34  ..

In my opinion, option 1 is prettier.


问:
ObservableArray not reflecting data update
I'm creating an app using the very slick KnockoutJS library, but I've run into a snag. On the html page, I have a plain <select> control that I want to load with JSON data returned from a web service.

I define the observable array as follows:

```<code>var laborRow = function () {
    this.positions = ko.observableArray([]);
};
</code>```

When the page loads, the ajax call is made and the data is returned. In the callback, I do the following:

```<code>    success: function (msg) {
        laborRow.positions = msg;
    }
</code>```

based on the KO docs, I would expect that I would set the result like this:

```<code>laborRow.positions(msg);
</code>```

However, that just throws an error stating that "laborRow.positions in not a function"

The template in the html is as follows:

```

<p>The <code>laborRow</code> object is a property on the ViewModel which is bound to the page. For whatever reason, this does not work. To add another wrinkle, if I add code to peek into the observableArray and print out some piece of data, the data is in there. So it is being loaded successfully.</p>

<p>Any thoughts would be greatly appreciated.</p>

<p>The full code for my example case:</p>

```var laborRow = function () {
    this.positions = ko.observableArray([]);
};

var projectEstimate = function () {
    this.laborLine = ko.observableArray([new laborRow()]);

};

var projectViewModel = new projectEstimate();
ko.applyBindings(projectViewModel);

//and the code in the callback function on ajax success

 success: function (msg) {
                laborRow.positions = msg;
                //laborRow.positions(msg); **this does not work - error is laborRow.positions is not a function**
            },
```

<p>And the html:</p>

<pre class="lang-html prettyprint-override"><code> <tbody data-bind='template: {name: "laborRowTemplate", foreach:
laborLine}'> </tbody>

  <script type="text/html" id="laborRowTemplate">
        <tr>
          <td><select data-bind='options: positions, optionsText:
"Title",  optionsCaption: "select", value: selectedPosition '></
select></td>

        </tr>
    </script>
</code>```

Finally, thanks to Sean's comments below, I was able to get it working by modifying the code in the callback as follows:

```<code>success: function (msg) {
    projectViewModel.laborLine()[(projectViewModel.laborLine().length-1)].positionList(msg);
}
</code>```

答:
The problem is that you haven't actually created your model:

```<code>var laborRow = function () {
    this.positions = ko.observableArray([]);
    // will only be called if you call var some_var = new laborRow()
};
</code>```

Change your function to a bare object (as shown in the Knockout docs):

```<code>var laborRow = {
    positions: ko.observableArray([])
};
</code>```

And you'll be able to call laborRow.positions(msg); and have it work.

EDIT

Based on the new code, laborRow is still not instantiated -- if you are setting var laborRow somewhere else in your code (around the ajax request, perhaps) then you'll want to make sure that your call stack looks like this:

```<code>projectViewModel.laborLine()[0].positions()
// This will return the array you're looking for.
// The key is that laborLine is a `getter` not an attribute
</code>```

I've been bitten by the "ko variables are getters not attributes" bug on several occasions ... might that be happening with your code?

Body:
I'm creating an app using the very slick KnockoutJS library, but I've run into a snag. On the html page, I have a plain <select> control that I want to load with JSON data returned from a web service.

I define the observable array as follows:

var laborRow = function () {
    this.positions = ko.observableArray([]);
};

When the page loads, the ajax call is made and the data is returned. In the callback, I do the following:

    success: function (msg) {
        laborRow.positions = msg;
    }

based on the KO docs, I would expect that I would set the result like this:

laborRow.positions(msg);

However, that just throws an error stating that "laborRow.positions in not a function"

The template in the html is as follows:

The laborRow object is a property on the ViewModel which is bound to the page. For whatever reason, this does not work. To add another wrinkle, if I add code to peek into the observableArray and print out some piece of data, the data is in there. So it is being loaded successfully.

Any thoughts would be greatly appreciated.

The full code for my example case:

var laborRow = function () {
    this.positions = ko.observableArray([]);
};

var projectEstimate = function () {
    this.laborLine = ko.observableArray([new laborRow()]);

};

var projectViewModel = new projectEstimate();
ko.applyBindings(projectViewModel);

//and the code in the callback function on ajax success

 success: function (msg) {
                laborRow.positions = msg;
                //laborRow.positions(msg); **this does not work - error is laborRow.positions is not a function**
            },

And the html:

Finally, thanks to Sean's comments below, I was able to get it working by modifying the code in the callback as follows:

success: function (msg) {
    projectViewModel.laborLine()[(projectViewModel.laborLine().length-1)].positionList(msg);
}

Body:
The problem is that you haven't actually created your model:

var laborRow = function () {
    this.positions = ko.observableArray([]);
    // will only be called if you call var some_var = new laborRow()
};

Change your function to a bare object (as shown in the Knockout docs):

var laborRow = {
    positions: ko.observableArray([])
};

And you'll be able to call laborRow.positions(msg); and have it work.

EDIT

Based on the new code, laborRow is still not instantiated -- if you are setting var laborRow somewhere else in your code (around the ajax request, perhaps) then you'll want to make sure that your call stack looks like this:

projectViewModel.laborLine()[0].positions()
// This will return the array you're looking for.
// The key is that laborLine is a `getter` not an attribute

I've been bitten by the "ko variables are getters not attributes" bug on several occasions ... might that be happening with your code?


答:
Declaring the variable on the outer scope and using it inside should solve your problem. However if you insist on creating a variable on the global scope you can do the following;

```<code>window.VAR_NAME = 'foo';
</code>```

By doing so you are actually creating a global variable VAR_NAME and it now has the value foo.

Title: How to global a js var in a function?

Body:
It is possible to global a variable inside a function, if not, how can I access a var in function b from function a.

var money;
var moneyInput = document.getElementById('input');

function check(){
if (moneyInput.value == "") {
    money = 100;
}

function hit() {
    document.write(money) // will this money var be 100 or undefined?
}

Body:
Declaring the variable on the outer scope and using it inside should solve your problem. However if you insist on creating a variable on the global scope you can do the following;

window.VAR_NAME = 'foo';

By doing so you are actually creating a global variable VAR_NAME and it now has the value foo.


问:
How to replace character at even position by ( and odd position by )
Is it possible to write down a regular expression such that the first $ sign will be replaced by a (, the second with a ), the third with a (, etc ?

For instance, the string

```<code>This is an $example$ of what I want, $ 1+1=2 $ and $ 2+2=4$.
</code>```

should become

```<code>This is an (example) of what I want, ( 1+1=2 ) and ( 2+2=4).
</code>```

答:
In R, you can use str_replace, which only replaces the first match, and a while loop to deal with pairs of matches at a time.

```<code># For str_*
library(stringr)
# For the pipes
library(magrittr)

str <- "asdfasdf $asdfa$ asdfasdf $asdf$ adsfasdf$asdf$"

while(any(str_detect(str, "\\$"))) {
   str <- str %>%
     str_replace("\\$", "(") %>%
     str_replace("\\$", ")")
}
</code>```

It's not the most efficient solution, probably, but it will go through and replace $ with ( and ) through the whole string.

Body:
Is it possible to write down a regular expression such that the first $ sign will be replaced by a (, the second with a ), the third with a (, etc ?

For instance, the string

This is an $example$ of what I want, $ 1+1=2 $ and $ 2+2=4$.

should become

This is an (example) of what I want, ( 1+1=2 ) and ( 2+2=4).

Body:
In R, you can use str_replace, which only replaces the first match, and a while loop to deal with pairs of matches at a time.

# For str_*
library(stringr)
# For the pipes
library(magrittr)

str <- "asdfasdf $asdfa$ asdfasdf $asdf$ adsfasdf$asdf$"

while(any(str_detect(str, "\\$"))) {
   str <- str %>%
     str_replace("\\$", "(") %>%
     str_replace("\\$", ")")
}

It's not the most efficient solution, probably, but it will go through and replace $ with ( and ) through the whole string.


问:
Get screenshots from browserstack
I have created a custom reporting tool based on ExpressJS and NodeJS for my selenium tests. I am storing all information about the executed tests in a own database (testrun, testcases, teststeps and so on).

Now, I want to show a screenshot for every test step. The tests will be executed in browserstack and now I want to get the screenshots from the build and integrate them in my custom report. My first idea was to take the screenshots by my own and store them into the database (or file system), but the images are very big and why not use the screenshots from browsertack.

Is it possible to get the screenshots from browserstack and integrate them into every test step in my custom reporting tool? I know, there is a api from browserstack, but I think it's quite difficult to get them and match it to my current logic.
The best way would be to get the screenshot path from browserstack at the runtime and store it to my database. Is that possible?

答:
I get the following answer from browserstack:

Browserstack REST API which will retrieve the 'Raw logs'. These Raw
  logs needs to be parsed locally to extract the screenshot URLs
  generated automatically as a part of the session 'Visual logs'. These
  URLs can then be stored in the local database. REST API: curl -u
  ":"
  https://www.browserstack.com/automate/sessions/.json The
  above API returns the response in JSON format. Depending on the
  requirement you can use "logs", "video_url", "browser_url" or
  "public_url" keys. "logs"                :    Link to access session's
  Raw Logs "video_url"        :    Link to access session's recorded
  video "browser_url"    :    Only logged in user can access this
  session link "public_url"        :    Session link accessible publicly

So, I guess it's not possible to receive the corresponding screenshot at runtime. At the moment, I am using a TestNGListener class to log each test step and store it directly into a db. My idea was to get the screenshot from browserstack, for example when afterNavigateTo is called. But this seems to be impossible. At the moment, I think I have to show my generated log and the visual log from browserstack in a separate view. Or do anyone has an other idea?

Title: Get screenshots from browserstack


问:
MSP430 Code Composer- Project builds and runs but changes do not show on board
As the title says its not giving me any errors when i build and run in code composer, but nothing happens on the baord. It even says the normal : "MSP430:  Flash/FRAM usage is 84 bytes. RAM usage is 80 bytes."  The code is below, should just light up leds in pattern. Straight from textbook, tried other code also.

```<code>#include <msp430.h>

void main (void)
{

   WDTCTL = WDTPW | WDTHOLD; // Stop watchdog timer
   P2DIR = 0x18; // Set pins with LEDs to output, 0b00011000
   P2OUT = 0x08; // LED2 (P2.4) on, LED1 (P2.3) off (active low!)

   for (;;) { }

}
</code>```

`

答:
The compiler tells you how many bytes you code needs from the Flash and RAM Memory. But this output does not mean that, those byte have also been transfered to the chip.

So perhaps the easy answer is: After compiling the code you have to start the debugger which automatically transfers the programm to the chip's flash memory and starts it.

If you had done this already then, it could be possible that:

you have not chosen the right serial port (virtual USB to Serial?)

your driver (flash programmer over usb) is corrupt (Windows ?)

your MSP430 is RIP

if you use a lauchpad:

your lauchpad is damaged (especially the USB programmer part)

you removed the jumper that connect the USB Programmer with the chip' UART  programming pins.

Body:
As the title says its not giving me any errors when i build and run in code composer, but nothing happens on the baord. It even says the normal : "MSP430:  Flash/FRAM usage is 84 bytes. RAM usage is 80 bytes."  The code is below, should just light up leds in pattern. Straight from textbook, tried other code also.

#include <msp430.h>

void main (void)
{

   WDTCTL = WDTPW | WDTHOLD; // Stop watchdog timer
   P2DIR = 0x18; // Set pins with LEDs to output, 0b00011000
   P2OUT = 0x08; // LED2 (P2.4) on, LED1 (P2.3) off (active low!)

   for (;;) { }

}

`


问:
Error in using NGramTokenize (lapply issue)
I'm using the NGramTokenizer from the rWeka package. I believe i have installed everything correctly. I'm executing the following code:

```<code>Bigram_Tokenizer <- function(x) NGramTokenizer(x, Weka_control(min = 2, max = 2))
tdm <- TermDocumentMatrix(corpus, control = list(tokenize= Bigram_Tokenizer()))
</code>```

Error I receive is:

```<code>Error in lapply(x,f): argument "x" is missing with no default.
</code>```

Any ideas on how to resolve this? Thanks again in advance.

Best

Vishal

答:
You seem to be executing Bigram_Tokenizer() in TermDocumentMatrix function instead of just passing it by reference. You need to just pass it withou executing:</p>

```<code>Bigram_Tokenizer <- function(x) NGramTokenizer(x, Weka_control(min = 2, max = 2))
tdm <- TermDocumentMatrix(corpus, control = list(tokenize= Bigram_Tokenizer))
</code>```

Body:
I'm using the NGramTokenizer from the rWeka package. I believe i have installed everything correctly. I'm executing the following code:

Bigram_Tokenizer <- function(x) NGramTokenizer(x, Weka_control(min = 2, max = 2))
tdm <- TermDocumentMatrix(corpus, control = list(tokenize= Bigram_Tokenizer()))

Error I receive is:

Error in lapply(x,f): argument "x" is missing with no default.

Any ideas on how to resolve this? Thanks again in advance.

Best

Vishal

Body:
You seem to be executing Bigram_Tokenizer() in TermDocumentMatrix function instead of just passing it by reference. You need to just pass it withou executing:

Bigram_Tokenizer <- function(x) NGramTokenizer(x, Weka_control(min = 2, max = 2))
tdm <- TermDocumentMatrix(corpus, control = list(tokenize= Bigram_Tokenizer))


问:
Jquery toggle(), hide() not working as expected
I'm just starting out with JQuery in a Drupal environment.

I have some thumbnails, and I want it so that when you click one, the bigger picture appears in the "viewport" (a hidden div appears). There might be better ways to accomplish what I am doing, but I need to do it this way.

This is what I have :

```<code>$(document).ready(function() {
  //$('#bigpic1').hide(); //show the first big picture always on page load
  $('#bigpic2').hide();
  $('#bigpic3').hide();

 $('a#thumb1').click(function() {
    $('#bigpic2').hide(); $('#bigpic3').hide();
    $('#bigpic3').toggle(200);
     return false;
  });
 $('a#thumb2').click(function() {
    $('#bigpic1').hide(); $('#bigpic3').hide();
    $('#bigpic2').toggle(200);
    return false;
  });
  $('a#thumb3').click(function() {
    $('#bigpic1').hide(); $('#bigpic2').hide();
    $('#bigpic3').toggle(200);
    return false;
  });

});
</code>```

Besides being some ugly code, it doesn't work right. The first big picture doesn't appear when the page does, and clicking on more thumbnails shows the right div - but never hides any (only one big picture is supposed to be visible at a time in the "viewport").

My HTML looks like this

```<code><table><tr>
  <td><a href="#" mce_href="#" id="thumb1">...thumb1...</td>
  <td><a href="#" mce_href="#" id="thumb2">...thumb2...</td>
  <td><a href="#" mce_href="#" id="thumb3">...thumb3...</td>
</tr>
<tr><td colspan="3">
  <!-- my "viewport" cell -->
  <!-- the big picture displays here -->
  <div  id="bigpic1">... </div>
  <div  id="bigpic2">...</div>
  <div  id="bigpic3">...</div>
</td></tr></table>
</code>```

答:
The # selector selects an id so you don't need the type in there. Selectors are on of jQuery's best features, so get more familiar with them all. http://api.jquery.com/category/selectors/.

You could even do a general method like this (you need to give the  elements a name).

```<code><table>
    <tr>
        <td>
            <a href="#" mce_href="#" name="thumb1" id="thumb1">...thumb1...</a>
        </td>
        <td>
            <a href="#" mce_href="#" name="thumb2" id="thumb2">...thumb2...</a>
        </td>
        <td>
            <a href="#" mce_href="#" name="thumb3" id="thumb3">...thumb3...</a>
        </td>
    </tr>
    <tr>
        <td colspan="3">
            <!-- my "viewport" cell -->
            <!-- the big picture displays here -->
            <div name="bigpic1" id="bigpic1">...1... </div>
            <div name="bigpic2" id="bigpic2">...2... </div>
            <div name="bigpic3" id="bigpic3">...3... </div>
        </td>
    </tr>
</table>
</code>```

And the jQuery code.

```<code>//on load
$(document).ready(function() {
    $('#bigpic2').hide();
    $('#bigpic3').hide();

    //this will be run when an element has a name with the text "thumb" in it
    $('[name*=thumb]').click(function() {
        //hide all big pictures (loops over every element that has a name with the text "bigpic" in it
        $('[name*=bigpic]').each(function(index, value) {
            if ($(this).is(':visible')) { //if the big pic is visible
                $(this).hide(200); //then hide it
                return false; //found the visible big pic so no need to keep looping
            }
        });
        //show the right image
        $('#bigpic' + $(this).attr('id').replace('thumb', '')).show(200);
    });
});// end on load
</code>```

This is less code, that is more extensible. It will not need to be changed if you add/remove images.
About thie first image showing on load did you try $('#bigpic1').show(); on document load. Oh and you don't need to return a value in the functions.

Body:
I'm just starting out with JQuery in a Drupal environment.

I have some thumbnails, and I want it so that when you click one, the bigger picture appears in the "viewport" (a hidden div appears). There might be better ways to accomplish what I am doing, but I need to do it this way.

This is what I have :

$(document).ready(function() {
  //$('#bigpic1').hide(); //show the first big picture always on page load
  $('#bigpic2').hide();
  $('#bigpic3').hide();

 $('a#thumb1').click(function() {
    $('#bigpic2').hide(); $('#bigpic3').hide();
    $('#bigpic3').toggle(200);
     return false;
  });
 $('a#thumb2').click(function() {
    $('#bigpic1').hide(); $('#bigpic3').hide();
    $('#bigpic2').toggle(200);
    return false;
  });
  $('a#thumb3').click(function() {
    $('#bigpic1').hide(); $('#bigpic2').hide();
    $('#bigpic3').toggle(200);
    return false;
  });

});

Besides being some ugly code, it doesn't work right. The first big picture doesn't appear when the page does, and clicking on more thumbnails shows the right div - but never hides any (only one big picture is supposed to be visible at a time in the "viewport").

My HTML looks like this

  ...thumb1...
  ...thumb2...
  ...thumb3...

...

...

...

Body:
The # selector selects an id so you don't need the type in there. Selectors are on of jQuery's best features, so get more familiar with them all. http://api.jquery.com/category/selectors/.

You could even do a general method like this (you need to give the <a> elements a name).

<table>
    <tr>
        <td>
            <a href="#" mce_href="#" name="thumb1" id="thumb1">...thumb1...</a>
        </td>
        <td>
            <a href="#" mce_href="#" name="thumb2" id="thumb2">...thumb2...</a>
        </td>
        <td>
            <a href="#" mce_href="#" name="thumb3" id="thumb3">...thumb3...</a>
        </td>
    </tr>
    <tr>
        <td colspan="3">
            <!-- my "viewport" cell -->
            <!-- the big picture displays here -->
            <div name="bigpic1" id="bigpic1">...1... </div>
            <div name="bigpic2" id="bigpic2">...2... </div>
            <div name="bigpic3" id="bigpic3">...3... </div>
        </td>
    </tr>
</table>

And the jQuery code.

//on load
$(document).ready(function() {
    $('#bigpic2').hide();
    $('#bigpic3').hide();

    //this will be run when an element has a name with the text "thumb" in it
    $('[name*=thumb]').click(function() {
        //hide all big pictures (loops over every element that has a name with the text "bigpic" in it
        $('[name*=bigpic]').each(function(index, value) {
            if ($(this).is(':visible')) { //if the big pic is visible
                $(this).hide(200); //then hide it
                return false; //found the visible big pic so no need to keep looping
            }
        });
        //show the right image
        $('#bigpic' + $(this).attr('id').replace('thumb', '')).show(200);
    });
});// end on load

This is less code, that is more extensible. It will not need to be changed if you add/remove images.
About thie first image showing on load did you try $('#bigpic1').show(); on document load. Oh and you don't need to return a value in the functions.