问:
How should I be assigning names to sprites from a sprite sheet?
I know how to load a sprite sheet, clip the images and return a list of those images, but I like to refer to my sprites by name rather than index, to keep the code readable and manageable, but it's sometimes long and tedious writing out lists of sprite names.

I usually create a dictionary, and refer to the sprite I need by name, but I wondered if I should be hard-coding the names?

This is what I usually do:

sprites = load_spritesheet('spr_buttons.png', (64, 64))
BUTTON_NAMES = ['start', 'start_hover', 'start_click', 'back', 'back_hover',
                'back_click', 'skip', 'skip_hover', 'skip_click', 'exit',
                'exit_hover', 'exit_click', 'check', 'check_hover',
                'check_click', 'blank']
spr_buttons = {}
for index, sprite in enumerate(sprites):
    spr_buttons[BUTTON_NAMES[index]] = sprite
```

<p>Using these button sprites as the example, I also have a button class and create a new instance for each button, passing in the name of the sprite.</p>

<p>This works fine, but I want to find a better way. Do I create a .txt file to accompany my sprite sheets and get the names from that? Or do I use a keyword + index number assigned to each sprite (e.g. <code>button_1</code>, <code>button_2</code> etc.)?</p>

<p>Here is my <code>NewButton</code> class:</p>

```import pygame

class NewButton:
    """Create and maintain a new button."""`

    def __init__(self, name, sprites, x_pos, y_pos, size):
        """Initialise a new button instance.

        :param name:    The name of the button from the dictionary.
        :param sprites: A dictionary of button sprite images.
        :param x_pos:   The x position of the button image.
        :param y_pos:   The y position of the button image.
        :param size:    The squared size of the button image.
        """
        self.img_normal = sprites[name]
        self.img_hover = sprites[name + '_hover']
        self.img_click = sprites[name + '_click']
        self.rect = pygame.Rect(x_pos, y_pos, size, size)
        self.image = self.img_normal
        self.hover = False
        self.clicked = False
        self.execute = False
        self.max_timer = 20
        self.click_timer = 0

    def update(self, delta):
        """Update the button instance.

        :param delta: A multiplier based on real time between updates.
        """
        if self.clicked:
            self.click_timer += delta
            if self.click_timer < self.max_timer / 2:
                self.image = self.img_click
            elif self.click_timer >= self.max_timer:
                self.clicked = False
                self.click_timer = 0
                self.image = self.img_normal
                self.execute = True
            else:
                self.image = self.img_normal
        else:
            mx, my = pygame.mouse.get_pos()
            if self.rect.collidepoint(mx, my):
                self.image = self.img_hover
                self.hover = True
            else:
                self.image = self.img_normal
                self.hover = False

    def click(self):
        """Set the button as being clicked."""
        self.clicked = True

    def reset(self):
        """Reset the execute status of the button."""
        self.execute = False
```

答:
You could use sequence unpacking of the sprites to assign them to the names you wish to use:</p>

```<code>sprites = load_spritesheet('spr_buttons.png', (64, 64))

start, start_hover, start_click, back, back_hover, back_click, \
skip, skip_hover, skip_click, exit, exit_hover, exit_click, \
check, check_hover, check_click, blank = sprites
</code>```

Body:
I know how to load a sprite sheet, clip the images and return a list of those images, but I like to refer to my sprites by name rather than index, to keep the code readable and manageable, but it's sometimes long and tedious writing out lists of sprite names.

I usually create a dictionary, and refer to the sprite I need by name, but I wondered if I should be hard-coding the names?

This is what I usually do:

sprites = load_spritesheet('spr_buttons.png', (64, 64))
BUTTON_NAMES = ['start', 'start_hover', 'start_click', 'back', 'back_hover',
                'back_click', 'skip', 'skip_hover', 'skip_click', 'exit',
                'exit_hover', 'exit_click', 'check', 'check_hover',
                'check_click', 'blank']
spr_buttons = {}
for index, sprite in enumerate(sprites):
    spr_buttons[BUTTON_NAMES[index]] = sprite

Using these button sprites as the example, I also have a button class and create a new instance for each button, passing in the name of the sprite.

This works fine, but I want to find a better way. Do I create a .txt file to accompany my sprite sheets and get the names from that? Or do I use a keyword + index number assigned to each sprite (e.g. button_1, button_2 etc.)?

Here is my NewButton class:

import pygame

class NewButton:
    """Create and maintain a new button."""`

    def __init__(self, name, sprites, x_pos, y_pos, size):
        """Initialise a new button instance.

        :param name:    The name of the button from the dictionary.
        :param sprites: A dictionary of button sprite images.
        :param x_pos:   The x position of the button image.
        :param y_pos:   The y position of the button image.
        :param size:    The squared size of the button image.
        """
        self.img_normal = sprites[name]
        self.img_hover = sprites[name + '_hover']
        self.img_click = sprites[name + '_click']
        self.rect = pygame.Rect(x_pos, y_pos, size, size)
        self.image = self.img_normal
        self.hover = False
        self.clicked = False
        self.execute = False
        self.max_timer = 20
        self.click_timer = 0

    def update(self, delta):
        """Update the button instance.

        :param delta: A multiplier based on real time between updates.
        """
        if self.clicked:
            self.click_timer += delta
            if self.click_timer < self.max_timer / 2:
                self.image = self.img_click
            elif self.click_timer >= self.max_timer:
                self.clicked = False
                self.click_timer = 0
                self.image = self.img_normal
                self.execute = True
            else:
                self.image = self.img_normal
        else:
            mx, my = pygame.mouse.get_pos()
            if self.rect.collidepoint(mx, my):
                self.image = self.img_hover
                self.hover = True
            else:
                self.image = self.img_normal
                self.hover = False

    def click(self):
        """Set the button as being clicked."""
        self.clicked = True

    def reset(self):
        """Reset the execute status of the button."""
        self.execute = False

Body:
You could use sequence unpacking of the sprites to assign them to the names you wish to use:

sprites = load_spritesheet('spr_buttons.png', (64, 64))

start, start_hover, start_click, back, back_hover, back_click, \
skip, skip_hover, skip_click, exit, exit_hover, exit_click, \
check, check_hover, check_click, blank = sprites


来源: stackexchange

问:
Trying to understand a recursive function to reverse a string
I can't understand why this code works. Do characters in the string get removed because they are being passed by reference? I see no decrement or such, so I find that really confusing. Also, is the string getting reversed because of the lifo nature of the function call stack?</p>

```<code> void reverse(const char * const sPtr){
   if('\0' == sPtr[0])
     return;
     else{
       reverse(&sPtr[1]);
       putchar(sPtr[0]);
    }
 }
</code>```

答:
If you input "abc", the call stack will look something like this.

```<code>reverse("abc")
    reverse("bc")
        reverse("c")
        print("c")
    print("b")
print("a")
</code>```

So each reverse call calls itself with the same string, but first character excluded, and THEN prints the first character in the string.

Do characters in the string get removed because they are being passed by reference?

There is no call by reference in C. Pointers kind of emulate it, but everything in C is passed by value. Besides, the type of the pointer const char * const says two things. First, the pointer will not get reassigned to point at anything else, but more importantly, it also says that the string will not be changed. Try adding the line sPtr[0] = 'a' somewhere, and you'll get a compiler error.

ContentLicense: CC BY-SA 4.0

Body:
I can't understand why this code works. Do characters in the string get removed because they are being passed by reference? I see no decrement or such, so I find that really confusing. Also, is the string getting reversed because of the lifo nature of the function call stack?

 void reverse(const char * const sPtr){
   if('\0' == sPtr[0])
     return;
     else{
       reverse(&sPtr[1]);
       putchar(sPtr[0]);
    }
 }

Body:
If you input "abc", the call stack will look something like this.

reverse("abc")
    reverse("bc")
        reverse("c")
        print("c")
    print("b")
print("a")

So each reverse call calls itself with the same string, but first character excluded, and THEN prints the first character in the string.

Do characters in the string get removed because they are being passed by reference?

There is no call by reference in C. Pointers kind of emulate it, but everything in C is passed by value. Besides, the type of the pointer const char * const says two things. First, the pointer will not get reassigned to point at anything else, but more importantly, it also says that the string will not be changed. Try adding the line sPtr[0] = 'a' somewhere, and you'll get a compiler error.


问:
Can i use C++ function pointers like a C#'s Action?
In C ++, I first encountered function pointers.

I tried to use this to make it similar to Action and Delegate in C #.

However, when declaring a function pointer, it is necessary to specify the type of the class in which the function exists.

ex) void (A :: * F) ();

Can I use a function pointer that can store a member function of any class?

In general, function pointers are used as shown in the code below.

```<code>class A {
public:
    void AF() { cout << "A::F" << endl; }
};

class B {
public:
    void(A::*BF)();
};

int main()
{
    A a;
    B b;

    b.BF = &A::AF;
    (a.*b.BF)();

    return 0;
}
</code>```

I want to use it like the code below.

is this possible?

Or is there something else to replace the function pointer?

```<code>class A {
public:
    void AF() { cout << "A::F" << endl; }
};

class B {
public:
    void(* BF)();
};

int main()
{
    A a;
    B b;

    b.BF = a.AF;

    return 0;
}
</code>```

I solved the question through the answer.

Thanks!

```<code>#include <functional>
#include <iostream>

class A {
public:
    void AF() { std::cout << "A::F" << std::endl; }
};

class C {
public:
    void CF() { std::cout << "C::F" << std::endl; }
};

class B {
public:
    B(){}
    std::function<void()> BF;
};

int main() {
    A a;
    C c;
    B b;
    b.BF = std::bind(&A::AF, &a);
    b.BF();
    b.BF = std::bind(&C::CF, &c);
    b.BF();

    int i;
    std::cin >> i;
    return 0;
}
</code>```

答:
Here's a C# style implementation of the accepted answer, It is memory efficient and flexible as you can construct and delegate at different points of execution which a C# developer might expect to do:</p>

```<code>#include <iostream>
#include <functional>

using namespace std;

class A {
public:
    void AF() { cout << "A::F" << endl; }
    void BF() { cout << "B::F" << endl; }
};

class B {
public:
    std::function<void()> Delegate;
};

int main() {
    A a;
    B b;

    b.Delegate = std::bind(&A::AF, &a);
    b.Delegate();

    b.Delegate = [&a] { a.BF(); };
    b.Delegate();
    return 0;
}
</code>```

Body:
In C ++, I first encountered function pointers.

I tried to use this to make it similar to Action and Delegate in C #.

However, when declaring a function pointer, it is necessary to specify the type of the class in which the function exists.

ex) void (A :: * F) ();

Can I use a function pointer that can store a member function of any class?

In general, function pointers are used as shown in the code below.

class A {
public:
    void AF() { cout << "A::F" << endl; }
};

class B {
public:
    void(A::*BF)();
};

int main()
{
    A a;
    B b;

    b.BF = &A::AF;
    (a.*b.BF)();

    return 0;
}

I want to use it like the code below.

is this possible?

Or is there something else to replace the function pointer?

class A {
public:
    void AF() { cout << "A::F" << endl; }
};

class B {
public:
    void(* BF)();
};

int main()
{
    A a;
    B b;

    b.BF = a.AF;

    return 0;
}

I solved the question through the answer.

Thanks!

#include <functional>
#include <iostream>

class A {
public:
    void AF() { std::cout << "A::F" << std::endl; }
};

class C {
public:
    void CF() { std::cout << "C::F" << std::endl; }
};

class B {
public:
    B(){}
    std::function<void()> BF;
};

int main() {
    A a;
    C c;
    B b;
    b.BF = std::bind(&A::AF, &a);
    b.BF();
    b.BF = std::bind(&C::CF, &c);
    b.BF();

    int i;
    std::cin >> i;
    return 0;
}

Body:
Here's a C# style implementation of the accepted answer, It is memory efficient and flexible as you can construct and delegate at different points of execution which a C# developer might expect to do:

#include <iostream>
#include <functional>

using namespace std;

class A {
public:
    void AF() { cout << "A::F" << endl; }
    void BF() { cout << "B::F" << endl; }
};

class B {
public:
    std::function<void()> Delegate;
};

int main() {
    A a;
    B b;

    b.Delegate = std::bind(&A::AF, &a);
    b.Delegate();

    b.Delegate = [&a] { a.BF(); };
    b.Delegate();
    return 0;
}


问:
Retrieving data from a pivot table in PHP
I'm trying to get data from a pivot table, but I haven't had any luck finding any information on how to retrieve the data.
When I look I always land up going to places that has Laravel, but I would like to do it in pure PHP.

So what I would like to do is grab the items that the user bought.
For example

```<code>User 3
order_date: 24 Feb 2018
items bought:
2
5
1

user 5
order_date: 05 May 2018
items bought:
3

user 2
order_date: 18 Oct 2018
items bought:
6
4
</code>```

Here is my items table

```<code>id| name   |description
1 | item 1 | item 1 description
2 | item 2 | item 2 description
3 | item 3 | item 3 description
4 | item 4 | item 4 description
5 | item 5 | item 5 description
6 | item 6 | item 6 description
</code>```

My pivot table

```<code>id| item_id   | order_id
1 | 2         |  1
2 | 5         |  1
3 | 1         |  1
4 | 3         |  2
5 | 6         |  3
6 | 4         |  3
</code>```

and my orders

```<code>id| order_date   | user_id
1 | 2018-02-24   | 3
2 | 2018-05-05   | 5
3 | 2018-10-18   | 2
</code>```

答: Thanks to @Dharman who posted the link to the duplicate question. I managed to solve my issue</p>

Body:
I'm trying to get data from a pivot table, but I haven't had any luck finding any information on how to retrieve the data.
When I look I always land up going to places that has Laravel, but I would like to do it in pure PHP.

So what I would like to do is grab the items that the user bought.
For example

User 3
order_date: 24 Feb 2018
items bought:
2
5
1

user 5
order_date: 05 May 2018
items bought:
3

user 2
order_date: 18 Oct 2018
items bought:
6
4

Here is my items table

id| name   |description
1 | item 1 | item 1 description
2 | item 2 | item 2 description
3 | item 3 | item 3 description
4 | item 4 | item 4 description
5 | item 5 | item 5 description
6 | item 6 | item 6 description

My pivot table

id| item_id   | order_id
1 | 2         |  1
2 | 5         |  1
3 | 1         |  1
4 | 3         |  2
5 | 6         |  3
6 | 4         |  3

and my orders

id| order_date   | user_id
1 | 2018-02-24   | 3
2 | 2018-05-05   | 5
3 | 2018-10-18   | 2


问:
Meteor package import css files from npm package that is only marked as dependency using tmeasday:check-npm-versions
Since quite some time there is this package tmeasday:check-npm-versions that allows to define an implicit npm package dependency to a Meteor package.

Use this package if you are writing an Atmosphere package that depends
  on a given npm package is installed at the app level of projects you
  are installed in.

Now I am writing a Meteor package, say me:my-package and have a dependency to an npm package, say some-package. This npm package requires me to import these styles manually.

The folder for that is located at some-package/style/main.less.

I tried to import the file within the package but it can't be imported into my package's less file:

```<code>@import "some-package/style/main";
@import "{}/some-package/style/main";
@import "node_modules/some-package/style/main";
@import "{}/node_modules/some-package/style/main";
</code>```

all throw the same error:

```<code>While processing files with less (for target web.browser):
packages/me:my-package/style.less:1: Unknown import: <one of the path's above>
</code>```

The obvious reason here: a Meteor package usually requires me to add files via api.addFiles but the package has no 'real dependency' to the npm package to import this file.

I could move the 'responsibility' of importing the styles to the application that will use 'me:my-package' because it will have to install the npm package, too.

Putting the following line into the css of the application that will use me:my-package actually works:

```<code>@import "/node_modules/some-package/style/main.less";
</code>```

But this would also force the app to install less or sass if the package uses it (as less in my case).

Somebody managed to solve this in a package-user-friendly way?

答:
After some time I came back to this issue and found an answer just by accident. It can be achieved with the dynamic-import package.

You need to add all the styles to import in an exported function that returns an array of dynamic imports.

So let's consider the hypothetical package me:mypackage:

Package.describe({
  name: 'me:mypackage',
  // ...
});

// this example uses it only on the client
// because the focus is importing styles
// but the pattern could work for other assets, too
Package.onUse(function(api) {
  api.versionsFrom('1.6');
  api.use('ecmascript', 'client');
  api.use('underscore', 'client');
  api.use('tmeasday:check-npm-versions', 'client')
  api.mainModule('mypackage.js', 'client');
});
```

<p>Note, that I use <code>api.mainModule</code> here, so we will export something. If you want to add the package to the global namespace you will have to attach the function with the dynamic imports somewhere to make it accessible.</p>

<p>In your main module you declare your npm dependencies and your dynamic styles import:</p>

<pre class="lang-js prettyprint-override"><code>import { checkNpmVersions } from 'meteor/tmeasday:check-npm-versions';
checkNpmVersions({
  'some-package': '4.x.x'
}, 'me:mypackage');

const somepackage = require('some-package)
// do whatever with some-package....

// export a function that let's your project
// to be able to just import the right style deps
export const importStyles = function() {
  return [
    import('some-package/style/main.css'),
    // ... and more if required
  ]
}
</code>```

In you project you need to add dynamic-imports and me:mypackage:

$ meteor add dynamic-imports me:mypackage
```

<p>and import it on top-level in your <code>client/main.js</code>:</p>

<pre class="lang-js prettyprint-override"><code>import { importStyles } from 'meteor/me:mypackage'
importStyles()
</code>```

Advantage:

No need to explicitly import styles in your main project

You can continue to avoid NPM.depends in your package

Just update the package if the dependent npm package changes it's structure, paths etc.

Dynamic imports return promises so you can "wait" until all dependencies are loaded

Disadvantage:

Assets are not available immediately, there may be a slight offset between loading and displaying. Sometimes you see the styles not being set for some miliseconds and you may show a loading screen / splash screen until all styles are imported

ContentLicense: CC BY-SA 3.0

Body:
Since quite some time there is this package tmeasday:check-npm-versions that allows to define an implicit npm package dependency to a Meteor package.

Use this package if you are writing an Atmosphere package that depends
  on a given npm package is installed at the app level of projects you
  are installed in.

Now I am writing a Meteor package, say me:my-package and have a dependency to an npm package, say some-package. This npm package requires me to import these styles manually.

The folder for that is located at some-package/style/main.less.

I tried to import the file within the package but it can't be imported into my package's less file:

@import "some-package/style/main";
@import "{}/some-package/style/main";
@import "node_modules/some-package/style/main";
@import "{}/node_modules/some-package/style/main";

all throw the same error:

While processing files with less (for target web.browser):
packages/me:my-package/style.less:1: Unknown import: <one of the path's above>

The obvious reason here: a Meteor package usually requires me to add files via api.addFiles but the package has no 'real dependency' to the npm package to import this file.

I could move the 'responsibility' of importing the styles to the application that will use 'me:my-package' because it will have to install the npm package, too.

Putting the following line into the css of the application that will use me:my-package actually works:

@import "/node_modules/some-package/style/main.less";

But this would also force the app to install less or sass if the package uses it (as less in my case).

Somebody managed to solve this in a package-user-friendly way?

Body:
After some time I came back to this issue and found an answer just by accident. It can be achieved with the dynamic-import package.

You need to add all the styles to import in an exported function that returns an array of dynamic imports.

So let's consider the hypothetical package me:mypackage:

Package.describe({
  name: 'me:mypackage',
  // ...
});

// this example uses it only on the client
// because the focus is importing styles
// but the pattern could work for other assets, too
Package.onUse(function(api) {
  api.versionsFrom('1.6');
  api.use('ecmascript', 'client');
  api.use('underscore', 'client');
  api.use('tmeasday:check-npm-versions', 'client')
  api.mainModule('mypackage.js', 'client');
});

Note, that I use api.mainModule here, so we will export something. If you want to add the package to the global namespace you will have to attach the function with the dynamic imports somewhere to make it accessible.

In your main module you declare your npm dependencies and your dynamic styles import:

import { checkNpmVersions } from 'meteor/tmeasday:check-npm-versions';
checkNpmVersions({
  'some-package': '4.x.x'
}, 'me:mypackage');

const somepackage = require('some-package)
// do whatever with some-package....

// export a function that let's your project
// to be able to just import the right style deps
export const importStyles = function() {
  return [
    import('some-package/style/main.css'),
    // ... and more if required
  ]
}

In you project you need to add dynamic-imports and me:mypackage:

$ meteor add dynamic-imports me:mypackage

and import it on top-level in your client/main.js:

import { importStyles } from 'meteor/me:mypackage'
importStyles()

Advantage:

No need to explicitly import styles in your main project

You can continue to avoid NPM.depends in your package

Just update the package if the dependent npm package changes it's structure, paths etc.

Dynamic imports return promises so you can "wait" until all dependencies are loaded

Disadvantage:

Assets are not available immediately, there may be a slight offset between loading and displaying. Sometimes you see the styles not being set for some miliseconds and you may show a loading screen / splash screen until all styles are imported


问:
Concatenate the two strings side by side separated by a space?
I want to concatenate two strings side by side. However, when I run my code the strings are saved one below the other. I want it to be side by side separated by a space.</p>

```<code>path = '../data/img'
mask = '../data/canny_mask'
text_file = open("train.lst", "w")
for file in os.listdir(path):
    img_name = file[:]

for file in os.listdir(mask):
    mask_name = file[:]
    text_file.write(str('data/img')+str(img_name)+'\n')+text_file.write(str('data/canny_mask')+str(mask_name)+'\n')

text_file.close()
</code>```

答:
Here, you are calling text_file.write() twice:

```<code>text_file.write(str('data/img')+str(img_name)+'\n')+text_file.write(str('data/canny_mask')+str(mask_name)+'\n')
</code>```

In the first call, there's a newline character '\n'. If you want a space instead of a newline, change the code at that point.

I also recommend to not put a + between the two calls. Write them in separate lines, or make only one call.

Body:
I want to concatenate two strings side by side. However, when I run my code the strings are saved one below the other. I want it to be side by side separated by a space.

path = '../data/img'
mask = '../data/canny_mask'
text_file = open("train.lst", "w")
for file in os.listdir(path):
    img_name = file[:]

for file in os.listdir(mask):
    mask_name = file[:]
    text_file.write(str('data/img')+str(img_name)+'\n')+text_file.write(str('data/canny_mask')+str(mask_name)+'\n')

text_file.close()

Body:
Here, you are calling text_file.write() twice:

text_file.write(str('data/img')+str(img_name)+'\n')+text_file.write(str('data/canny_mask')+str(mask_name)+'\n')

In the first call, there's a newline character '\n'. If you want a space instead of a newline, change the code at that point.

I also recommend to not put a + between the two calls. Write them in separate lines, or make only one call.


问:
Case-sensitive entity recognition
I have keywords that are all stored in lower case, e.g. "discount nike shoes", that I am trying to perform entity extraction on. The issue I've run into is that spaCy seems to be case sensitive when it comes to NER. Mind you , I don't think that this is spaCy specific.

When I run...

```<code>doc = nlp(u"i love nike shoes from the uk")

for ent in doc.ents:
    print(ent.text, ent.start_char, ent.end_char, ent.label_)
</code>```

... nothing is returned.

When I run...

```<code>doc = nlp(u"i love Nike shoes from the Uk")

for ent in doc.ents:
    print(ent.text, ent.start_char, ent.end_char, ent.label_)
</code>```

I get the following results...

```<code>Nike 7 11 ORG
Uk 25 27 GPE
</code>```

Should I just title case everything? Is there another workaround that I could use?

答:
spaCy's pre-trained statistical models were trained on a large corpus of general news and web text. This means that the entity recognizer has likely only seen very few all-lowercase examples, because that's much less common in those types of texts. In English, capitalisation is also a strong indicator for a named entitiy (unlike German, where all nouns are typically capitalised), so the model probably tends to pay more attention to that.

If you're working with text that doesn't have proper capitalisation, you probably want to fine-tune the model to be less sensitive here. See the docs on updating the named entity recognizer for more details and code examples.

Producing the training examples will hopefully not be very difficult, because you can use existing annotations and datasets, or create one using the pre-trained model, and then lowercase everything. For example, you could take text with proper capitalisation, run the model over it and extract all entitiy spans in the text. Next, you lowercase all the texts, and update the model with the new data. Make sure to also mix in text with proper capitalisation, because you don't want the model to learn something like "Everything is lowercase now! Capitalisation doesn't exist anymore!".

Btw, if you have entities that can be defined using a list or set of rules, you might also want to check out the EntityRuler component. It can be combined with the statistical entity recognizer and will let you pass in a dictionary of exact matches or abstract token patterns that can be case-insensitive. For instance, [{"lower": "nike"}] would match one token whose lowercase form is "nike" – so "NIKE", "Nike", "nike", "NiKe" etc.

Title: Case-sensitive entity recognition

Body:
I have keywords that are all stored in lower case, e.g. "discount nike shoes", that I am trying to perform entity extraction on. The issue I've run into is that spaCy seems to be case sensitive when it comes to NER. Mind you , I don't think that this is spaCy specific.

When I run...

doc = nlp(u"i love nike shoes from the uk")

for ent in doc.ents:
    print(ent.text, ent.start_char, ent.end_char, ent.label_)

... nothing is returned.

When I run...

doc = nlp(u"i love Nike shoes from the Uk")

for ent in doc.ents:
    print(ent.text, ent.start_char, ent.end_char, ent.label_)

I get the following results...

Nike 7 11 ORG
Uk 25 27 GPE

Should I just title case everything? Is there another workaround that I could use?


问:
Whats the standard way to manage many to many relationships using checkboxes on rails these days?
Forgive me if this is a silly question because i'm still fairly new to rails,

Whats the standard way to manage many to many relationships using checkboxes on rails these days?

Anything ive seen requires either patching with method_missing or using a after_save callback..

Is there an automatic way of doing it in rails 3?

(Using a relationship model and not HABTM)

Thanks

Daniel

答:
I believe a has_many through is what you want, as HABTM is deprecated from what I understand.

For example, I have Devise implemented into my project with users, and users can have many roles, roles has many users. There is a table called "assignments" (with user_id and role_id columns) that links the users and roles tables.

So my models look something like...

user.rb

```<code>has_many :assignments, :dependent => :destroy
has_many :roles, :through => :assignments
</code>```

assignment.rb

```<code>belongs_to :user
belongs_to :role
</code>```

role.rb

```<code>has_many :assignments
has_many :users, :through => :assignments
</code>```

Then in my view _form.html.erb for Users, I have

```<code><% for role in Role.find(:all) %>
  <%= check_box_tag "user[role_ids][]", role.id, @user.roles.include?(role), :multiple => true, :include_blank => TRUE %>
  <%= role.name %>
<% end %>
</code>```

So when the user is saved with the appropriate checkboxes, the relationships are taken care of. Anyway, I don't recall the episode number, but there is a Railscast that I believe I got this from.

Body:
I believe a has_many through is what you want, as HABTM is deprecated from what I understand.

For example, I have Devise implemented into my project with users, and users can have many roles, roles has many users. There is a table called "assignments" (with user_id and role_id columns) that links the users and roles tables.

So my models look something like...

user.rb

has_many :assignments, :dependent => :destroy
has_many :roles, :through => :assignments

assignment.rb

belongs_to :user
belongs_to :role

role.rb

has_many :assignments
has_many :users, :through => :assignments

Then in my view _form.html.erb for Users, I have

<% for role in Role.find(:all) %>
  <%= check_box_tag "user[role_ids][]", role.id, @user.roles.include?(role), :multiple => true, :include_blank => TRUE %>
  <%= role.name %>
<% end %>

So when the user is saved with the appropriate checkboxes, the relationships are taken care of. Anyway, I don't recall the episode number, but there is a Railscast that I believe I got this from.


答:
First of all you've to consider, that the pygame.sprite.Sprite in pygame.sprite.Group are not ordered. It is not guaranteed, that the sprites are enumerated in the same order when they group is iterated, as they were append to the group.

See the documentation of pygame.sprite.Group:

The Sprites in the Group are not ordered, so drawing and iterating the Sprites is in no particular order.

I recommend to define enums which are naming the buttons:

from enum import Enum
class Button(Enum):
    start = 0
    start_hover = 1
    # [...]
```

<p>Create a dictionary where each buttons is associated to an enumerator:</p>

<pre class="lang-py prettyprint-override"><code>spr_buttons = dict(zip(Button, sprites))
</code>```

So a button can be accessed by e.g.:

sprite = spr_buttons[Button.start]
```

<p>or even by using <code>getattr</code> and a name:</p>

<pre class="lang-py prettyprint-override"><code>sprite = spr_buttons[getattr(Button, "start")]
</code>```

Alternatively you can create a list of buttons and access by the .value property of the enumerator, which is the index of the list:

spr_buttons = list(sprites)
sprite = spr_buttons[Button.start_hover.value]
```

Title: How should I be assigning names to sprites from a sprite sheet?

Body:
First of all you've to consider, that the pygame.sprite.Sprite in pygame.sprite.Group are not ordered. It is not guaranteed, that the sprites are enumerated in the same order when they group is iterated, as they were append to the group.

See the documentation of pygame.sprite.Group:

The Sprites in the Group are not ordered, so drawing and iterating the Sprites is in no particular order.

I recommend to define enums which are naming the buttons:

from enum import Enum
class Button(Enum):
    start = 0
    start_hover = 1
    # [...]

Create a dictionary where each buttons is associated to an enumerator:

spr_buttons = dict(zip(Button, sprites))

So a button can be accessed by e.g.:

sprite = spr_buttons[Button.start]

or even by using getattr and a name:

sprite = spr_buttons[getattr(Button, "start")]

Alternatively you can create a list of buttons and access by the .value property of the enumerator, which is the index of the list:

spr_buttons = list(sprites)
sprite = spr_buttons[Button.start_hover.value]


问:
How to calculate profit formula with multiple user input text
I'm trying to make a simple calculation formula but I don't know how to add all the variables simultaneously.

I already tried this but it is giving an error and is being super inaccurate.

```<code>var fee :Int = Int(0.866)
var otherFee:Int = Int(0.30)

@IBAction func calculateProfit(_ sender: Any) {
    let sold = Int(soldTextField.text!)!
    let paid = Int(paidTextField.text!)!
    let shipping = Int(shippingTextField.text!)!

    profitTotal.text = String(sold * fee - otherFee - paid - shipping )
}
</code>```

I suspect that when I hit the button it will multiply, subtract, subtract simultaneously.

答:
You need to provide Default value also for Textfield text because Force Unwrapping soldTextfield.text lead to crashes if there is no text inside textfield.

```<code>Double(soldTextField.text ?? "0") ?? 0
</code>```

Same also for other textfields

Body:
I'm trying to make a simple calculation formula but I don't know how to add all the variables simultaneously.

I already tried this but it is giving an error and is being super inaccurate.

var fee :Int = Int(0.866)
var otherFee:Int = Int(0.30)

@IBAction func calculateProfit(_ sender: Any) {
    let sold = Int(soldTextField.text!)!
    let paid = Int(paidTextField.text!)!
    let shipping = Int(shippingTextField.text!)!

    profitTotal.text = String(sold * fee - otherFee - paid - shipping )
}

I suspect that when I hit the button it will multiply, subtract, subtract simultaneously.

Body:
You need to provide Default value also for Textfield text because Force Unwrapping soldTextfield.text lead to crashes if there is no text inside textfield.

Double(soldTextField.text ?? "0") ?? 0

Same also for other textfields


问:
Excel macro for data reformatting
I need to reformat a 33500 row of data in excel. I am trying to write a macro that would do this for me.

I have put some nested loop to solve the issue

```<code>Dim i As Integer
Dim m As Integer
Dim n As Integer
Dim K As Integer
Dim p As Integer
Dim c As Integer

For c = 0 To 10

    For n = 5 To 10

        K = 14 + 7 * (n - 5)

        For i = 0 To 7
            m = 14 + 8 * c
            ActiveSheet.Cells(m + i, n).Select
            Selection.Copy

            ActiveSheet.Cells(K + i, 37).Select
            ActiveSheet.Paste
        Next i

    Next n

Next c
</code>```

I am stuck at how to get this operation done for 32500 rows

答:
Revised the code according to the comment and now working like a charm. Thank you so much

Dim i As Integer
Dim m As Integer
Dim n As Integer
Dim K As Integer
Dim p As Integer

For i = 0 To 121

m = 14
   For n = 5 To 35

ActiveSheet.Range(Cells(m + i * 8, n), Cells(m + i * 8 + 7, n)).Copy

Range("AK" & Rows.Count).End(xlUp).Offset(1).PasteSpecial xlValues

```<code>Next n
</code>```

Next i

End Sub

Title: Excel macro for data reformatting

Body:
I need to reformat a 33500 row of data in excel. I am trying to write a macro that would do this for me.

I have put some nested loop to solve the issue

Dim i As Integer
Dim m As Integer
Dim n As Integer
Dim K As Integer
Dim p As Integer
Dim c As Integer

For c = 0 To 10

    For n = 5 To 10

        K = 14 + 7 * (n - 5)

        For i = 0 To 7
            m = 14 + 8 * c
            ActiveSheet.Cells(m + i, n).Select
            Selection.Copy

            ActiveSheet.Cells(K + i, 37).Select
            ActiveSheet.Paste
        Next i

    Next n

Next c

I am stuck at how to get this operation done for 32500 rows

Body:
Revised the code according to the comment and now working like a charm. Thank you so much

Dim i As Integer
Dim m As Integer
Dim n As Integer
Dim K As Integer
Dim p As Integer

For i = 0 To 121

m = 14
   For n = 5 To 35

ActiveSheet.Range(Cells(m + i * 8, n), Cells(m + i * 8 + 7, n)).Copy

Range("AK" & Rows.Count).End(xlUp).Offset(1).PasteSpecial xlValues

Next n

Next i

End Sub


问:
 not working in aframe 0.9.2
I try to change the radius of a nested child element with animation. My code looks like this:

```

<p>in my react code I catch the mouseOver event from the parent</p>

<pre class="lang-js prettyprint-override"><code>const onMouseEnter = (e) => {
   const innerSphere = e.target.querySelector('#inner-sphere');
   innerSphere.emit("fillSphere");
}
</code>```

but nothing happens. Or is there another way to animate a child entity. For example with the Aframe animation attribute. I could not find anything in the A-Frame documentation.

I use A-Frame in Version 0.9.2

答:
The  element was deprecated in a-frame 0.9.0 in favor of the animation component.

It should look a little bit like this:

```<code><a-sphere id="outer-sphere" radius="0.6" material="color:white;opacity: 0.6">
    <a-sphere id="inner-sphere" radius="0.1" material="color:red; opacity: 0.6"
              animation="property: radius; from: 0.1; to: 0.6: startEvents: fillSphere">
    </a-sphere>
</a-sphere>
</code>```

Title: <a-animation> not working in aframe 0.9.2

Body:
I try to change the radius of a nested child element with animation. My code looks like this:

in my react code I catch the mouseOver event from the parent

const onMouseEnter = (e) => {
   const innerSphere = e.target.querySelector('#inner-sphere');
   innerSphere.emit("fillSphere");
}

but nothing happens. Or is there another way to animate a child entity. For example with the Aframe animation attribute. I could not find anything in the A-Frame documentation.

I use A-Frame in Version 0.9.2

Body:
The <a-animation> element was deprecated in a-frame 0.9.0 in favor of the animation component.

It should look a little bit like this:

<a-sphere id="outer-sphere" radius="0.6" material="color:white;opacity: 0.6">
    <a-sphere id="inner-sphere" radius="0.1" material="color:red; opacity: 0.6"
              animation="property: radius; from: 0.1; to: 0.6: startEvents: fillSphere">
    </a-sphere>
</a-sphere>


问:
The objects aren't displayed: E/RecyclerView: No adapter attached; skipping layout 2 Firestore Query
First I do a Query from Firestore to take some data.
I have 2 RecyclerViews.
In the first one, I show data from an SQLite database.
In the second one, I can't show data from a Firestore Query (the objects aren't displayed).

The problem, I think, is because when I want to fill the second RecyclerView the data from Firestore Query haven't arrived yet.

Java class:

```<code>package com.android.fworkout.fworkout;

import android.content.Context;
import android.content.SharedPreferences;
import android.database.Cursor;
import android.database.sqlite.SQLiteDatabase;
import android.os.Bundle;
import android.support.annotation.NonNull;
import android.support.v7.app.AppCompatActivity;
import android.support.v7.widget.LinearLayoutManager;
import android.support.v7.widget.RecyclerView;
import android.util.Log;
import android.view.View;
import android.widget.Button;
import android.widget.EditText;
import android.widget.Toast;

import com.firebase.ui.firestore.FirestoreRecyclerOptions;
import com.google.android.gms.tasks.OnCompleteListener;
import com.google.android.gms.tasks.OnFailureListener;
import com.google.android.gms.tasks.OnSuccessListener;
import com.google.android.gms.tasks.Task;
import com.google.firebase.firestore.DocumentSnapshot;
import com.google.firebase.firestore.FirebaseFirestore;
import com.google.firebase.firestore.Query;

import java.util.ArrayList;

public class EntrenamientoEditarDetalleActivity extends AppCompatActivity {

    //Recuperar el id del entrenamiento
    //Take training id
    String idEntrenamiento = "";

    //Contexto
    //Context
    Context context;

    //Recuperar ejercicios
    //Take exercises
    static ArrayList<String> listaIdEjercicios = new ArrayList<>();
    ArrayList<Ejercicio> listaEjercicios;

    //Base de datos
    //Database
    EjerciciosDBHelper ejercDB;

    //Recuperar jugadores
    //Take players
    static ArrayList<String> listaApodos = new ArrayList<>();
    ListaJugadoresEntrenamientoAdapter ljeAdapter;

    //Firestore
    //Firestore
    FirebaseFirestore rootRef = FirebaseFirestore.getInstance();
    SharedPreferences sharedPref;

    //XML
    //XML
    EditText etHora, etFecha, etOpinion;
    Button bGuardar;
    RecyclerView rvEjercicios, rvJugadores;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_entrenamiento_editar_detalle);

        //Coger el contexto de la Activity
        //Take the context of the Activity
        context = this;

        //Recuperar el id del entrenamiento
        //Take training id
        Bundle extras = getIntent().getExtras();
        if (extras != null) {
            idEntrenamiento = extras.getString("idEntrenamientoEditar");
        }

        //Limpiar las listas antes de recuperar los datos
        //Clean the lists before recovering the data
        listaIdEjercicios.clear();
        listaApodos.clear();

        //XML
        //XML
        etHora = (EditText) findViewById(R.id.etHoraEntrenamientoEditarDetalle);
        etFecha = (EditText) findViewById(R.id.etFechaEntrenamientoEditarDetalle);
        etOpinion = (EditText) findViewById(R.id.etOpinionEntrenamientoEditarDetalle);
        bGuardar = (Button) findViewById(R.id.bGuardarEntrenamientoEditarDetalle);
        rvJugadores = (RecyclerView) findViewById(R.id.rvJugadoresEntrenamientoEditarDetalle);
        rvEjercicios = (RecyclerView) findViewById(R.id.rvEjerciciosEntrenamientoEditarDetalle);

        //Recuperar id de mi equipo
        //Take id of my team
        sharedPref = getSharedPreferences("PreferenciasFWO", Context.MODE_PRIVATE);

        //FirebaseFirestore rootRef = FirebaseFirestore.getInstance();
        rootRef.collection("equipos").document(sharedPref.getString("idEquipo", "")).collection("entrenamientos").document(idEntrenamiento)
                .get().addOnCompleteListener(new OnCompleteListener<DocumentSnapshot>() {
            @Override
            public void onComplete(@NonNull Task<DocumentSnapshot> task) {
                if (task.isSuccessful()) {
                    DocumentSnapshot document = task.getResult();
                    Log.e("FUNCIONA", document.getId() + " => " + document.getData());
                    //Recuperar fecha
                    //Take date
                    etFecha.setText(String.valueOf(document.getData().get("fecha")));
                    //Recuperar hora
                    //Take hour
                    etHora.setText(String.valueOf(document.getData().get("hora")));
                    //Recuperar ejercicios seleccionados
                    //Take selected exercises
                    listaIdEjercicios = (ArrayList<String>) document.getData().get("ejercicios");
                    //Recuperar opinión
                    //Take opinion
                    etOpinion.setText((String) document.getData().get("opinion"));
                    //Recuperar jugadores
                    //Take players
                    listaApodos = (ArrayList<String>) document.getData().get("jugadores");
                    //Log.e("APODOS:", "" + listaApodos.size());

                    //Consultar y mostrar ejercicios
                    //Consult and show exercises
                    ejercDB = new EjerciciosDBHelper(context);
                    listaEjercicios = new ArrayList<>();
                    LinearLayoutManager layoutManager = new LinearLayoutManager(context, LinearLayoutManager.VERTICAL, false);
                    rvEjercicios.setLayoutManager(layoutManager);
                    //Añadir ejercicios desde la base de datos local
                    //Add exercises from the local database
                    consultarListaEjercicios();
                    ListaEjerciciosAdapter adapter = new ListaEjerciciosAdapter(listaEjercicios);
                    rvEjercicios.setAdapter(adapter);

                    /*
                     *
                     * NO FUNCIONA       IT DOESN'T WORK
                     *     |||                 |||
                     *     |||                 |||
                     *     |||                 |||
                     *     VVV                 VVV
                     */
                    //Recuperar jugadores
                    //Take players
                    //Cargar datos de mi equipo
                    //Take players of my team
                    Query query = rootRef.collection("equipos").document(sharedPref.getString("idEquipo", "")).collection("jugadores")
                            .orderBy("apodo", Query.Direction.ASCENDING);

                    FirestoreRecyclerOptions<Jugador> options = new FirestoreRecyclerOptions.Builder<Jugador>()
                            .setQuery(query, Jugador.class)
                            .build();
                    //Mostrar jugadores
                    //Show players
                    LinearLayoutManager llm = new LinearLayoutManager(context, LinearLayoutManager.VERTICAL, false);
                    rvJugadores.setLayoutManager(llm);
                    ljeAdapter = new ListaJugadoresEntrenamientoAdapter(options);
                    rvJugadores.setHasFixedSize(true);
                    rvJugadores.setAdapter(ljeAdapter);

                } else {
                    //Log.e("ERR56", "768");
                }
            }
        });

        bGuardar.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                //Guardar todo
                //Save all
                //FirebaseFirestore rootRef = FirebaseFirestore.getInstance();
                rootRef.collection("equipos").document(sharedPref.getString("idEquipo", "")).collection("entrenamientos").document(idEntrenamiento)
                        .update("fecha", etFecha.getText().toString(),
                                "hora", etHora.getText().toString(),
                                "opinion", etOpinion.getText().toString(),
                                "jugadores", listaApodos,
                                "ejercicios", listaIdEjercicios)
                        .addOnSuccessListener(new OnSuccessListener<Void>() {
                            @Override
                            public void onSuccess(Void aVoid) {
                                //Cerrar la Activity
                                //Close the Activity
                                finish();
                            }
                        })
                        .addOnFailureListener(new OnFailureListener() {
                            @Override
                            public void onFailure(@NonNull Exception e) {
                                //Avisar del fallo
                                //Warn of the failure
                                Toast.makeText(context, "ERROR", Toast.LENGTH_SHORT).show();
                            }
                        });
                //Limpiar las listas después de guardar los datos
                //Clean the lists after saving the data
                listaIdEjercicios.clear();
                listaApodos.clear();
            }
        });
    }

    private void consultarListaEjercicios() {
        SQLiteDatabase sqlLiteDB = ejercDB.getWritableDatabase();
        String query = "SELECT id AS id, titulo AS titulo, duracion AS duracion, tipo AS tipo FROM ejercicios;";
        Cursor cursor = sqlLiteDB.rawQuery(query, null);

        while (cursor.moveToNext()) {
            Ejercicio ejercicio = new Ejercicio();
            ejercicio.id = String.valueOf(cursor.getInt(0));
            ejercicio.titulo = cursor.getString(1);
            ejercicio.duracion = cursor.getString(2);
            ejercicio.tipo = cursor.getString(3);

            listaEjercicios.add(ejercicio);
        }
    }

}
</code>```

Adapter:

```<code>package com.android.fworkout.fworkout;

import android.content.Context;
import android.support.annotation.NonNull;
import android.support.v7.widget.RecyclerView;
import android.util.Log;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.Button;
import android.widget.LinearLayout;
import android.widget.TextView;

import com.firebase.ui.firestore.FirestoreRecyclerAdapter;
import com.firebase.ui.firestore.FirestoreRecyclerOptions;

public class ListaJugadoresEntrenamientoAdapter extends FirestoreRecyclerAdapter<Jugador, ListaJugadoresEntrenamientoAdapter.JugadorEntrenamientoViewHolder> {

    public ListaJugadoresEntrenamientoAdapter(@NonNull FirestoreRecyclerOptions<Jugador> options) {
        super(options);
    }

    @NonNull
    @Override
    public JugadorEntrenamientoViewHolder onCreateViewHolder(@NonNull ViewGroup viewGroup, int i) {
        View v = LayoutInflater.from(viewGroup.getContext()).inflate(R.layout.elemento_lista_jugadores_entrenamiento_adapter, viewGroup, false);
        return new ListaJugadoresEntrenamientoAdapter.JugadorEntrenamientoViewHolder(v);
    }

    @Override
    protected void onBindViewHolder(@NonNull JugadorEntrenamientoViewHolder holder, int position, @NonNull Jugador model) {
        String apodoJugador = model.getApodo();
        holder.tvApodo.setText(apodoJugador);
        Log.e("APODOJUGADOR", model.getApodo());

        if (model.getLesionado().equalsIgnoreCase("si")) {
            holder.llElementos.setBackgroundColor(0xFF75151E);
        } else {
            if (model.getSancionado().equalsIgnoreCase("si")) {
                holder.llElementos.setBackgroundColor(0xFF0E294B);
            } else {
                holder.llElementos.setBackgroundColor(0xFF57A639);
            }
        }
        for (int i = 0; i < EntrenamientoEditarDetalleActivity.listaApodos.size(); i++) {
            if (EntrenamientoEditarDetalleActivity.listaApodos.get(i).equalsIgnoreCase(apodoJugador)) {
                holder.bAnhadir.setText("Eliminar");
                holder.anhadido = true;
                break;
            }
        }

        holder.setOnClickListeners();
    }

    public class JugadorEntrenamientoViewHolder extends RecyclerView.ViewHolder implements View.OnClickListener {

        Context context;
        TextView tvApodo;
        Button bAnhadir;
        LinearLayout llElementos;

        boolean anhadido = false;

        public JugadorEntrenamientoViewHolder(@NonNull View itemView) {
            super(itemView);
            context = itemView.getContext();
            llElementos = (LinearLayout) itemView.findViewById(R.id.llJugadorElementoSeleccionJugadorEntrenamiento);
            tvApodo = (TextView) itemView.findViewById(R.id.tvApodoJugadorElementoSeleccionJugadorEntrenamiento);
            bAnhadir = (Button) itemView.findViewById(R.id.bAnhadirJugadorElementoSeleccionJugadorEntrenamiento);
        }

        public void setOnClickListeners() {
            bAnhadir.setOnClickListener(this);
        }

        @Override
        public void onClick(View v) {
            if (anhadido) {
                for (int i = 0; i < EntrenamientoEditarDetalleActivity.listaApodos.size(); i++) {
                    if (EntrenamientoEditarDetalleActivity.listaApodos.get(i).equalsIgnoreCase(tvApodo.getText().toString())) {
                        EntrenamientoEditarDetalleActivity.listaApodos.remove(i);
                        bAnhadir.setText("Añadir");
                        anhadido = false;
                        break;
                    }
                }
            } else {
                EntrenamientoEditarDetalleActivity.listaApodos.add(tvApodo.getText().toString());
                bAnhadir.setText("Eliminar");
                anhadido = true;
            }
        }
    }
}
</code>```

XML:

```<code><?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:orientation="vertical"
    tools:context=".EntrenamientoEditarDetalleActivity">

    <GridLayout
        android:id="@+id/glDatosEntrenamientoEditarDetalle"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:layout_margin="15dp"
        android:layout_marginBottom="10dp"
        android:alignmentMode="alignMargins"
        android:columnCount="2"
        android:columnOrderPreserved="false"
        android:rowCount="3">

        <!-- Día -->
        <!-- Day -->
        <TextView
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:text="@string/Fecha" />

        <EditText
            android:id="@+id/etFechaEntrenamientoEditarDetalle"
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:hint="@string/Fecha"
            android:inputType="date" />

        <!-- Hora -->
        <!-- Hour -->
        <TextView
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:text="@string/Hora" />

        <EditText
            android:id="@+id/etHoraEntrenamientoEditarDetalle"
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:hint="@string/Hora"
            android:inputType="time" />

        <!-- Opinión -->
        <!-- Opinion -->
        <TextView
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:text="@string/Opinion" />

        <EditText
            android:id="@+id/etOpinionEntrenamientoEditarDetalle"
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:hint="@string/Opinion" />

    </GridLayout>

    <!-- Jugadores y Ejercicios -->
    <!-- Players and Exercises -->
    <LinearLayout
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:layout_above="@id/bGuardarEntrenamientoEditarDetalle"
        android:layout_below="@+id/glDatosEntrenamientoEditarDetalle"
        android:orientation="vertical">

        <!-- Jugadores -->
        <!-- Players -->
        <TextView
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:gravity="center"
            android:text="@string/Jugadores" />

        <android.support.v7.widget.RecyclerView
            android:id="@+id/rvJugadoresEntrenamientoEditarDetalle"
            android:layout_width="match_parent"
            android:layout_height="0dp"
            android:layout_weight="1" />

        <!-- Ejercicios -->
        <!-- Exercises -->
        <TextView
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:gravity="center"
            android:text="@string/Ejercicios" />

        <android.support.v7.widget.RecyclerView
            android:id="@+id/rvEjerciciosEntrenamientoEditarDetalle"
            android:layout_width="match_parent"
            android:layout_height="0dp"
            android:layout_weight="1" />

    </LinearLayout>

    <!-- Guardar -->
    <!-- To save -->
    <Button
        android:id="@+id/bGuardarEntrenamientoEditarDetalle"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_alignParentBottom="true"
        android:layout_centerInParent="true"
        android:text="@string/guardar" />
</RelativeLayout>
</code>```

ERROR:

```<code>E/RecyclerView: No adapter attached; skipping layout
</code>```

答:
I solved, the adapter didn't listen to the data but if you force to listen to the new data it works:

```<code>                //Mostrar jugadores
                //Show players
                LinearLayoutManager llm = new LinearLayoutManager(context, LinearLayoutManager.VERTICAL, false);
                rvJugadores.setLayoutManager(llm);
                ljeAdapter = new ListaJugadoresEntrenamientoAdapter(options);
                rvJugadores.setHasFixedSize(true);
                rvJugadores.setAdapter(ljeAdapter);
                ljeAdapter.startListening();
</code>```

Body:
First I do a Query from Firestore to take some data.
I have 2 RecyclerViews.
In the first one, I show data from an SQLite database.
In the second one, I can't show data from a Firestore Query (the objects aren't displayed).

The problem, I think, is because when I want to fill the second RecyclerView the data from Firestore Query haven't arrived yet.

Java class:

package com.android.fworkout.fworkout;

import android.content.Context;
import android.content.SharedPreferences;
import android.database.Cursor;
import android.database.sqlite.SQLiteDatabase;
import android.os.Bundle;
import android.support.annotation.NonNull;
import android.support.v7.app.AppCompatActivity;
import android.support.v7.widget.LinearLayoutManager;
import android.support.v7.widget.RecyclerView;
import android.util.Log;
import android.view.View;
import android.widget.Button;
import android.widget.EditText;
import android.widget.Toast;

import com.firebase.ui.firestore.FirestoreRecyclerOptions;
import com.google.android.gms.tasks.OnCompleteListener;
import com.google.android.gms.tasks.OnFailureListener;
import com.google.android.gms.tasks.OnSuccessListener;
import com.google.android.gms.tasks.Task;
import com.google.firebase.firestore.DocumentSnapshot;
import com.google.firebase.firestore.FirebaseFirestore;
import com.google.firebase.firestore.Query;

import java.util.ArrayList;

public class EntrenamientoEditarDetalleActivity extends AppCompatActivity {

    //Recuperar el id del entrenamiento
    //Take training id
    String idEntrenamiento = "";

    //Contexto
    //Context
    Context context;

    //Recuperar ejercicios
    //Take exercises
    static ArrayList<String> listaIdEjercicios = new ArrayList<>();
    ArrayList<Ejercicio> listaEjercicios;

    //Base de datos
    //Database
    EjerciciosDBHelper ejercDB;

    //Recuperar jugadores
    //Take players
    static ArrayList<String> listaApodos = new ArrayList<>();
    ListaJugadoresEntrenamientoAdapter ljeAdapter;

    //Firestore
    //Firestore
    FirebaseFirestore rootRef = FirebaseFirestore.getInstance();
    SharedPreferences sharedPref;

    //XML
    //XML
    EditText etHora, etFecha, etOpinion;
    Button bGuardar;
    RecyclerView rvEjercicios, rvJugadores;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_entrenamiento_editar_detalle);

        //Coger el contexto de la Activity
        //Take the context of the Activity
        context = this;

        //Recuperar el id del entrenamiento
        //Take training id
        Bundle extras = getIntent().getExtras();
        if (extras != null) {
            idEntrenamiento = extras.getString("idEntrenamientoEditar");
        }

        //Limpiar las listas antes de recuperar los datos
        //Clean the lists before recovering the data
        listaIdEjercicios.clear();
        listaApodos.clear();

        //XML
        //XML
        etHora = (EditText) findViewById(R.id.etHoraEntrenamientoEditarDetalle);
        etFecha = (EditText) findViewById(R.id.etFechaEntrenamientoEditarDetalle);
        etOpinion = (EditText) findViewById(R.id.etOpinionEntrenamientoEditarDetalle);
        bGuardar = (Button) findViewById(R.id.bGuardarEntrenamientoEditarDetalle);
        rvJugadores = (RecyclerView) findViewById(R.id.rvJugadoresEntrenamientoEditarDetalle);
        rvEjercicios = (RecyclerView) findViewById(R.id.rvEjerciciosEntrenamientoEditarDetalle);

        //Recuperar id de mi equipo
        //Take id of my team
        sharedPref = getSharedPreferences("PreferenciasFWO", Context.MODE_PRIVATE);

        //FirebaseFirestore rootRef = FirebaseFirestore.getInstance();
        rootRef.collection("equipos").document(sharedPref.getString("idEquipo", "")).collection("entrenamientos").document(idEntrenamiento)
                .get().addOnCompleteListener(new OnCompleteListener<DocumentSnapshot>() {
            @Override
            public void onComplete(@NonNull Task<DocumentSnapshot> task) {
                if (task.isSuccessful()) {
                    DocumentSnapshot document = task.getResult();
                    Log.e("FUNCIONA", document.getId() + " => " + document.getData());
                    //Recuperar fecha
                    //Take date
                    etFecha.setText(String.valueOf(document.getData().get("fecha")));
                    //Recuperar hora
                    //Take hour
                    etHora.setText(String.valueOf(document.getData().get("hora")));
                    //Recuperar ejercicios seleccionados
                    //Take selected exercises
                    listaIdEjercicios = (ArrayList<String>) document.getData().get("ejercicios");
                    //Recuperar opinión
                    //Take opinion
                    etOpinion.setText((String) document.getData().get("opinion"));
                    //Recuperar jugadores
                    //Take players
                    listaApodos = (ArrayList<String>) document.getData().get("jugadores");
                    //Log.e("APODOS:", "" + listaApodos.size());

                    //Consultar y mostrar ejercicios
                    //Consult and show exercises
                    ejercDB = new EjerciciosDBHelper(context);
                    listaEjercicios = new ArrayList<>();
                    LinearLayoutManager layoutManager = new LinearLayoutManager(context, LinearLayoutManager.VERTICAL, false);
                    rvEjercicios.setLayoutManager(layoutManager);
                    //Añadir ejercicios desde la base de datos local
                    //Add exercises from the local database
                    consultarListaEjercicios();
                    ListaEjerciciosAdapter adapter = new ListaEjerciciosAdapter(listaEjercicios);
                    rvEjercicios.setAdapter(adapter);

                    /*
                     *
                     * NO FUNCIONA       IT DOESN'T WORK
                     *     |||                 |||
                     *     |||                 |||
                     *     |||                 |||
                     *     VVV                 VVV
                     */
                    //Recuperar jugadores
                    //Take players
                    //Cargar datos de mi equipo
                    //Take players of my team
                    Query query = rootRef.collection("equipos").document(sharedPref.getString("idEquipo", "")).collection("jugadores")
                            .orderBy("apodo", Query.Direction.ASCENDING);

                    FirestoreRecyclerOptions<Jugador> options = new FirestoreRecyclerOptions.Builder<Jugador>()
                            .setQuery(query, Jugador.class)
                            .build();
                    //Mostrar jugadores
                    //Show players
                    LinearLayoutManager llm = new LinearLayoutManager(context, LinearLayoutManager.VERTICAL, false);
                    rvJugadores.setLayoutManager(llm);
                    ljeAdapter = new ListaJugadoresEntrenamientoAdapter(options);
                    rvJugadores.setHasFixedSize(true);
                    rvJugadores.setAdapter(ljeAdapter);

                } else {
                    //Log.e("ERR56", "768");
                }
            }
        });

        bGuardar.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                //Guardar todo
                //Save all
                //FirebaseFirestore rootRef = FirebaseFirestore.getInstance();
                rootRef.collection("equipos").document(sharedPref.getString("idEquipo", "")).collection("entrenamientos").document(idEntrenamiento)
                        .update("fecha", etFecha.getText().toString(),
                                "hora", etHora.getText().toString(),
                                "opinion", etOpinion.getText().toString(),
                                "jugadores", listaApodos,
                                "ejercicios", listaIdEjercicios)
                        .addOnSuccessListener(new OnSuccessListener<Void>() {
                            @Override
                            public void onSuccess(Void aVoid) {
                                //Cerrar la Activity
                                //Close the Activity
                                finish();
                            }
                        })
                        .addOnFailureListener(new OnFailureListener() {
                            @Override
                            public void onFailure(@NonNull Exception e) {
                                //Avisar del fallo
                                //Warn of the failure
                                Toast.makeText(context, "ERROR", Toast.LENGTH_SHORT).show();
                            }
                        });
                //Limpiar las listas después de guardar los datos
                //Clean the lists after saving the data
                listaIdEjercicios.clear();
                listaApodos.clear();
            }
        });
    }

    private void consultarListaEjercicios() {
        SQLiteDatabase sqlLiteDB = ejercDB.getWritableDatabase();
        String query = "SELECT id AS id, titulo AS titulo, duracion AS duracion, tipo AS tipo FROM ejercicios;";
        Cursor cursor = sqlLiteDB.rawQuery(query, null);

        while (cursor.moveToNext()) {
            Ejercicio ejercicio = new Ejercicio();
            ejercicio.id = String.valueOf(cursor.getInt(0));
            ejercicio.titulo = cursor.getString(1);
            ejercicio.duracion = cursor.getString(2);
            ejercicio.tipo = cursor.getString(3);

            listaEjercicios.add(ejercicio);
        }
    }

}

Adapter:

package com.android.fworkout.fworkout;

import android.content.Context;
import android.support.annotation.NonNull;
import android.support.v7.widget.RecyclerView;
import android.util.Log;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.Button;
import android.widget.LinearLayout;
import android.widget.TextView;

import com.firebase.ui.firestore.FirestoreRecyclerAdapter;
import com.firebase.ui.firestore.FirestoreRecyclerOptions;

public class ListaJugadoresEntrenamientoAdapter extends FirestoreRecyclerAdapter<Jugador, ListaJugadoresEntrenamientoAdapter.JugadorEntrenamientoViewHolder> {

    public ListaJugadoresEntrenamientoAdapter(@NonNull FirestoreRecyclerOptions<Jugador> options) {
        super(options);
    }

    @NonNull
    @Override
    public JugadorEntrenamientoViewHolder onCreateViewHolder(@NonNull ViewGroup viewGroup, int i) {
        View v = LayoutInflater.from(viewGroup.getContext()).inflate(R.layout.elemento_lista_jugadores_entrenamiento_adapter, viewGroup, false);
        return new ListaJugadoresEntrenamientoAdapter.JugadorEntrenamientoViewHolder(v);
    }

    @Override
    protected void onBindViewHolder(@NonNull JugadorEntrenamientoViewHolder holder, int position, @NonNull Jugador model) {
        String apodoJugador = model.getApodo();
        holder.tvApodo.setText(apodoJugador);
        Log.e("APODOJUGADOR", model.getApodo());

        if (model.getLesionado().equalsIgnoreCase("si")) {
            holder.llElementos.setBackgroundColor(0xFF75151E);
        } else {
            if (model.getSancionado().equalsIgnoreCase("si")) {
                holder.llElementos.setBackgroundColor(0xFF0E294B);
            } else {
                holder.llElementos.setBackgroundColor(0xFF57A639);
            }
        }
        for (int i = 0; i < EntrenamientoEditarDetalleActivity.listaApodos.size(); i++) {
            if (EntrenamientoEditarDetalleActivity.listaApodos.get(i).equalsIgnoreCase(apodoJugador)) {
                holder.bAnhadir.setText("Eliminar");
                holder.anhadido = true;
                break;
            }
        }

        holder.setOnClickListeners();
    }

    public class JugadorEntrenamientoViewHolder extends RecyclerView.ViewHolder implements View.OnClickListener {

        Context context;
        TextView tvApodo;
        Button bAnhadir;
        LinearLayout llElementos;

        boolean anhadido = false;

        public JugadorEntrenamientoViewHolder(@NonNull View itemView) {
            super(itemView);
            context = itemView.getContext();
            llElementos = (LinearLayout) itemView.findViewById(R.id.llJugadorElementoSeleccionJugadorEntrenamiento);
            tvApodo = (TextView) itemView.findViewById(R.id.tvApodoJugadorElementoSeleccionJugadorEntrenamiento);
            bAnhadir = (Button) itemView.findViewById(R.id.bAnhadirJugadorElementoSeleccionJugadorEntrenamiento);
        }

        public void setOnClickListeners() {
            bAnhadir.setOnClickListener(this);
        }

        @Override
        public void onClick(View v) {
            if (anhadido) {
                for (int i = 0; i < EntrenamientoEditarDetalleActivity.listaApodos.size(); i++) {
                    if (EntrenamientoEditarDetalleActivity.listaApodos.get(i).equalsIgnoreCase(tvApodo.getText().toString())) {
                        EntrenamientoEditarDetalleActivity.listaApodos.remove(i);
                        bAnhadir.setText("Añadir");
                        anhadido = false;
                        break;
                    }
                }
            } else {
                EntrenamientoEditarDetalleActivity.listaApodos.add(tvApodo.getText().toString());
                bAnhadir.setText("Eliminar");
                anhadido = true;
            }
        }
    }
}

XML:

<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:orientation="vertical"
    tools:context=".EntrenamientoEditarDetalleActivity">

    <GridLayout
        android:id="@+id/glDatosEntrenamientoEditarDetalle"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:layout_margin="15dp"
        android:layout_marginBottom="10dp"
        android:alignmentMode="alignMargins"
        android:columnCount="2"
        android:columnOrderPreserved="false"
        android:rowCount="3">

        <TextView
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:text="@string/Fecha" />

        <EditText
            android:id="@+id/etFechaEntrenamientoEditarDetalle"
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:hint="@string/Fecha"
            android:inputType="date" />

        <TextView
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:text="@string/Hora" />

        <EditText
            android:id="@+id/etHoraEntrenamientoEditarDetalle"
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:hint="@string/Hora"
            android:inputType="time" />

        <TextView
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:text="@string/Opinion" />

        <EditText
            android:id="@+id/etOpinionEntrenamientoEditarDetalle"
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:hint="@string/Opinion" />

    </GridLayout>

    <LinearLayout
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:layout_above="@id/bGuardarEntrenamientoEditarDetalle"
        android:layout_below="@+id/glDatosEntrenamientoEditarDetalle"
        android:orientation="vertical">

        <TextView
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:gravity="center"
            android:text="@string/Jugadores" />

        <android.support.v7.widget.RecyclerView
            android:id="@+id/rvJugadoresEntrenamientoEditarDetalle"
            android:layout_width="match_parent"
            android:layout_height="0dp"
            android:layout_weight="1" />

        <TextView
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:gravity="center"
            android:text="@string/Ejercicios" />

        <android.support.v7.widget.RecyclerView
            android:id="@+id/rvEjerciciosEntrenamientoEditarDetalle"
            android:layout_width="match_parent"
            android:layout_height="0dp"
            android:layout_weight="1" />

    </LinearLayout>

    <Button
        android:id="@+id/bGuardarEntrenamientoEditarDetalle"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_alignParentBottom="true"
        android:layout_centerInParent="true"
        android:text="@string/guardar" />
</RelativeLayout>

ERROR:

E/RecyclerView: No adapter attached; skipping layout

Body:
I solved, the adapter didn't listen to the data but if you force to listen to the new data it works:

                //Mostrar jugadores
                //Show players
                LinearLayoutManager llm = new LinearLayoutManager(context, LinearLayoutManager.VERTICAL, false);
                rvJugadores.setLayoutManager(llm);
                ljeAdapter = new ListaJugadoresEntrenamientoAdapter(options);
                rvJugadores.setHasFixedSize(true);
                rvJugadores.setAdapter(ljeAdapter);
                ljeAdapter.startListening();


问:
Catch Post Goods Issue event while outbound delivery processing
I am using the user exit USEREXIT_SAVE_DOCUMENT_PREPARE to check some positions in a delivery for some specific criteria.

I just want to do this whenever PGI is triggered. For this I use this condition in the user-exit:

```<code>IF ( sy-tcode EQ 'VL01N'    OR
     sy-tcode EQ 'VL02N' )  AND
     sy-ucomm EQ 'WABU_T'.
</code>```

But now I am afraid that this is not enough for cases like:

booking the exit directly from vl02n (without checking the positions)

book the exit via "Edit --> Post Good Issue"

editing the positions and book

Are there some further options which can be checked to make sure that there is a booking?

How can I make completely sure that a post of goods was triggered in fact?

答:
You can try to utilize Workflow to cover all possible cases.

Create Workflow event which will be triggered upon delivery creation/change and check for Post Goods Issue there. Delivery BO is LIKP so go to tcode SWU_EWCD and enter data like this

Workflow events are based on change documents so every times smth is written to the table it will be fired. Check that your event is properly created in SWEC transaction.

You can also create events based on NACE conditions. After that use your event to generate your own workflow.

Also BAdI LE_SHP_DELIVERY_PROC may be of interest for you, it has method
SAVE_AND_PUBLISH_BEFORE_OUTPUT which is executed before saving of delivery.

Body:
I am using the user exit USEREXIT_SAVE_DOCUMENT_PREPARE to check some positions in a delivery for some specific criteria.

I just want to do this whenever PGI is triggered. For this I use this condition in the user-exit:

IF ( sy-tcode EQ 'VL01N'    OR
     sy-tcode EQ 'VL02N' )  AND
     sy-ucomm EQ 'WABU_T'.

But now I am afraid that this is not enough for cases like:

booking the exit directly from vl02n (without checking the positions)

book the exit via "Edit --> Post Good Issue"

editing the positions and book

Are there some further options which can be checked to make sure that there is a booking?

How can I make completely sure that a post of goods was triggered in fact?


问:
how to get specific numbers out of string value that is changing ; php
I'm trying to get latitude and longitude number values out of location info string.

if I search 'hawaii' on the map, the map api returns the string value like below.

$location = {map: geo="20.471884,-157.505,6" p="Hawaii"}

and I'd like to get latitude and longitude value into $lat, $lng.

How can I make it in php???

答:
Maybe something like this is what you need:

```<code><?php

$re = '/(["\'])(\\\\?.)*?\1/';
$str = '{map: geo="20.471884,-157.505,6" p="Hawaii"}';

preg_match_all($re, $str, $matches, PREG_SET_ORDER, 0);

var_dump($matches);
</code>```

test here: http://sandbox.onlinephpfunctions.com/code/e858fca9b0ba65d59919f28ae2a228db5e7610da

Body:
Maybe something like this is what you need:

<?php

$re = '/(["\'])(\\\\?.)*?\1/';
$str = '{map: geo="20.471884,-157.505,6" p="Hawaii"}';

preg_match_all($re, $str, $matches, PREG_SET_ORDER, 0);

var_dump($matches);

test here: http://sandbox.onlinephpfunctions.com/code/e858fca9b0ba65d59919f28ae2a228db5e7610da


问:
Sum the number equivalent of alphabets in a word until it's single digit?
I am trying to solve a problem where a user gives a text input then I have to convert the text into given numeric values, add them together unless the answer is a single digit number.

So far, I have been able to get input, transform them into given numbers and store them in an array. But I cannot figure out what I will do next. How I will add the values together until it is left a single digit number.

var values = {a:1,b:2,c:3,d:4,e:5,f:6,g:7,h:8,i:9,j:10,k:11,l:12,m:13,n:14,o:15,p:16,q:17,r:18,s:19,t:20,u:21,v:22,w:23,x:24,y:25,z:26};
var someText = prompt('');

someText = someText.trim();
someText = someText.match(/\S/g);

var result = "";
for (i = 0; i < someText.length; i++) {
  result += values[someText[i]];
}

alert(result);```

For Example if input is "action" then numeric values will be
 =>1.3.20.9.15.14.
-Add these values together.
   1+3+20+9+15+14 answer will be 62.
-As the Answer is a 2 digit number, we add the numbers again
   e.g 62 = 6+2= 8.

Note:
If answer is more then 1 digits: e.g 199 => 1+9+9 => 19 => 1+9 => 10 = 1+0 = 1.
Answer must always be a single digit number.

答:
Here's how you can do it:

var values = {a:1,b:2,c:3,d:4,e:5,f:6,g:7,h:8,i:9,j:10,k:11,l:12,m:13,n:14,o:15,p:16,q:17,r:18,s:19,t:20,u:21,v:22,w:23,x:24,y:25,z:26};
var someText = prompt('');

someText = someText.trim();
someText = someText.match(/\S/g);

var result = "";
for (i = 0; i < someText.length; i++) {
  result += values[someText[i]];
}

// While the result is >9, which means that there's more than 1 digit
while(result > 9) {
   // Cast result as String, so we can use charAt()
   var stringedResult = String(result);

   // Reset our result var, because we're going to recalculate it
   result = 0;

   // For each int in our result, we add them up (ex. 621 = 6+2+1)
   for(var i=0; i<stringedResult.length; i++) {
       // Cast the stringed result back to a number, and add it to our result variable
       result += Number(stringedResult.charAt(i));
   }
}

alert(result);```

Body:
I am trying to solve a problem where a user gives a text input then I have to convert the text into given numeric values, add them together unless the answer is a single digit number.

So far, I have been able to get input, transform them into given numbers and store them in an array. But I cannot figure out what I will do next. How I will add the values together until it is left a single digit number.

var values = {a:1,b:2,c:3,d:4,e:5,f:6,g:7,h:8,i:9,j:10,k:11,l:12,m:13,n:14,o:15,p:16,q:17,r:18,s:19,t:20,u:21,v:22,w:23,x:24,y:25,z:26};
var someText = prompt('');

someText = someText.trim();
someText = someText.match(/\S/g);

var result = "";
for (i = 0; i < someText.length; i++) {
  result += values[someText[i]];
}

alert(result);

For Example if input is "action" then numeric values will be
 =>1.3.20.9.15.14.
-Add these values together.
   1+3+20+9+15+14 answer will be 62.
-As the Answer is a 2 digit number, we add the numbers again
   e.g 62 = 6+2= 8.

Note:
If answer is more then 1 digits: e.g 199 => 1+9+9 => 19 => 1+9 => 10 = 1+0 = 1.
Answer must always be a single digit number.


问:
CharacterController can climb jump on slightly tilted walls
I have a issue with the CharacterController component being able to climb on slightly tilted walls. The bottom part is able to stand on the wall, which makes it possible to jump again. Any advice tackeling this kind of behaviour? Here is an example gif of what I mean.</p>

答:
It had something to do with the skinwidth being to thin.

Two colliders can penetrate each other as deep as their Skin Width. Larger Skin Widths reduce jitter. Low Skin Width can cause the character to get stuck. A good setting is to make this value 10% of the Radius.

Retaining this value (10%) solved the issue for me.


问:
Catch input field for "type in answer" type on iOS Anki app
There is a bug in iOS Anki app. When I type thai in this field tone marks are being cut on top of it:

I think I can fix it by increasing padding or something like that using CSS but I don't know how to catch this field in the template. Is there any HTML class or id to match from CSS?

Thanks.

P.S. I tried this:
input { ... }

and this:
[contenteditable] { ... }

and even this:
[placeholder="type in the answer"] { ... }

But nothing works. I am starting to thing that it is not even an HTML being used there. Maybe some native for iOS input or something like that.

答:
Okey for those who landed here... It is native iOS widget and we have no control over it. Though tone glyph trimming was resolved:
https://anki.tenderapp.com/discussions/ankimobile/9706-catch-input-field-for-type-in-answer-type-on-ios</p>


问:
How to open link in Safari from an HTML hosted in a web browser control?
We have an iphone app that hosts a web browser control which points to a website whose sole purpose is to display information for the application. I would like to know if it is possible to have an anchor/button open Safari using HTML/JavaScript. If it is possible, how so?

Thanks...

答:
Set the delegate property of your UIWebView object (what you call the 'web browser control') to an object of your own that implements the method "webView:shouldStartLoadWithRequest:navigationType:" of the UIWebViewDelegate protocol:

http://developer.apple.com/library/ios/#documentation/uikit/reference/UIWebViewDelegate_Protocol/Reference/Reference.html%23//apple_ref/occ/intf/UIWebViewDelegate

You can then detect if you desired URL is being requested and in that case open it on an external Safari instance using UIApplication's openURL method.


问:
FadeInImage in BoxDecoration
I love the FadeInImage

I can do this

```<code>child: FadeInImage.assetNetwork(
    image: 'https://placeimg.com/640/480/any',
    placeholder: 'assets/images/loading.gif',
  ),
</code>```

I want to use the FadeInImage in a BoxDecoration as below.

```<code>decoration: BoxDecoration(
  borderRadius: BorderRadius.circular(8.0),
  image: DecorationImage(
    image: FadeInImage.assetNetwork(
        '${document['image']}'),
    fit: BoxFit.cover,
  ),
),
</code>```

I get this error:

The argument type 'FadeInImage' can't be assigned to the parameter type 'ImageProvider'

How would I go about it?

Use Case

In a carousel, put in placeholder, before network loaded image comes in

Here's my carousel Widget (I'm using the carousel_slider package for Flutter)

```<code>  Widget _carouselSlider(BuildContext context) {
    return StreamBuilder<QuerySnapshot>(
      stream: Firestore.instance.collection('events').snapshots(),
      builder: (BuildContext context, AsyncSnapshot<QuerySnapshot> snapshot) {
        if (snapshot.hasError) return new Text('Error: ${snapshot.error}');
        switch (snapshot.connectionState) {
          case ConnectionState.waiting:
            return new Text('Loading...');
          default:
            return CarouselSlider(
              height: 150.0,
              enlargeCenterPage: true,
              enableInfiniteScroll: false,
              items: snapshot.data.documents.map((DocumentSnapshot document) {
                print('Listing the documents: $document');
                return Builder(
                  builder: (BuildContext context) {
                    return GestureDetector(
                      onTap: () {
                        print('I am clicked');
                        Navigator.pushNamed(context, '/detail');
                      },
                      child: Container(
                        width: MediaQuery.of(context).size.width,
                        margin: EdgeInsets.only(
                            left: 5.0, right: 5.0, bottom: 20.0),
                        decoration: BoxDecoration(
                          borderRadius: BorderRadius.circular(8.0),
                          image: DecorationImage(
                            image: NetworkImage('${document['image']}'),
                            fit: BoxFit.cover,
                          ),
                        ),
                        child: Center(
                          child: Text(
                            '${document['name']}',
                            style: TextStyle(fontSize: 16.0),
                          ),
                        ),
                      ),
                    );
                  },
                );
              }).toList(),
            );
        }
      },
    );
  }
</code>```

So, for the part

```<code>image: DecorationImage(
                        image: NetworkImage('${document['image']}'),
                        fit: BoxFit.cover,
                      ),
</code>```

I wish to have a placeholder approach, instead of only the text until network loaded image arrives.

答:
Here is the code. </p>

```<code>class _HomePageState extends State<HomePage> {
  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(),
      body: Center(
          child: FutureBuilder<bool>(
        future: _myFuture(),
        builder: (BuildContext context, AsyncSnapshot snapshot) {
          if (snapshot.hasData) return _yourWidget();
          return CircularProgressIndicator();
        },
      )),
    );
  }

  Widget _yourWidget() {
    return Stack(
      children: <Widget>[
        Center(
          child: FadeInImage(
            width: 300,
            height: 300,
            placeholder: AssetImage(chocolateImage),
            image: NetworkImage(poolImageUrl),
            fit: BoxFit.cover,
          ),
        ),
        Center(child: Text('Pool', style: TextStyle(fontSize: 36.0, color: Colors.white, fontWeight: FontWeight.bold))),
      ],
    );
  }

  Future<bool> _myFuture() async {
    await Future.delayed(Duration(milliseconds: 10500));
    return true;
  }
}
</code>```

Title: FadeInImage in BoxDecoration

Body:
I love the FadeInImage

I can do this

child: FadeInImage.assetNetwork(
    image: 'https://placeimg.com/640/480/any',
    placeholder: 'assets/images/loading.gif',
  ),

I want to use the FadeInImage in a BoxDecoration as below.

decoration: BoxDecoration(
  borderRadius: BorderRadius.circular(8.0),
  image: DecorationImage(
    image: FadeInImage.assetNetwork(
        '${document['image']}'),
    fit: BoxFit.cover,
  ),
),

I get this error:

The argument type 'FadeInImage' can't be assigned to the parameter type 'ImageProvider'

How would I go about it?

Use Case

In a carousel, put in placeholder, before network loaded image comes in

Here's my carousel Widget (I'm using the carousel_slider package for Flutter)

  Widget _carouselSlider(BuildContext context) {
    return StreamBuilder<QuerySnapshot>(
      stream: Firestore.instance.collection('events').snapshots(),
      builder: (BuildContext context, AsyncSnapshot<QuerySnapshot> snapshot) {
        if (snapshot.hasError) return new Text('Error: ${snapshot.error}');
        switch (snapshot.connectionState) {
          case ConnectionState.waiting:
            return new Text('Loading...');
          default:
            return CarouselSlider(
              height: 150.0,
              enlargeCenterPage: true,
              enableInfiniteScroll: false,
              items: snapshot.data.documents.map((DocumentSnapshot document) {
                print('Listing the documents: $document');
                return Builder(
                  builder: (BuildContext context) {
                    return GestureDetector(
                      onTap: () {
                        print('I am clicked');
                        Navigator.pushNamed(context, '/detail');
                      },
                      child: Container(
                        width: MediaQuery.of(context).size.width,
                        margin: EdgeInsets.only(
                            left: 5.0, right: 5.0, bottom: 20.0),
                        decoration: BoxDecoration(
                          borderRadius: BorderRadius.circular(8.0),
                          image: DecorationImage(
                            image: NetworkImage('${document['image']}'),
                            fit: BoxFit.cover,
                          ),
                        ),
                        child: Center(
                          child: Text(
                            '${document['name']}',
                            style: TextStyle(fontSize: 16.0),
                          ),
                        ),
                      ),
                    );
                  },
                );
              }).toList(),
            );
        }
      },
    );
  }

So, for the part

image: DecorationImage(
                        image: NetworkImage('${document['image']}'),
                        fit: BoxFit.cover,
                      ),

I wish to have a placeholder approach, instead of only the text until network loaded image arrives.

Body:
Here is the code.

class _HomePageState extends State<HomePage> {
  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(),
      body: Center(
          child: FutureBuilder<bool>(
        future: _myFuture(),
        builder: (BuildContext context, AsyncSnapshot snapshot) {
          if (snapshot.hasData) return _yourWidget();
          return CircularProgressIndicator();
        },
      )),
    );
  }

  Widget _yourWidget() {
    return Stack(
      children: <Widget>[
        Center(
          child: FadeInImage(
            width: 300,
            height: 300,
            placeholder: AssetImage(chocolateImage),
            image: NetworkImage(poolImageUrl),
            fit: BoxFit.cover,
          ),
        ),
        Center(child: Text('Pool', style: TextStyle(fontSize: 36.0, color: Colors.white, fontWeight: FontWeight.bold))),
      ],
    );
  }

  Future<bool> _myFuture() async {
    await Future.delayed(Duration(milliseconds: 10500));
    return true;
  }
}


问:
Can I get ModalController by singleton?
This is a very common usage of ModalController.

constructor(private modalCtrl: ModalController) { }
```

<p>However, I want to retrieve <code>ModalController</code> in a static context just like this,</p>

<pre class="lang-js prettyprint-override"><code>static showModal() {
  // `instance` or whatever
  ModalController.instance.create({
     /* .... */
  });
}
</code>```

Is there any way to access the instance of services in Angular or Ionic?

答:
if you will use singleton in angular you can use services

https://angular.io/guide/singleton-services

```<code>import { Injectable } from '@angular/core';
import { zip } from 'rxjs';

@Injectable({
  providedIn: 'root'
})
export class ModalService {
  private modals: any[] = [];
  constructor() { }

  add(modal:any){
    this.modals.push(modal);
  }

  remove(id:string){
    this.modals =  this.modals.filter(x=> x.id !== id)
  }

  open(id:string){
    let modal:any = this.modals.filter(x=>x.id === id)[0];
    modal.open();
  }

  close(id:string){
    let modal:any = this.modals.filter(x=>x.id === id)[0];
    modal.close();
  }

}
</code>```

Title: Can I get ModalController by singleton?

Body:
This is a very common usage of ModalController.

constructor(private modalCtrl: ModalController) { }

However, I want to retrieve ModalController in a static context just like this,

static showModal() {
  // `instance` or whatever
  ModalController.instance.create({
     /* .... */
  });
}

Is there any way to access the instance of services in Angular or Ionic?

Body:
if you will use singleton in angular you can use services

https://angular.io/guide/singleton-services

import { Injectable } from '@angular/core';
import { zip } from 'rxjs';

@Injectable({
  providedIn: 'root'
})
export class ModalService {
  private modals: any[] = [];
  constructor() { }

  add(modal:any){
    this.modals.push(modal);
  }

  remove(id:string){
    this.modals =  this.modals.filter(x=> x.id !== id)
  }

  open(id:string){
    let modal:any = this.modals.filter(x=>x.id === id)[0];
    modal.open();
  }

  close(id:string){
    let modal:any = this.modals.filter(x=>x.id === id)[0];
    modal.close();
  }

}