问:
Python: load variables in a dict into namespace
I want to use a bunch of local variables defined in a function, outside of the function. So I am passing x=locals() in the return value.

How can I load all the variables defined in that dictionary into the namespace outside the function, so that instead of accessing the value using x['variable'], I could simply use variable.

答:
The Bunch answer is ok but lacks recursion and proper __repr__ and __eq__ builtins to simulate what you can already do with a dict. Also the key to recursion is not only to recurse on dicts but also on lists, so that dicts inside lists are also converted.

These two options I hope will cover your needs (you might have to adjust the type checks in __elt() for more complex objects; these were tested mainly on json imports so very simple core types).

The Bunch approach (as per previous answer) - object takes a dict and converts it recursively. repr(obj) will return Bunch({...}) that can be re-interpreted into an equivalent object.

class Bunch(object):
    def __init__(self, adict):
        """Create a namespace object from a dict, recursively"""
        self.__dict__.update({k: self.__elt(v) for k, v in adict.items()})

    def __elt(self, elt):
        """Recurse into elt to create leaf namespace objects"""
        if type(elt) is dict:
            return type(self)(elt)
        if type(elt) in (list, tuple):
            return [self.__elt(i) for i in elt]
        return elt

    def __repr__(self):
        """Return repr(self)."""
        return "%s(%s)" % (type(self).__name__, repr(self.__dict__))

    def __eq__(self, other):
        if hasattr(other, '__dict__'):
            return self.__dict__ == other.__dict__
        return NotImplemented
        # Use this to allow comparing with dicts:
        #return self.__dict__ == (other.__dict__ if hasattr(other, '__dict__') else other)
```
<ol start="2">
<li>The <em>SimpleNamespace</em> approach - since <code>types.SimpleNamespace</code> already implements <code>__repr__</code> and <code>__eq__</code>, all you need is to implement a recursive <code>__init__</code> method:</li>
</ol>
<pre class="lang-py prettyprint-override"><code>import types
class RecursiveNamespace(types.SimpleNamespace):
    # def __init__(self, /, **kwargs):  # better, but Python 3.8+
    def __init__(self, **kwargs):
        """Create a SimpleNamespace recursively"""
        self.__dict__.update({k: self.__elt(v) for k, v in kwargs.items()})

    def __elt(self, elt):
        """Recurse into elt to create leaf namespace objects"""
        if type(elt) is dict:
            return type(self)(**elt)
        if type(elt) in (list, tuple):
            return [self.__elt(i) for i in elt]
        return elt

    # Optional, allow comparison with dicts:
    #def __eq__(self, other):
    #    return self.__dict__ == (other.__dict__ if hasattr(other, '__dict__') else other)
</code>```

The RecursiveNamespace class takes keyword arguments, which can of course come from a de-referenced dict (ex **mydict)

Now let's put them to the test (argparse.Namespace added for comparison, although it's nested dict is manually converted):

from argparse import Namespace
from itertools import combinations
adict = {'foo': 'bar', 'baz': [{'aaa': 'bbb', 'ccc': 'ddd'}]}
a = Bunch(adict)
b = RecursiveNamespace(**adict)
c = Namespace(**adict)
c.baz[0] = Namespace(**c.baz[0])
for n in ['a', 'b', 'c']:
    print(f'{n}:', str(globals()[n]))
for na, nb in combinations(['a', 'b', 'c'], 2):
    print(f'{na} == {nb}:', str(globals()[na] == globals()[nb]))
```
<p>The result is:</p>
```a: Bunch({'foo': 'bar', 'baz': [Bunch({'aaa': 'bbb', 'ccc': 'ddd'})]})
b: RecursiveNamespace(foo='bar', baz=[RecursiveNamespace(aaa='bbb', ccc='ddd')])
c: Namespace(foo='bar', baz=[Namespace(aaa='bbb', ccc='ddd')])
a == b: True
a == c: True
b == c: False
```

Although those are different classes, because they both (a and b) have been initialized to equivalent namespaces and their __eq__ method compares the namespace only (self.__dict__), comparing two namespace objects returns True. For the case of comparing with argparse.Namespace, for some reason only Bunch works and I'm unsure why (please comment if you know, I haven't looked much further as types.SimpleNameSpace is a built-in implementation).

You might also notice that I recurse using type(self)(...) rather than using the class name - this has two advantages: first the class can be renamed without having to update recursive calls, and second if the class is subclassed we'll be recursing using the subclass name. It's also the name used in __repr__ (type(self).__name__).

EDIT 2021-11-27:

Modified the Bunch.__eq__ method to make it safe against type mismatch.

Added/modified optional __eq__ methods (commented out) to allow comparing with the original dict and argparse.Namespace(**dict) (note that the later is not recursive but would still be comparable with other classes as the sublevel structs would compare fine anyway).

ContentLicense: CC BY-SA 2.5

Body:
The Bunch answer is ok but lacks recursion and proper __repr__ and __eq__ builtins to simulate what you can already do with a dict. Also the key to recursion is not only to recurse on dicts but also on lists, so that dicts inside lists are also converted.

These two options I hope will cover your needs (you might have to adjust the type checks in __elt() for more complex objects; these were tested mainly on json imports so very simple core types).

The Bunch approach (as per previous answer) - object takes a dict and converts it recursively. repr(obj) will return Bunch({...}) that can be re-interpreted into an equivalent object.

class Bunch(object):
    def __init__(self, adict):
        """Create a namespace object from a dict, recursively"""
        self.__dict__.update({k: self.__elt(v) for k, v in adict.items()})

    def __elt(self, elt):
        """Recurse into elt to create leaf namespace objects"""
        if type(elt) is dict:
            return type(self)(elt)
        if type(elt) in (list, tuple):
            return [self.__elt(i) for i in elt]
        return elt

    def __repr__(self):
        """Return repr(self)."""
        return "%s(%s)" % (type(self).__name__, repr(self.__dict__))

    def __eq__(self, other):
        if hasattr(other, '__dict__'):
            return self.__dict__ == other.__dict__
        return NotImplemented
        # Use this to allow comparing with dicts:
        #return self.__dict__ == (other.__dict__ if hasattr(other, '__dict__') else other)

The SimpleNamespace approach - since types.SimpleNamespace already implements __repr__ and __eq__, all you need is to implement a recursive __init__ method:

import types
class RecursiveNamespace(types.SimpleNamespace):
    # def __init__(self, /, **kwargs):  # better, but Python 3.8+
    def __init__(self, **kwargs):
        """Create a SimpleNamespace recursively"""
        self.__dict__.update({k: self.__elt(v) for k, v in kwargs.items()})

    def __elt(self, elt):
        """Recurse into elt to create leaf namespace objects"""
        if type(elt) is dict:
            return type(self)(**elt)
        if type(elt) in (list, tuple):
            return [self.__elt(i) for i in elt]
        return elt

    # Optional, allow comparison with dicts:
    #def __eq__(self, other):
    #    return self.__dict__ == (other.__dict__ if hasattr(other, '__dict__') else other)

The RecursiveNamespace class takes keyword arguments, which can of course come from a de-referenced dict (ex **mydict)

Now let's put them to the test (argparse.Namespace added for comparison, although it's nested dict is manually converted):

from argparse import Namespace
from itertools import combinations
adict = {'foo': 'bar', 'baz': [{'aaa': 'bbb', 'ccc': 'ddd'}]}
a = Bunch(adict)
b = RecursiveNamespace(**adict)
c = Namespace(**adict)
c.baz[0] = Namespace(**c.baz[0])
for n in ['a', 'b', 'c']:
    print(f'{n}:', str(globals()[n]))
for na, nb in combinations(['a', 'b', 'c'], 2):
    print(f'{na} == {nb}:', str(globals()[na] == globals()[nb]))

The result is:

a: Bunch({'foo': 'bar', 'baz': [Bunch({'aaa': 'bbb', 'ccc': 'ddd'})]})
b: RecursiveNamespace(foo='bar', baz=[RecursiveNamespace(aaa='bbb', ccc='ddd')])
c: Namespace(foo='bar', baz=[Namespace(aaa='bbb', ccc='ddd')])
a == b: True
a == c: True
b == c: False

Although those are different classes, because they both (a and b) have been initialized to equivalent namespaces and their __eq__ method compares the namespace only (self.__dict__), comparing two namespace objects returns True. For the case of comparing with argparse.Namespace, for some reason only Bunch works and I'm unsure why (please comment if you know, I haven't looked much further as types.SimpleNameSpace is a built-in implementation).

You might also notice that I recurse using type(self)(...) rather than using the class name - this has two advantages: first the class can be renamed without having to update recursive calls, and second if the class is subclassed we'll be recursing using the subclass name. It's also the name used in __repr__ (type(self).__name__).

EDIT 2021-11-27:

Modified the Bunch.__eq__ method to make it safe against type mismatch.

Added/modified optional __eq__ methods (commented out) to allow comparing with the original dict and argparse.Namespace(**dict) (note that the later is not recursive but would still be comparable with other classes as the sublevel structs would compare fine anyway).


来源: stackexchange

问:
How to create a leveling system with discord.py with python?
I tried to make a levelling system into my bot but something went wrong. The level rose after each message and not after the specified parameter. How to make it work properly? How to create a leveling system with discord.py?

Here is my code:

@client.event
async def on_message( message ):
    if message.author.bot:
        return
    else:
        member = message.author.name
        msg_len = len(message.content)
        rand_number_1 = randint( 1, 10 )
        exp_first = msg_len * rand_number_1
        coins_first = exp_first // 10
        data_levels_member_first = { 'exp': 0, 'coins': 0, 'level': 0}
        filename = f'./Data/Profiles/Profile{message.author.name}{message.guild}.json'
        try:
            data = load( filename )
        except Exception:
            dump( filename, data_levels_member_first )
            data = load( filename )
        exp_member = data['exp']
        coins_member = data['coins']
        lvl_member = data['level']
        exp = exp_first + exp_member
        coins = coins_first + coins_member
        lvl = exp ** (1/4)
        if lvl_member < lvl:
            lvl_member += 1
            print('You lvl up!')
        data_levels_member = { 'exp': exp, 'coins': coins, 'level': lvl_member}
        dump( filename, data_levels_member )
        await client.process_commands(message)
```

答:
Here is a level sytem code that might help you:</p>

```<code>@client.event
async def on_member_join(member):
    with open('users.json', 'r') as f:
        users = json.load(f)

    await update_data(users, member)

    with open('users.json', 'w') as f:
        json.dump(users, f)

@client.event
async def on_message(message):
    if message.author.bot == False:
        with open('users.json', 'r') as f:
            users = json.load(f)

        await update_data(users, message.author)
        await add_experience(users, message.author, 5)
        await level_up(users, message.author, message)

        with open('users.json', 'w') as f:
            json.dump(users, f)

    await client.process_commands(message)

async def update_data(users, user):
    if not f'{user.id}' in users:
        users[f'{user.id}'] = {}
        users[f'{user.id}']['experience'] = 0
        users[f'{user.id}']['level'] = 1

async def add_experience(users, user, exp):
    users[f'{user.id}']['experience'] += exp

async def level_up(users, user, message):
    with open('levels.json', 'r') as g:
        levels = json.load(g)
    experience = users[f'{user.id}']['experience']
    lvl_start = users[f'{user.id}']['level']
    lvl_end = int(experience ** (1 / 4))
    if lvl_start < lvl_end:
        await message.channel.send(f'{user.mention} has leveled up to level {lvl_end}')
        users[f'{user.id}']['level'] = lvl_end

@client.command()
async def level(ctx, member: discord.Member = None):
    if not member:
        id = ctx.message.author.id
        with open('users.json', 'r') as f:
            users = json.load(f)
        lvl = users[str(id)]['level']
        await ctx.send(f'You are at level {lvl}!')
    else:
        id = member.id
        with open('users.json', 'r') as f:
            users = json.load(f)
        lvl = users[str(id)]['level']
        await ctx.send(f'{member} is at level {lvl}!')
</code>```

ContentLicense: CC BY-SA 4.0

Body:
Here is a level sytem code that might help you:

@client.event
async def on_member_join(member):
    with open('users.json', 'r') as f:
        users = json.load(f)

    await update_data(users, member)

    with open('users.json', 'w') as f:
        json.dump(users, f)

@client.event
async def on_message(message):
    if message.author.bot == False:
        with open('users.json', 'r') as f:
            users = json.load(f)

        await update_data(users, message.author)
        await add_experience(users, message.author, 5)
        await level_up(users, message.author, message)

        with open('users.json', 'w') as f:
            json.dump(users, f)

    await client.process_commands(message)

async def update_data(users, user):
    if not f'{user.id}' in users:
        users[f'{user.id}'] = {}
        users[f'{user.id}']['experience'] = 0
        users[f'{user.id}']['level'] = 1

async def add_experience(users, user, exp):
    users[f'{user.id}']['experience'] += exp

async def level_up(users, user, message):
    with open('levels.json', 'r') as g:
        levels = json.load(g)
    experience = users[f'{user.id}']['experience']
    lvl_start = users[f'{user.id}']['level']
    lvl_end = int(experience ** (1 / 4))
    if lvl_start < lvl_end:
        await message.channel.send(f'{user.mention} has leveled up to level {lvl_end}')
        users[f'{user.id}']['level'] = lvl_end

@client.command()
async def level(ctx, member: discord.Member = None):
    if not member:
        id = ctx.message.author.id
        with open('users.json', 'r') as f:
            users = json.load(f)
        lvl = users[str(id)]['level']
        await ctx.send(f'You are at level {lvl}!')
    else:
        id = member.id
        with open('users.json', 'r') as f:
            users = json.load(f)
        lvl = users[str(id)]['level']
        await ctx.send(f'{member} is at level {lvl}!')


问:
Adding a new array does not update my total array count in Swift Xcode
Problem: Initially my count is correct, however, adding a new array does not update my total array count label.

I have a View Controller (VC) that shows a label with a count of total arrays.
I have a Table View Controller (TVC) that arrays are added or deleted from.
I have a separate struct file to hold the arrays.

The label populates with the correct number of arrays when I run it. However, adding a new array item (via TVC) in the simulator does not update the label on the VC.

Questions:

Should I put the count in a function in VC? It is currently in the viewDidLoad()

Should I then call the function in TVC when adding or deleting an array?

If 2 is yes then do I reference the function in VTC? Would it simply be
updateCount() or do I have to reference the VC controller e.g.
ViewController.updateCount()

I have tried both ways but it does not seem to work, if I can get confirmation that would be great then I can make it work.

Thank you in Advance

答:
My suggestion is bad but it works.

The easiest answer is use static variable, but it will cost memory phone. example code:

```<code>import Foundation
import UIKit

class VC: UIViewController {
    static var count = 0
    let label: UILabel = UILabel()

    override func viewWillAppear(_ animated: Bool) {
        super.viewWillAppear(animated)

        label.text = String(VC.count)
    }
}

class TVC: UITableViewController {

    func updateCount() {
        VC.count = VC.count + 1
    }
}
</code>```

Whenever function updateCount() called in TVC, and go back to VC class it will update the count.

My other suggestion is use MVVM pattern that sending VCViewModel as parameter to TVC. and update count in VCViewModel.

Other suggestion is use delegate pattern.

Body:
My suggestion is bad but it works.

The easiest answer is use static variable, but it will cost memory phone. example code:

import Foundation
import UIKit

class VC: UIViewController {
    static var count = 0
    let label: UILabel = UILabel()

    override func viewWillAppear(_ animated: Bool) {
        super.viewWillAppear(animated)

        label.text = String(VC.count)
    }
}

class TVC: UITableViewController {

    func updateCount() {
        VC.count = VC.count + 1
    }
}

Whenever function updateCount() called in TVC, and go back to VC class it will update the count.

My other suggestion is use MVVM pattern that sending VCViewModel as parameter to TVC. and update count in VCViewModel.

Other suggestion is use delegate pattern.


问:
Using NSPredicate to analyze strings
Howdy! This question is pretty long so be sure to have a seat first :)

At one point in my code I get a string from the user, and I analyze that string. By analyzing I mean going through every character and mathcing it against a predicate the user has set in an NSPredicateEditor. The predicate is setup progamatically this way:

```<code>NSArray* keyPaths = [NSArray arrayWithObjects:
                         [NSExpression expressionForKeyPath: @"Character"],
                         [NSExpression expressionForKeyPath: @"Character Before"],
                         [NSExpression expressionForKeyPath: @"Character After"],
                         nil];
// -----------------------------------------
NSArray* constants = [NSArray arrayWithObjects:
                      [NSExpression expressionForConstantValue: @"Any letter"],
                      [NSExpression expressionForConstantValue: @"Letter (uppercase)"],
                      [NSExpression expressionForConstantValue: @"Letter (lowercase)"],
                      [NSExpression expressionForConstantValue: @"Number"],
                      [NSExpression expressionForConstantValue: @"Alphanumerical"],
                      [NSExpression expressionForConstantValue: @"Ponctuation Mark"],
                      nil];
// -----------------------------------------
NSArray* compoundTypes = [NSArray arrayWithObjects:
                          [NSNumber numberWithInteger: NSNotPredicateType],
                          [NSNumber numberWithInteger: NSAndPredicateType],
                          [NSNumber numberWithInteger: NSOrPredicateType],
                          nil];
// -----------------------------------------
NSArray* operatorsA = [NSArray arrayWithObjects:
                       [NSNumber numberWithInteger: NSEqualToPredicateOperatorType],
                       [NSNumber numberWithInteger: NSNotEqualToPredicateOperatorType],
                       nil];

NSArray* operatorsB = [NSArray arrayWithObjects:
                       [NSNumber numberWithInteger: NSInPredicateOperatorType],
                       nil];
// -----------------------------------------
NSPredicateEditorRowTemplate* template1 = [[NSPredicateEditorRowTemplate alloc] initWithLeftExpressions: keyPaths
                                                                                rightExpressions: constants
                                                                                modifier: NSDirectPredicateModifier
                                                                                operators: operatorsA
                                                                                options: 0];

NSPredicateEditorRowTemplate* template2 = [[NSPredicateEditorRowTemplate alloc] initWithLeftExpressions: keyPaths
                                                                           rightExpressionAttributeType: NSStringAttributeType
                                                                                modifier: NSDirectPredicateModifier
                                                                                operators: operatorsB
                                                                                options: 0];

NSPredicateEditorRowTemplate* compound = [[NSPredicateEditorRowTemplate alloc] initWithCompoundTypes: compoundTypes];
// -----------------------------------------
NSArray* rowTemplates = [NSArray arrayWithObjects: template1, template2, compound, nil];

[myPredicateEditor setRowTemplates: rowTemplates];
</code>```

So you can see I have three keypaths and some constants they can be compared with.
When analyzing the string I basically want to do this, in pseudocode:

```<code>originalString = [string from NSTextView]
for (char in originalString)
    bChar = [character before char]
    aChar = [character after char]

    predicate = [predicate from myPredicateEditor]

    // using predicate - problem!
    result = [evaluate predicate with:
               bChar somehow 'linked' to keypath 'Character Before'
               char 'linked' to 'Character'
               aChar 'linked' to 'Character After' // These values change, of course
              and also:
               constant "All letters" as "abc...WXYZ"
               constant "Numbers" as "0123456789"
               etc for all other constants set up  // These don't
              ]

    if (result) then do something with char, bChar and aChar
</code>```

You can see where my problem basically lies:

'Character Before/After' cannot be keypaths because of the space, but I want to keep it that way as it is more beautiful for the user (imagine having something as 'characterBefore' instead...)

Constants such as 'Numbers' actually represent strings like '0123456789', witch I can't display to the user as well

I was able to find a workaround to this problem, but I now it doesn't work with every character and it is also very unefficient (in my opinion, at least). What I do is get the predicate format from the predicate, replace what I have to replace, and evaluate that new format instead. Now for some real code that explains this:

```<code>#define kPredicateSubstitutionsDict [NSDictionary dictionaryWithObjectsAndKeys: \
@"IN 'abcdefghijklmnopqrstuvwxyz'", @"== \"Letter (lowercase)\"", \
@"IN 'ABCDEFGHIJKLMNOPQRSTUVWXYZ'", @"== \"Letter (uppercase)\"", \
@"IN 'abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ'", @"== \"Any letter\"", \
@"IN '1234567890'", @"== \"Number\"", \
@"IN 'abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ1234567890'", @"== \"Alphanumerical\"", \
@"IN ',.;:!?'", @"== \"Ponctuation Mark\"", \
\
@"MATCHES '[^a-z]'"         , @"!= \"Letter (lowercase)\"", \
@"MATCHES '[^A-Z]'"         , @"!= \"Letter (uppercase)\"", \
@"MATCHES '[^a-zA-Z]'"      , @"!= \"Any letter\"", \
@"MATCHES '[^0-9]'"         , @"!= \"Number\"", \
@"MATCHES '[^a-zA-Z0-9]'"   , @"!= \"Alphanumerical\"", \
@"MATCHES '[^,\.;:!\?]'"  , @"!= \"Ponctuation Mark\"", \
\
nil]

// NSPredicate* predicate is setup in another place
// NSString* originalString is also setup in another place
NSString* predFormat = [predicate predicateFormat];
for (NSString* key in [kPredicateSubstitutionsDict allKeys]) {
    prefFormat = [predFormat stringByReplacingOccurrencesOfString: key withString: [kPredicateSubstitutionsDict objectForKey: key]];
}

for (NSInteger i = 0; i < [originalString length]; i++) {
    NSString* charString = [originalString substringWithRange: NSMakeRange(i, 1)];
    NSString* bfString;
    NSString* afString;

    if (i == 0) {
            bfString = @"";
    }
    else {
            bfString = [originalString substringWithRange: NSMakeRange(i - 1, 1)];
    }

    if (i == [originalString length] - 1) {
            afString = @"";
    }
    else {
            afString = [originalString substringWithRange: NSMakeRange(i + 1, 1)];
    }

    predFormat = [predFormat stringByReplacingOccurrencesOfString: @"Character Before" withString: [NSString stringWithFormat: @"\"%@\"", bfString]];
    predFormat = [predFormat stringByReplacingOccurrencesOfString: @"Character After" withString: [NSString stringWithFormat: @"\"%@\"", afString]];
    predFormat = [predFormat stringByReplacingOccurrencesOfString: @"Character" withString: [NSString stringWithFormat: @"\"%@\"", charString]];

    NSPredicate* newPred = [NSPredicate predicateWithFormat: predFormat];
    if ([newPred evaluateWithObject: self]) { // self just so I give it something (nothing is actually gotten from self)
        // if predicate evaluates to true, then do something exciting!
    }
}
</code>```

So, here you go, this is a simplified version of what I am doing. If you see any typos, most probably they're not in my code, because I've edited this quite a bit so it would be simpler.

To summarize:

I need to evaluate the predicate the user makes against many characters, modifying it quite a bit, while trying to be as efficient as possible

The problems I find with my approach are:

I don't think it's clean at all

I have no guarantee that it will work on every case (when one of the character is a newline/enter character, the predicate raises an error saying it can't understand the format)

That's all folks! Thanks for reading thus far. May your god be with you when solving this mess!

EDIT: Just to clarify things abut, I would add that what seems the trigger to this problem is the fact that I cannot, right at the start when I setup the predicate editor, define one constant with a name (that gets displayed to the user) and a value that represents that constant and gets inserted in the predicate format. The same thing for keypaths: if I could have one display name, and then one value that would be those var strings for predicate ($VAR or whatever it is) all the problems would be solved. If this is possible, please tell me how. If it is impossible, then please focus on the other problems I describe.

答:
So the main question:

Can you build an NSPredicateEditorRowTemplate that uses different constants than what's displayed in the user interface?

Answer: yes.  You used to be able to set this up in Interface Builder, but my attempts to do so in Xcode 4 have been unsuccessful.  It's possible that the capability was removed in the IB => Xcode 4 merge.

Fortunately, you can do it in code.  Unfortunately, it requires an NSPredicateEditorRowTemplate subclass.  I haven't found a way to do it without such a subclass.

The gist is to override -templateViews in your row template, and do something like this:

```<code>- (NSArray *)templateViews {
  NSArray *views = [super templateViews];
  // views[0] is the left-hand popup
  // views[1] is the operator popup
  // views[2] is the right-hand side (textfield, popup, whatever)
  NSPopUpButton *left = [views objectAtIndex:0];
  NSArray *items = [left itemArray];
  for (NSMenuItem *item in items) {
    //the representedObject of the item is the expression that will be used in the predicate
    NSExpression *keyPathExpression = [item representedObject];

    //we can alter the -title of the menuItem without altering the expression object
    if ([[keyPathExpression keyPath] isEqual:@"before"]) {
      [item setTitle:@"Character Before"];
    } else if ([[keyPathExpression keyPath] isEqual:@"after"]) {
      [item setTitle:@"Character After"];
    }
  }
  return views;
}
</code>```

And voilá!  A popup in your predicate editor where the title does not match the keypath.

edit

The other way to solve this (without subclassing!) would be to put your custom text in a .strings file and "localize" your editor to English (or whatever language you want).

Localizing NSPredicateEditor

Followup to Localizing NSPredicateEditor

Imagine this situation: a user puts in the predicate editor this expression Character/is not/Number. The format for that predicate would be "character != "0123456789" This is always true, even if the character is a number! How do I "replace" these operators: is/is not with their real functions IN/NOT (IN ...)?

If you were to express these comparisons in a predicate, you probably wouldn't use != and ==.  Likely, you'd want to do something like:

```<code>character MATCHES '[0-9]'
</code>```

And one of:

```<code>character MATCHES '[^0-9]'
NOT(character MATCHES '[0-9]')
</code>```

For this, the way that I can think of to do this would be to have two separate row templates.  One would recognize and display predicates in the first format (MATCHES '[0-9]'), and the second would recognize and display the negation.  You're starting to get into the weird realm of NSPredicateEditorRowTemplates, I think.  I'm still not really sure what you're trying to accomplish and why you want to be matching every character of a string against a predicate, but whatever.

For more information on how to create custom row templates, check out these two blog posts:

Creating a simple NSPredicateEditorRowTemplate

Creating an advanced NSPredicateEditorRowTemplate

ContentLicense: CC BY-SA 3.0

Title: Using NSPredicate to analyze strings

Body:
Howdy! This question is pretty long so be sure to have a seat first :)

At one point in my code I get a string from the user, and I analyze that string. By analyzing I mean going through every character and mathcing it against a predicate the user has set in an NSPredicateEditor. The predicate is setup progamatically this way:

NSArray* keyPaths = [NSArray arrayWithObjects:
                         [NSExpression expressionForKeyPath: @"Character"],
                         [NSExpression expressionForKeyPath: @"Character Before"],
                         [NSExpression expressionForKeyPath: @"Character After"],
                         nil];
// -----------------------------------------
NSArray* constants = [NSArray arrayWithObjects:
                      [NSExpression expressionForConstantValue: @"Any letter"],
                      [NSExpression expressionForConstantValue: @"Letter (uppercase)"],
                      [NSExpression expressionForConstantValue: @"Letter (lowercase)"],
                      [NSExpression expressionForConstantValue: @"Number"],
                      [NSExpression expressionForConstantValue: @"Alphanumerical"],
                      [NSExpression expressionForConstantValue: @"Ponctuation Mark"],
                      nil];
// -----------------------------------------
NSArray* compoundTypes = [NSArray arrayWithObjects:
                          [NSNumber numberWithInteger: NSNotPredicateType],
                          [NSNumber numberWithInteger: NSAndPredicateType],
                          [NSNumber numberWithInteger: NSOrPredicateType],
                          nil];
// -----------------------------------------
NSArray* operatorsA = [NSArray arrayWithObjects:
                       [NSNumber numberWithInteger: NSEqualToPredicateOperatorType],
                       [NSNumber numberWithInteger: NSNotEqualToPredicateOperatorType],
                       nil];

NSArray* operatorsB = [NSArray arrayWithObjects:
                       [NSNumber numberWithInteger: NSInPredicateOperatorType],
                       nil];
// -----------------------------------------
NSPredicateEditorRowTemplate* template1 = [[NSPredicateEditorRowTemplate alloc] initWithLeftExpressions: keyPaths
                                                                                rightExpressions: constants
                                                                                modifier: NSDirectPredicateModifier
                                                                                operators: operatorsA
                                                                                options: 0];

NSPredicateEditorRowTemplate* template2 = [[NSPredicateEditorRowTemplate alloc] initWithLeftExpressions: keyPaths
                                                                           rightExpressionAttributeType: NSStringAttributeType
                                                                                modifier: NSDirectPredicateModifier
                                                                                operators: operatorsB
                                                                                options: 0];

NSPredicateEditorRowTemplate* compound = [[NSPredicateEditorRowTemplate alloc] initWithCompoundTypes: compoundTypes];
// -----------------------------------------
NSArray* rowTemplates = [NSArray arrayWithObjects: template1, template2, compound, nil];

[myPredicateEditor setRowTemplates: rowTemplates];

So you can see I have three keypaths and some constants they can be compared with.
When analyzing the string I basically want to do this, in pseudocode:

originalString = [string from NSTextView]
for (char in originalString)
    bChar = [character before char]
    aChar = [character after char]

    predicate = [predicate from myPredicateEditor]

    // using predicate - problem!
    result = [evaluate predicate with:
               bChar somehow 'linked' to keypath 'Character Before'
               char 'linked' to 'Character'
               aChar 'linked' to 'Character After' // These values change, of course
              and also:
               constant "All letters" as "abc...WXYZ"
               constant "Numbers" as "0123456789"
               etc for all other constants set up  // These don't
              ]

    if (result) then do something with char, bChar and aChar

You can see where my problem basically lies:

'Character Before/After' cannot be keypaths because of the space, but I want to keep it that way as it is more beautiful for the user (imagine having something as 'characterBefore' instead...)

Constants such as 'Numbers' actually represent strings like '0123456789', witch I can't display to the user as well

I was able to find a workaround to this problem, but I now it doesn't work with every character and it is also very unefficient (in my opinion, at least). What I do is get the predicate format from the predicate, replace what I have to replace, and evaluate that new format instead. Now for some real code that explains this:

#define kPredicateSubstitutionsDict [NSDictionary dictionaryWithObjectsAndKeys: \
@"IN 'abcdefghijklmnopqrstuvwxyz'", @"== \"Letter (lowercase)\"", \
@"IN 'ABCDEFGHIJKLMNOPQRSTUVWXYZ'", @"== \"Letter (uppercase)\"", \
@"IN 'abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ'", @"== \"Any letter\"", \
@"IN '1234567890'", @"== \"Number\"", \
@"IN 'abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ1234567890'", @"== \"Alphanumerical\"", \
@"IN ',.;:!?'", @"== \"Ponctuation Mark\"", \
\
@"MATCHES '[^a-z]'"         , @"!= \"Letter (lowercase)\"", \
@"MATCHES '[^A-Z]'"         , @"!= \"Letter (uppercase)\"", \
@"MATCHES '[^a-zA-Z]'"      , @"!= \"Any letter\"", \
@"MATCHES '[^0-9]'"         , @"!= \"Number\"", \
@"MATCHES '[^a-zA-Z0-9]'"   , @"!= \"Alphanumerical\"", \
@"MATCHES '[^,\.;:!\?]'"  , @"!= \"Ponctuation Mark\"", \
\
nil]

// NSPredicate* predicate is setup in another place
// NSString* originalString is also setup in another place
NSString* predFormat = [predicate predicateFormat];
for (NSString* key in [kPredicateSubstitutionsDict allKeys]) {
    prefFormat = [predFormat stringByReplacingOccurrencesOfString: key withString: [kPredicateSubstitutionsDict objectForKey: key]];
}

for (NSInteger i = 0; i < [originalString length]; i++) {
    NSString* charString = [originalString substringWithRange: NSMakeRange(i, 1)];
    NSString* bfString;
    NSString* afString;

    if (i == 0) {
            bfString = @"";
    }
    else {
            bfString = [originalString substringWithRange: NSMakeRange(i - 1, 1)];
    }

    if (i == [originalString length] - 1) {
            afString = @"";
    }
    else {
            afString = [originalString substringWithRange: NSMakeRange(i + 1, 1)];
    }

    predFormat = [predFormat stringByReplacingOccurrencesOfString: @"Character Before" withString: [NSString stringWithFormat: @"\"%@\"", bfString]];
    predFormat = [predFormat stringByReplacingOccurrencesOfString: @"Character After" withString: [NSString stringWithFormat: @"\"%@\"", afString]];
    predFormat = [predFormat stringByReplacingOccurrencesOfString: @"Character" withString: [NSString stringWithFormat: @"\"%@\"", charString]];

    NSPredicate* newPred = [NSPredicate predicateWithFormat: predFormat];
    if ([newPred evaluateWithObject: self]) { // self just so I give it something (nothing is actually gotten from self)
        // if predicate evaluates to true, then do something exciting!
    }
}

So, here you go, this is a simplified version of what I am doing. If you see any typos, most probably they're not in my code, because I've edited this quite a bit so it would be simpler.

To summarize:

I need to evaluate the predicate the user makes against many characters, modifying it quite a bit, while trying to be as efficient as possible

The problems I find with my approach are:

I don't think it's clean at all

I have no guarantee that it will work on every case (when one of the character is a newline/enter character, the predicate raises an error saying it can't understand the format)

That's all folks! Thanks for reading thus far. May your god be with you when solving this mess!

EDIT: Just to clarify things abut, I would add that what seems the trigger to this problem is the fact that I cannot, right at the start when I setup the predicate editor, define one constant with a name (that gets displayed to the user) and a value that represents that constant and gets inserted in the predicate format. The same thing for keypaths: if I could have one display name, and then one value that would be those var strings for predicate ($VAR or whatever it is) all the problems would be solved. If this is possible, please tell me how. If it is impossible, then please focus on the other problems I describe.

Body:
So the main question:

Can you build an NSPredicateEditorRowTemplate that uses different constants than what's displayed in the user interface?

Answer: yes.  You used to be able to set this up in Interface Builder, but my attempts to do so in Xcode 4 have been unsuccessful.  It's possible that the capability was removed in the IB => Xcode 4 merge.

Fortunately, you can do it in code.  Unfortunately, it requires an NSPredicateEditorRowTemplate subclass.  I haven't found a way to do it without such a subclass.

The gist is to override -templateViews in your row template, and do something like this:

- (NSArray *)templateViews {
  NSArray *views = [super templateViews];
  // views[0] is the left-hand popup
  // views[1] is the operator popup
  // views[2] is the right-hand side (textfield, popup, whatever)
  NSPopUpButton *left = [views objectAtIndex:0];
  NSArray *items = [left itemArray];
  for (NSMenuItem *item in items) {
    //the representedObject of the item is the expression that will be used in the predicate
    NSExpression *keyPathExpression = [item representedObject];

    //we can alter the -title of the menuItem without altering the expression object
    if ([[keyPathExpression keyPath] isEqual:@"before"]) {
      [item setTitle:@"Character Before"];
    } else if ([[keyPathExpression keyPath] isEqual:@"after"]) {
      [item setTitle:@"Character After"];
    }
  }
  return views;
}

And voilá!  A popup in your predicate editor where the title does not match the keypath.

edit

The other way to solve this (without subclassing!) would be to put your custom text in a .strings file and "localize" your editor to English (or whatever language you want).

Localizing NSPredicateEditor

Followup to Localizing NSPredicateEditor

Imagine this situation: a user puts in the predicate editor this expression Character/is not/Number. The format for that predicate would be "character != "0123456789" This is always true, even if the character is a number! How do I "replace" these operators: is/is not with their real functions IN/NOT (IN ...)?

If you were to express these comparisons in a predicate, you probably wouldn't use != and ==.  Likely, you'd want to do something like:

character MATCHES '[0-9]'

And one of:

character MATCHES '[^0-9]'
NOT(character MATCHES '[0-9]')

For this, the way that I can think of to do this would be to have two separate row templates.  One would recognize and display predicates in the first format (MATCHES '[0-9]'), and the second would recognize and display the negation.  You're starting to get into the weird realm of NSPredicateEditorRowTemplates, I think.  I'm still not really sure what you're trying to accomplish and why you want to be matching every character of a string against a predicate, but whatever.

For more information on how to create custom row templates, check out these two blog posts:

Creating a simple NSPredicateEditorRowTemplate

Creating an advanced NSPredicateEditorRowTemplate


问:
AWS Elastic Beanstalk: WSGI path incorrect?
I'm attempting to deploy my first application to EB and am following along with this turorial: https://docs.aws.amazon.com/elasticbeanstalk/latest/dg/create-deploy-python-django.html

Unfortunately, I'm still getting a 502 error when deploying the final app. I'm confused because I've followed the directions to the tee.

I'm getting the following error

```<code>ImportError: Failed to find application, did you mean 'ebdjango/wsgi:application'?
</code>```

I'm not sure what this means. Per the instructions, I edited the django.config file to include this text:

```<code>option_settings:
  aws:elasticbeanstalk:container:python:
    WSGIPath: ebdjango/wsgi.py
</code>```

This appears to match my file structure:

```<code>- ebdjango
  -.ebextensions
    - django.config
  - .elasticbeanstalk
  - ebdjango
    _ __init__.py
    - settings.py
    - urls.py
    - wsgi.py
  - manage.py
  - requirements.txt
</code>```

So the config file is set up correctly, right?

I'm running Python 3.7 and Django 2.2.

I know that EB searches for application.py, and I thought the config file is supposed to point the server towards my custom app? What am I missing here?

EDIT: I'm also getting this error:

```<code>ModuleNotFoundError: No module named 'ebdjango/wsgi'
</code>```

Is something off about my file structure?

EDIT 2: I forgot to include the init.py file in my post, see Ben's comment.

答:
In your django.config change:

```<code>option_settings:
  aws:elasticbeanstalk:container:python:
    WSGIPath: ebdjango.wsgi
</code>```

And in your

```<code>import os
from django.core.wsgi import get_wsgi_application
os.environ["DJANGO_SETTINGS_MODULE"] = "ebdjango.settings"
application = get_wsgi_application()
</code>```

Body:
I'm attempting to deploy my first application to EB and am following along with this turorial: https://docs.aws.amazon.com/elasticbeanstalk/latest/dg/create-deploy-python-django.html

Unfortunately, I'm still getting a 502 error when deploying the final app. I'm confused because I've followed the directions to the tee.

I'm getting the following error

ImportError: Failed to find application, did you mean 'ebdjango/wsgi:application'?

I'm not sure what this means. Per the instructions, I edited the django.config file to include this text:

option_settings:
  aws:elasticbeanstalk:container:python:
    WSGIPath: ebdjango/wsgi.py

This appears to match my file structure:

- ebdjango
  -.ebextensions
    - django.config
  - .elasticbeanstalk
  - ebdjango
    _ __init__.py
    - settings.py
    - urls.py
    - wsgi.py
  - manage.py
  - requirements.txt

So the config file is set up correctly, right?

I'm running Python 3.7 and Django 2.2.

I know that EB searches for application.py, and I thought the config file is supposed to point the server towards my custom app? What am I missing here?

EDIT: I'm also getting this error:

ModuleNotFoundError: No module named 'ebdjango/wsgi'

Is something off about my file structure?

EDIT 2: I forgot to include the init.py file in my post, see Ben's comment.

Body:
In your django.config change:

option_settings:
  aws:elasticbeanstalk:container:python:
    WSGIPath: ebdjango.wsgi

And in your

import os
from django.core.wsgi import get_wsgi_application
os.environ["DJANGO_SETTINGS_MODULE"] = "ebdjango.settings"
application = get_wsgi_application()


问:
Validating Undefined in React Native
I have a situation where I'm trying to pass some params via onPress to another screen. However I'm unable to capture the Undefined state and it gives me the red screen error -

Type Error: undefined is not an object.

Here's my snippet. Am I missing something?

```<code>const pressHandle = (item) => {
        const capVal = state.payload.find((grabVal) => grabVal.jobId === item.jobId).jobId;

        console.log(capVal); // in a defined case, I have a log so the query is correct.

        if( typeof(capVal) !== undefined || typeof(capVal) != null ) {
            setGrabber(capVal);
        } else {
            setGrabber('undefined!');
        }
        console.log(grabber);
}
</code>```

答:
You just have to do a null check your error is probably appearing due to accessing a property of an undefined item when finding an item.

Adding ?.jobId will access the jobId only if an item is found and then you can check if(capVal) which will run if capVal has a value

```<code>const pressHandle = (item) => {
        const capVal = state.payload.find((grabVal) => grabVal.jobId === item.jobId)?.jobId;

        console.log(capVal); // in a defined case, I have a log so the query is correct.

        if(capVal) {
            setGrabber(capVal);
        } else {
            setGrabber('undefined!');
        }
        console.log(grabber);
}
</code>```

Title: Validating Undefined in React Native

Body:
I have a situation where I'm trying to pass some params via onPress to another screen. However I'm unable to capture the Undefined state and it gives me the red screen error -

Type Error: undefined is not an object.

Here's my snippet. Am I missing something?

const pressHandle = (item) => {
        const capVal = state.payload.find((grabVal) => grabVal.jobId === item.jobId).jobId;

        console.log(capVal); // in a defined case, I have a log so the query is correct.

        if( typeof(capVal) !== undefined || typeof(capVal) != null ) {
            setGrabber(capVal);
        } else {
            setGrabber('undefined!');
        }
        console.log(grabber);
}

Body:
You just have to do a null check your error is probably appearing due to accessing a property of an undefined item when finding an item.

Adding ?.jobId will access the jobId only if an item is found and then you can check if(capVal) which will run if capVal has a value

const pressHandle = (item) => {
        const capVal = state.payload.find((grabVal) => grabVal.jobId === item.jobId)?.jobId;

        console.log(capVal); // in a defined case, I have a log so the query is correct.

        if(capVal) {
            setGrabber(capVal);
        } else {
            setGrabber('undefined!');
        }
        console.log(grabber);
}


问:
Program not reading '?' after separation of strings by '?' as well as '.'
I have an original text file that is one very long string. I separated this file / string using '?' and full stop '.' in order to be able to go through it sentence by sentence, and I saved these sentences / strings into a list called sentences_list.

I'm reading the strings in that list, in order to count the number of '?' symbols but it's not picking up the '?' symbol at all. How can this be?
Here is the code for the function that looks for the '?' :

```<code>def count_question_symbols(list):
    count = 0
    for item in list:
        if "?" in item:
            count += 1
    print("Questions asked", count, "times")

count_question_symbols(sentences_list)
</code>```

And here is the code where the 'sentences_list' is created:

```<code>file = open("classic_cars.txt", "r")
sentences_list = []
for line in file:
    sentences_list.extend(re.split(r"[?\.]\s*", line))
</code>```

答:
The separation isn't that necessary:

```<code>with open('text.txt','r') as f: # Stores all text as a string in a variable
    sentences_list = f.read()

def count_question_symbols(string):
    count = len(string)-len(string.replace('?','')) # Calculate the difference when subtraction original string with partial string
    print("Questions asked", count, "times")

count_question_symbols(sentences_list)
</code>```

Output:

```<code>Questions asked 3 times
</code>```

Body:
I have an original text file that is one very long string. I separated this file / string using '?' and full stop '.' in order to be able to go through it sentence by sentence, and I saved these sentences / strings into a list called sentences_list.

I'm reading the strings in that list, in order to count the number of '?' symbols but it's not picking up the '?' symbol at all. How can this be?
Here is the code for the function that looks for the '?' :

def count_question_symbols(list):
    count = 0
    for item in list:
        if "?" in item:
            count += 1
    print("Questions asked", count, "times")

count_question_symbols(sentences_list)

And here is the code where the 'sentences_list' is created:

file = open("classic_cars.txt", "r")
sentences_list = []
for line in file:
    sentences_list.extend(re.split(r"[?\.]\s*", line))

Body:
The separation isn't that necessary:

with open('text.txt','r') as f: # Stores all text as a string in a variable
    sentences_list = f.read()

def count_question_symbols(string):
    count = len(string)-len(string.replace('?','')) # Calculate the difference when subtraction original string with partial string
    print("Questions asked", count, "times")

count_question_symbols(sentences_list)

Output:

Questions asked 3 times


问:
Adding multiple OnClickListeners to a RecyclerView using Kotlin
I'm in the process of fiddling my way to a working app using Kotlin and I have hit a roadblock when trying to implement OnClickListeners for my three buttons. I have my RecyclerView populate properly, but despite following the recommendations on this SO post (except in Kotlin) and following the documentation, though I am still having trouble getting the implementation to work.

The code below is my adapter class for the implementation.

```<code>class BrowseHabitsAdapter(private val habits: ArrayList<Habit>) :
    RecyclerView.Adapter<BrowseHabitsAdapter.ViewHolder>() {

    override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): ViewHolder {
        val itemView = LayoutInflater.from(parent.context).inflate(R.layout.habit_card, parent, false)

        return ViewHolder(itemView, object: HabitClickListener {
            override fun onDecrease(position: Int) {
                val streak = itemView.dayCounter.text.toString().toInt()
                itemView.dayCounter.text = streak.dec().toString()
            }

            override fun onIncrease(position: Int) {
                val streak = itemView.dayCounter.text.toString().toInt()
                itemView.dayCounter.text = streak.inc().toString()
            }

            override fun onEdit(position: Int) {
                TODO("Change Activity to Edit")
            }
        })

    }

    override fun onBindViewHolder(holder: ViewHolder, position: Int) {
        val currentItem = habits[position]

        holder.habitTitle.text = currentItem.title
        holder.streak.text = currentItem.streak.toString()
    }

    override fun getItemCount() = habits.size

    class ViewHolder(itemView : View, listener : HabitClickListener) : RecyclerView.ViewHolder(itemView), View.OnClickListener {
        val habitTitle: TextView = itemView.habitTitle
        val streak: TextView = itemView.dayCounter
        val decreaseCounterButton : Button = itemView.decreaseCounterButton
        val increaseCounterButton : Button = itemView.increaseCounterButton
        val listener = listener

        init {
            decreaseCounterButton.setOnClickListener(this)
            increaseCounterButton.setOnClickListener(this)
        }

        override fun onClick(v: View?) {
            when (itemView.id) {
                itemView.decreaseCounterButton.id -> listener.onDecrease(this.layoutPosition)
                itemView.increaseCounterButton.id -> listener.onIncrease(this.layoutPosition)
            }
        }
    }

    interface HabitClickListener {
        fun onDecrease(position : Int)
        fun onIncrease(position : Int)
        fun onEdit(position : Int)
    }
}
</code>```

and the following is my XML code defining one of my cards:

```<code><?xml version="1.0" encoding="utf-8"?>
<androidx.cardview.widget.CardView xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    xmlns:tools="http://schemas.android.com/tools"
    android:id="@+id/cardView"
    android:layout_width="match_parent"
    android:layout_height="wrap_content"
    android:layout_marginStart="10dp"
    android:layout_marginTop="10dp"
    android:layout_marginEnd="10dp"
    app:cardBackgroundColor="#eeeeee"
    app:cardCornerRadius="10dp"
    app:layout_constraintEnd_toEndOf="parent"
    app:layout_constraintStart_toStartOf="parent"
    app:layout_constraintTop_toTopOf="parent"
    tools:context=".MainActivity">

    <LinearLayout
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:orientation="vertical">

        <LinearLayout
            android:id="@+id/cardHeader"
            android:layout_width="match_parent"
            android:layout_height="match_parent"
            android:orientation="horizontal">

            <TextView
                android:id="@+id/habitTitle"
                android:layout_width="wrap_content"
                android:layout_height="wrap_content"
                android:layout_marginLeft="10dp"
                android:layout_marginTop="10dp"
                android:layout_marginRight="10dp"
                android:text="@string/default_card_title"
                android:textSize="18sp" />

            <Space
                android:layout_width="0dp"
                android:layout_height="wrap_content"
                android:layout_gravity="center"
                android:layout_weight="1" />

            <ImageView
                android:id="@+id/settingsIcon"
                android:layout_width="25dp"
                android:layout_height="25dp"
                android:layout_gravity="bottom"
                android:layout_marginRight="10dp"
                app:srcCompat="@android:drawable/ic_menu_manage" />
        </LinearLayout>

        <LinearLayout
            android:id="@+id/cardControls"
            android:layout_width="match_parent"
            android:layout_height="match_parent"
            android:gravity="center"
            android:orientation="horizontal">

            <Button
                android:id="@+id/decreaseCounterButton"
                android:layout_width="wrap_content"
                android:layout_height="wrap_content"
                android:layout_margin="10dp"
                android:text="-"
                android:textAllCaps="false"
                android:textSize="30sp" />

            <Space
                android:layout_width="wrap_content"
                android:layout_height="wrap_content"
                android:layout_weight="1" />

            <TextView
                android:id="@+id/dayCounter"
                android:layout_width="wrap_content"
                android:layout_height="wrap_content"
                android:layout_margin="10dp"
                android:fontFamily="sans-serif-medium"
                android:text="0"
                android:textAlignment="center"
                android:textSize="30sp"
                android:textStyle="bold" />

            <Space
                android:layout_width="wrap_content"
                android:layout_height="wrap_content"
                android:layout_weight="1" />

            <Button
                android:id="@+id/increaseCounterButton"
                android:layout_width="wrap_content"
                android:layout_height="wrap_content"
                android:layout_margin="10dp"
                android:text="+"
                android:textSize="30sp" />
        </LinearLayout>

    </LinearLayout>

</androidx.cardview.widget.CardView>
</code>```

Any additional explanation that can be provided as to what I did wrong and what is going on in detail would be really appreciated!

答:
You are in kotlin so need to implement View.OnClickListener you can directly use setOnClickListener on any view.

Inside your ViewHolder Class:

```<code>itemView.increaseCounterButton.setOnClickListener{

       listener.onIncrease(this.layoutPosition)
 }

itemView.decreaseCounterButton.setOnClickListener{

      listener.onDecrease(this.layoutPosition)
 }
</code>```

Body:
I'm in the process of fiddling my way to a working app using Kotlin and I have hit a roadblock when trying to implement OnClickListeners for my three buttons. I have my RecyclerView populate properly, but despite following the recommendations on this SO post (except in Kotlin) and following the documentation, though I am still having trouble getting the implementation to work.

The code below is my adapter class for the implementation.

class BrowseHabitsAdapter(private val habits: ArrayList<Habit>) :
    RecyclerView.Adapter<BrowseHabitsAdapter.ViewHolder>() {

    override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): ViewHolder {
        val itemView = LayoutInflater.from(parent.context).inflate(R.layout.habit_card, parent, false)

        return ViewHolder(itemView, object: HabitClickListener {
            override fun onDecrease(position: Int) {
                val streak = itemView.dayCounter.text.toString().toInt()
                itemView.dayCounter.text = streak.dec().toString()
            }

            override fun onIncrease(position: Int) {
                val streak = itemView.dayCounter.text.toString().toInt()
                itemView.dayCounter.text = streak.inc().toString()
            }

            override fun onEdit(position: Int) {
                TODO("Change Activity to Edit")
            }
        })

    }

    override fun onBindViewHolder(holder: ViewHolder, position: Int) {
        val currentItem = habits[position]

        holder.habitTitle.text = currentItem.title
        holder.streak.text = currentItem.streak.toString()
    }

    override fun getItemCount() = habits.size

    class ViewHolder(itemView : View, listener : HabitClickListener) : RecyclerView.ViewHolder(itemView), View.OnClickListener {
        val habitTitle: TextView = itemView.habitTitle
        val streak: TextView = itemView.dayCounter
        val decreaseCounterButton : Button = itemView.decreaseCounterButton
        val increaseCounterButton : Button = itemView.increaseCounterButton
        val listener = listener

        init {
            decreaseCounterButton.setOnClickListener(this)
            increaseCounterButton.setOnClickListener(this)
        }

        override fun onClick(v: View?) {
            when (itemView.id) {
                itemView.decreaseCounterButton.id -> listener.onDecrease(this.layoutPosition)
                itemView.increaseCounterButton.id -> listener.onIncrease(this.layoutPosition)
            }
        }
    }

    interface HabitClickListener {
        fun onDecrease(position : Int)
        fun onIncrease(position : Int)
        fun onEdit(position : Int)
    }
}

and the following is my XML code defining one of my cards:

<?xml version="1.0" encoding="utf-8"?>
<androidx.cardview.widget.CardView xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    xmlns:tools="http://schemas.android.com/tools"
    android:id="@+id/cardView"
    android:layout_width="match_parent"
    android:layout_height="wrap_content"
    android:layout_marginStart="10dp"
    android:layout_marginTop="10dp"
    android:layout_marginEnd="10dp"
    app:cardBackgroundColor="#eeeeee"
    app:cardCornerRadius="10dp"
    app:layout_constraintEnd_toEndOf="parent"
    app:layout_constraintStart_toStartOf="parent"
    app:layout_constraintTop_toTopOf="parent"
    tools:context=".MainActivity">

    <LinearLayout
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:orientation="vertical">

        <LinearLayout
            android:id="@+id/cardHeader"
            android:layout_width="match_parent"
            android:layout_height="match_parent"
            android:orientation="horizontal">

            <TextView
                android:id="@+id/habitTitle"
                android:layout_width="wrap_content"
                android:layout_height="wrap_content"
                android:layout_marginLeft="10dp"
                android:layout_marginTop="10dp"
                android:layout_marginRight="10dp"
                android:text="@string/default_card_title"
                android:textSize="18sp" />

            <Space
                android:layout_width="0dp"
                android:layout_height="wrap_content"
                android:layout_gravity="center"
                android:layout_weight="1" />

            <ImageView
                android:id="@+id/settingsIcon"
                android:layout_width="25dp"
                android:layout_height="25dp"
                android:layout_gravity="bottom"
                android:layout_marginRight="10dp"
                app:srcCompat="@android:drawable/ic_menu_manage" />
        </LinearLayout>

        <LinearLayout
            android:id="@+id/cardControls"
            android:layout_width="match_parent"
            android:layout_height="match_parent"
            android:gravity="center"
            android:orientation="horizontal">

            <Button
                android:id="@+id/decreaseCounterButton"
                android:layout_width="wrap_content"
                android:layout_height="wrap_content"
                android:layout_margin="10dp"
                android:text="-"
                android:textAllCaps="false"
                android:textSize="30sp" />

            <Space
                android:layout_width="wrap_content"
                android:layout_height="wrap_content"
                android:layout_weight="1" />

            <TextView
                android:id="@+id/dayCounter"
                android:layout_width="wrap_content"
                android:layout_height="wrap_content"
                android:layout_margin="10dp"
                android:fontFamily="sans-serif-medium"
                android:text="0"
                android:textAlignment="center"
                android:textSize="30sp"
                android:textStyle="bold" />

            <Space
                android:layout_width="wrap_content"
                android:layout_height="wrap_content"
                android:layout_weight="1" />

            <Button
                android:id="@+id/increaseCounterButton"
                android:layout_width="wrap_content"
                android:layout_height="wrap_content"
                android:layout_margin="10dp"
                android:text="+"
                android:textSize="30sp" />
        </LinearLayout>

    </LinearLayout>

</androidx.cardview.widget.CardView>

Any additional explanation that can be provided as to what I did wrong and what is going on in detail would be really appreciated!

Body:
You are in kotlin so need to implement View.OnClickListener you can directly use setOnClickListener on any view.

Inside your ViewHolder Class:

itemView.increaseCounterButton.setOnClickListener{

       listener.onIncrease(this.layoutPosition)
 }

itemView.decreaseCounterButton.setOnClickListener{

      listener.onDecrease(this.layoutPosition)
 }


问:
How do I know when an attachment attribute is being added to my NSTextView?
Because of the semantics of certain NSTextView attachments in my application, I want to know when they are inserted or deleted from my text storage.

My subclass of NSTextView implements the shouldChangeTextInRange:replacementString: method, which allows me to easily see when an attachment is about to be replaced (I can search the text storage at the specified range).

Because the replacement string is just an NSString and not an NSAttributedString, I have no way of seeing from this method whether an attachment is being inserted. The documentation even goes so far as to say that the string may be nil if "only attributes" are being edited.

So the question is, what's the best override point to see when an attachment is being inserted? Or perhaps as useful: what's the best override point to see when attributes are being modified?

Update: I said above I had no way of knowing whether an attachment is being inserted. It's pointed out to me that I can tell that "an" attachment is involved, because the string will contain the magic NSAttachmentCharacter. But I won't have specific information about the attachment until after the edit is complete.

答: Delegate methods have various corner cases. It's better to subclass NSTextStorage class.


问:
HTML form: validation and preventing page refresh when submit
I have an HTML form with a submit button and would like to prevent page refresh after clicking Submit (I also have some AJAX calls in the click handler as well):

var rating_form = d3.select("body")
  .append('form')
  .attr('class', 'rating');

 // Appending up and down vote radio button
 var radio_groups = rating_form.append('div').attr('class', 'form-group');

 // Radio for up
 var radio_grp_chk = radio_groups
  .append('div')
  .attr('class', 'form-check form-check-inline upvote');
 radio_grp_chk
  .append('input')
  .attr('class', 'form-check-input')
  .attr('type', 'radio')
  .attr('name', 'voting-radio')
  .attr('value', 'thumbup')
  .attr("required", "");
 radio_grp_chk.append('span').text("upvote");

 // Radio for down
 var radio_grp_chk2 = radio_groups
  .append('div')
  .attr('class', 'form-check form-check-inline downvote');
 radio_grp_chk2
  .append('input')
  .attr('class', 'form-check-input')
  .attr('type', 'radio')
  .attr('name', 'voting-radio')
  .attr('value', 'thumbdown')
  .attr("required", "");
 radio_grp_chk2.append('span').text("downvote");

 // Appending text area
 rating_form
  .append('div')
  .attr('class', 'form-group')
  .append('textarea')
  .attr('class', 'form-control feedback-text')
  .attr('placeholder', 'Enter your text...');

 // Submit button
 rating_form
  .append('button')
  .attr('type', 'submit')
  .attr('class', 'btn btn-primary rating-btn')
  .text('Submit!');

  // Bind click event
  rating_form.select('.rating-btn').on('click', function () {
  d3.event.preventDefault();

  var current_text = $("form").find("textarea").val();
  var current_vote = $("form").find('input[name=voting-radio]:checked').val()

  console.log(
   'My text is: ' +
    current_text +
    " and the vote is: " +
    current_vote
  );

  // Some further AJAX calls here
 });```
<pre class="snippet-code-html lang-html prettyprint-override"><code><!DOCTYPE html>
<head>
    <!-- bootstrap -->
    <link rel="stylesheet" href="https://stackpath.bootstrapcdn.com/bootstrap/4.1.3/css/bootstrap.min.css"
        crossorigin="anonymous">
</head>

<body>
    <script src="https://d3js.org/d3.v5.min.js"></script>
    <!-- jQuery -->
    <script src="https://code.jquery.com/jquery-3.5.0.min.js" crossorigin="anonymous"></script>
</body></code>```

To prevent auto-refresh when submitting, I use d3.event.preventDefault(); in the click listener.

However, this makes the form not validate (my radio buttons have required attribute) => clicking submit without selecting a radio choice will not show any error. So how do I resolve this?

答:
Not sure where this d3 object comes from but your submit handler probably needs to accept an event parameter:

```<code>  rating_form.select('.rating-btn').on('click', function (e) {
        e.preventDefault();
        ...
</code>```

For details see https://api.jquery.com/event.preventDefault/

Body:
I have an HTML form with a submit button and would like to prevent page refresh after clicking Submit (I also have some AJAX calls in the click handler as well):

var rating_form = d3.select("body")
  .append('form')
  .attr('class', 'rating');

 // Appending up and down vote radio button
 var radio_groups = rating_form.append('div').attr('class', 'form-group');

 // Radio for up
 var radio_grp_chk = radio_groups
  .append('div')
  .attr('class', 'form-check form-check-inline upvote');
 radio_grp_chk
  .append('input')
  .attr('class', 'form-check-input')
  .attr('type', 'radio')
  .attr('name', 'voting-radio')
  .attr('value', 'thumbup')
  .attr("required", "");
 radio_grp_chk.append('span').text("upvote");

 // Radio for down
 var radio_grp_chk2 = radio_groups
  .append('div')
  .attr('class', 'form-check form-check-inline downvote');
 radio_grp_chk2
  .append('input')
  .attr('class', 'form-check-input')
  .attr('type', 'radio')
  .attr('name', 'voting-radio')
  .attr('value', 'thumbdown')
  .attr("required", "");
 radio_grp_chk2.append('span').text("downvote");

 // Appending text area
 rating_form
  .append('div')
  .attr('class', 'form-group')
  .append('textarea')
  .attr('class', 'form-control feedback-text')
  .attr('placeholder', 'Enter your text...');

 // Submit button
 rating_form
  .append('button')
  .attr('type', 'submit')
  .attr('class', 'btn btn-primary rating-btn')
  .text('Submit!');

  // Bind click event
  rating_form.select('.rating-btn').on('click', function () {
  d3.event.preventDefault();

  var current_text = $("form").find("textarea").val();
  var current_vote = $("form").find('input[name=voting-radio]:checked').val()

  console.log(
   'My text is: ' +
    current_text +
    " and the vote is: " +
    current_vote
  );

  // Some further AJAX calls here
 });

<!DOCTYPE html>

    <link rel="stylesheet" href="https://stackpath.bootstrapcdn.com/bootstrap/4.1.3/css/bootstrap.min.css"
        crossorigin="anonymous">

To prevent auto-refresh when submitting, I use d3.event.preventDefault(); in the click listener.

However, this makes the form not validate (my radio buttons have required attribute) => clicking submit without selecting a radio choice will not show any error. So how do I resolve this?

Body:
Not sure where this d3 object comes from but your submit handler probably needs to accept an event parameter:

  rating_form.select('.rating-btn').on('click', function (e) {
        e.preventDefault();
        ...

For details see https://api.jquery.com/event.preventDefault/


问:
React component looks like it has a static shared state within its instances

Expected component behaviour:
- Load animation as defined by 'if' condition
- Then after 1000ms, the setTimeout function will change the state, thus rendering the 'else' part of the conditional

Additional Details
The component loads in fine, however, when I have another instance of the component created, both on alerts fire at the same time, and the this.render.state is set to true. This prevents the animation from loading as part of the conditional statement, since state.render is true... even though it should be false... Shouldn't each instance of this component display the default conditional behaviour?

Name.js Component

```<code>
export class Name extends Component {
  state = {
    render: false,
  };

  componentDidMount() {
    //alert('Test')
    setTimeout(
      function () {
        //Start the timer
        this.setState({ render: true }); //After 1 second, set render to true
      }.bind(this),
      1000
    );
  }

  render() {
    if (this.state.render === false) {
      return (
        <div className={styles.LContainer}>
          <div className={styles.ldsRing}>
            <div></div>
            <div></div>
            <div></div>
            <div></div>
          </div>
        </div>
      );
    } else {
      console.log(this.state.render)
      return (
        <div className={styles.Container}>
          <img
            className={styles.imageO}
            src={require("./Apple_logo_white.svg")}
          />
          <div className={styles.textArea}>
            <h1 className={styles.title}>{this.props.title}</h1>
            <h2 className={styles.subtitle}>
            {this.props.sub}
          </h2>
          <Input name="name" handleChange = {this.props.handleChange} />
          <ScreenButton  goDirection={this.props.backScreen}  direction="back"/>
          <ScreenButton  goDirection={this.props.nextScreen}  direction="next"/>
          </div>
        </div>
      );
    }
  }
}
</code>```

I'm also using a switch statement to render these components, could that have anything to do with it?

```<code>render() {
    //Pulling information down from state:
    const { step, name, interest, location } = this.state;
    const values = { step, name, interest, location };

    switch (step) {
      case 1:
        return (
          <Welcome
            nextScreen={this.nextScreen}
            handleChange={this.handleChange}
            values={values}
          />
        );

      case 2:
        console.log(this.state.step);
        //return <h1>GOLS</h1>
        return (
            <React.Fragment>
          <Name
            nextScreen={this.nextScreen}
            backScreen={this.backScreen}
            handleChange={this.handleChange}
            values={values}
            sub="Example text"
            title="Example text"
          />
          </React.Fragment>
        );

      case 3:
        console.log(this.state.step);
        return (
          <React.Fragment>
            <Name
              nextScreen={this.nextScreen}
              backScreen={this.backScreen}
              handleChange={this.handleChange}
              values={values}
              sub="Example text"
              title="Example text"
            />
          </React.Fragment>
        );

    }
  }

  [1]: https://i.stack.imgur.com/U0v38.gif
</code>```

答:
I just checked and confirmed it's working like this.

```<code>import React, { Component } from 'react';
export default class Name extends Component {
    constructor(props){
        super();
        this.state = {
            render: false,
          };
    }

    componentDidMount() {
      //alert('Test')
      setTimeout(
          ()=>{
            this.setState({ render: true });
          },1000
      );
    }

    render() {
      if (this.state.render === false) {
        return (
          <h1>Helloooo</h1>
        );
      } else {
        console.log(this.state.render)
        return (
          <h1>Bye</h1>
        );
      }
    }
  }
</code>```

See this: https://codesandbox.io/s/angry-breeze-gdmmy?file=/src/App.js

Body:
Expected component behaviour:
- Load animation as defined by 'if' condition
- Then after 1000ms, the setTimeout function will change the state, thus rendering the 'else' part of the conditional

Additional Details
The component loads in fine, however, when I have another instance of the component created, both on alerts fire at the same time, and the this.render.state is set to true. This prevents the animation from loading as part of the conditional statement, since state.render is true... even though it should be false... Shouldn't each instance of this component display the default conditional behaviour?

Name.js Component

export class Name extends Component {
  state = {
    render: false,
  };

  componentDidMount() {
    //alert('Test')
    setTimeout(
      function () {
        //Start the timer
        this.setState({ render: true }); //After 1 second, set render to true
      }.bind(this),
      1000
    );
  }

  render() {
    if (this.state.render === false) {
      return (

      );
    } else {
      console.log(this.state.render)
      return (

{this.props.title}

            {this.props.sub}

          <Input name="name" handleChange = {this.props.handleChange} />
          <ScreenButton  goDirection={this.props.backScreen}  direction="back"/>
          <ScreenButton  goDirection={this.props.nextScreen}  direction="next"/>

      );
    }
  }
}

I'm also using a switch statement to render these components, could that have anything to do with it?

render() {
    //Pulling information down from state:
    const { step, name, interest, location } = this.state;
    const values = { step, name, interest, location };

    switch (step) {
      case 1:
        return (
          <Welcome
            nextScreen={this.nextScreen}
            handleChange={this.handleChange}
            values={values}
          />
        );

      case 2:
        console.log(this.state.step);
        //return
GOLS

        return (
            <React.Fragment>
          <Name
            nextScreen={this.nextScreen}
            backScreen={this.backScreen}
            handleChange={this.handleChange}
            values={values}
            sub="Example text"
            title="Example text"
          />
          </React.Fragment>
        );

      case 3:
        console.log(this.state.step);
        return (
          <React.Fragment>
            <Name
              nextScreen={this.nextScreen}
              backScreen={this.backScreen}
              handleChange={this.handleChange}
              values={values}
              sub="Example text"
              title="Example text"
            />
          </React.Fragment>
        );

    }
  }

  [1]: https://i.stack.imgur.com/U0v38.gif

Body:
I just checked and confirmed it's working like this.

import React, { Component } from 'react';
export default class Name extends Component {
    constructor(props){
        super();
        this.state = {
            render: false,
          };
    }

    componentDidMount() {
      //alert('Test')
      setTimeout(
          ()=>{
            this.setState({ render: true });
          },1000
      );
    }

    render() {
      if (this.state.render === false) {
        return (
          <h1>Helloooo</h1>
        );
      } else {
        console.log(this.state.render)
        return (
          <h1>Bye</h1>
        );
      }
    }
  }

See this: https://codesandbox.io/s/angry-breeze-gdmmy?file=/src/App.js


问:
Spring: Unable to set SameSite cookie to None
I'm unable to set SameSite cookie value to None.

Following is how i'm generating ResponseCookie object.

```<code>ResponseCookie cookie = ResponseCookie.from("Hb", cookieUserId)
            .maxAge(!isEmpty(cookieUserId) ? MAX_COOKIE_DURATION : 0)
            .domain("test.com")
            .sameSite("None")
            .secure(true)
            .path("/")
            .build();
 response.addCookie(cookie)
</code>```

Curl request to endpoint

```<code>curl -X POST "localhost:8080/v1/user/v" --data "{}" -v -H 'Content-Type: application/json'
</code>```

Response:

```<code>< set-cookie: Hb=00b7be31-fc6d-4891-a07c-46b5ef2b423c; Max-Age=7776000; Expires=Fri, 8 Nov 2019 17:23:52 GMT; Path=/; Domain=test.com; Secure
</code>```

As you can see SameSite attribute is missing from the cookie.

Spring Boot (version: 2.1.3.RELEASE) dependency

```<code>        <dependency>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-webflux</artifactId>
        <exclusions>
            <exclusion>
                <groupId>org.springframework.boot</groupId>
                <artifactId>spring-boot-starter-logging</artifactId>
            </exclusion>
        </exclusions>
    </dependency>
</code>```

答: LukeSolar's answer was correct.The DefaultCookieSerializer is in the spring-session jar.So you need to add spring-session dependencies. You can refer to the official documentation https://spring.io/projects/spring-session

Body:
I'm unable to set SameSite cookie value to None.

Following is how i'm generating ResponseCookie object.

ResponseCookie cookie = ResponseCookie.from("Hb", cookieUserId)
            .maxAge(!isEmpty(cookieUserId) ? MAX_COOKIE_DURATION : 0)
            .domain("test.com")
            .sameSite("None")
            .secure(true)
            .path("/")
            .build();
 response.addCookie(cookie)

Curl request to endpoint

curl -X POST "localhost:8080/v1/user/v" --data "{}" -v -H 'Content-Type: application/json'

Response:

< set-cookie: Hb=00b7be31-fc6d-4891-a07c-46b5ef2b423c; Max-Age=7776000; Expires=Fri, 8 Nov 2019 17:23:52 GMT; Path=/; Domain=test.com; Secure

As you can see SameSite attribute is missing from the cookie.

Spring Boot (version: 2.1.3.RELEASE) dependency

        <dependency>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-webflux</artifactId>
        <exclusions>
            <exclusion>
                <groupId>org.springframework.boot</groupId>
                <artifactId>spring-boot-starter-logging</artifactId>
            </exclusion>
        </exclusions>
    </dependency>


问:
How do I reference a textarea value in another table cell?
I want to reference the content of a text area, but I keep getting undefined:

```<code>$(".send-comment").click(function(e) {
    e.preventDefault();
    var data = $(this).siblings(".comment-text").val();
    alert(data);
});

<tr>
    <td>#textAreaTag(label=false, name="comment[text]", class="comment-text")#</td>
    <td>#submitTag(value="Send", class="send-comment")#</td>
</tr>
</code>```

I suspect it might be because the send button has no siblings (it's alone in a td)... but surely, there has to be a better way to get the value than using this.parent().sibling().child()...

I'm using classes because I have several comment forms on the same page that belong to different posts.

FYI, the generated source from my framework is as expected...

答:
Try this:

```<code>$(".send-comment").click(function(e) {
    e.preventDefault();
    var prevCell = $(this).parent().prev();
    var data = $(".comment-text", prevCell).val();
    alert(data);
});
</code>```

Alternate:

```<code>$(".send-comment").click(function(e) {
    e.preventDefault();
    var data = $(".comment-text", $(this).closest("tr")).val();
    alert(data);
});
</code>```

Body:
I want to reference the content of a text area, but I keep getting undefined:

$(".send-comment").click(function(e) {
    e.preventDefault();
    var data = $(this).siblings(".comment-text").val();
    alert(data);
});

    #textAreaTag(label=false, name="comment[text]", class="comment-text")#
    #submitTag(value="Send", class="send-comment")#

I suspect it might be because the send button has no siblings (it's alone in a td)... but surely, there has to be a better way to get the value than using this.parent().sibling().child()...

I'm using classes because I have several comment forms on the same page that belong to different posts.

FYI, the generated source from my framework is as expected...

Body:
Try this:

$(".send-comment").click(function(e) {
    e.preventDefault();
    var prevCell = $(this).parent().prev();
    var data = $(".comment-text", prevCell).val();
    alert(data);
});

Alternate:

$(".send-comment").click(function(e) {
    e.preventDefault();
    var data = $(".comment-text", $(this).closest("tr")).val();
    alert(data);
});


问:
Can we get all
 values using React ref on its
 parent?
Can we get all li values by using React Refs on its UL parent? like forward refs or  children kind of???

I'm expecting to do the below using React Ref.

```<code>let listItem = getElementsByTagName('li');

let anchor;

let listAnchorVal;

for(let i = 0; i < listItem.length; i++){
   anchor = listItem[i].getElementsByTagName("a")[0];
   listAnchorVal= anchor.textContent || anchor.innerText;
}
</code>```

My React code below

```<code>const listItems = React.createRef();

const handleKeyUp = () => {
     console.log(listItems.current.value) :(
};

return (
    <div>
        <input type="text" className="list-filter-input" onKeyUp={handleKeyUp} placeholder="Search names...." />
         <span style={{position:"absolute", right:"925px", marginTop:"1.5%"}}><i className="fa fa-fw fa-search"></i></span>
            <ul className="list-filter-ul" ref={listItems}>
                <li><a href="#">Deepak</a></li>
                <li><a href="#">Mytidbit</a></li>
                <li><a href="#">Hello</a></li>
                <li><a href="#">World</a></li>
                <li><a href="#">Chris</a></li>
                <li><a href="#">Bestie</a></li>
                <li><a href="#">Sugar</a></li>
            </ul>
    </div>
</code>```

This is a list filter i'm trying to implement.

onKeyUp on input, I wish to do the below. Do you think using state to have li values to achieve this filter is unavoidable? I'm thinking of other possibilities than using a state.

```<code>     onKeyUp(e){
      listItemValues.filter(val=>{
return val.toLowerCase().includes(e.target.value.toLowerCase()))
 }
}
</code>```

答:
A key concept when using React or Vue or similar framework is that your UI should always be a representation of your data; your UI doesn't store any extra information. In your case, you can pull out the names into an array:</p>

```<code>// The value in the input is state, it needs to be stored as it changes.
const [searchValue, setSearchValue] = useState("");

// The names to render are data, they are stored in a plain old array.
const names = [
    "Deepak",
    "Mytidbit",
    "Hello",
    "World",
    "Chris",
    "Bestie",
    "Sugar",
];

// The filtered list is derivable from state + data, it doesn't need
// to be stored separately
const filteredNames = names.filter(val =>
    val.toLowerCase().includes(searchValue.toLowerCase())
);

const handleKeyUp = (event) => {
    setSearchValue(event.target.value);
};

return (
    <div>
        <input type="text" className="list-filter-input" onKeyUp={handleKeyUp} placeholder="Search names...." value={searchValue} />
         <span style={{position:"absolute", right:"925px", marginTop:"1.5%"}}><i className="fa fa-fw fa-search"></i></span>
            <ul className="list-filter-ul">
                {filteredNames.map(name => (
                    <li key={name}><a href="#">{name}</a></li>
                ))}
            </ul>
    </div>
);
</code>```

Title: Can we get all <li> values using React ref on its <ul> parent?

Body:
Can we get all li values by using React Refs on its UL parent? like forward refs or  children kind of???

I'm expecting to do the below using React Ref.

let listItem = getElementsByTagName('li');

let anchor;

let listAnchorVal;

for(let i = 0; i < listItem.length; i++){
   anchor = listItem[i].getElementsByTagName("a")[0];
   listAnchorVal= anchor.textContent || anchor.innerText;
}

My React code below

const listItems = React.createRef();

const handleKeyUp = () => {
     console.log(listItems.current.value) :(
};

return (

        <input type="text" className="list-filter-input" onKeyUp={handleKeyUp} placeholder="Search names...." />

Deepak

Mytidbit

Hello

World

Chris

Bestie

Sugar

This is a list filter i'm trying to implement.

onKeyUp on input, I wish to do the below. Do you think using state to have li values to achieve this filter is unavoidable? I'm thinking of other possibilities than using a state.

     onKeyUp(e){
      listItemValues.filter(val=>{
return val.toLowerCase().includes(e.target.value.toLowerCase()))
 }
}

Body:
A key concept when using React or Vue or similar framework is that your UI should always be a representation of your data; your UI doesn't store any extra information. In your case, you can pull out the names into an array:

// The value in the input is state, it needs to be stored as it changes.
const [searchValue, setSearchValue] = useState("");

// The names to render are data, they are stored in a plain old array.
const names = [
    "Deepak",
    "Mytidbit",
    "Hello",
    "World",
    "Chris",
    "Bestie",
    "Sugar",
];

// The filtered list is derivable from state + data, it doesn't need
// to be stored separately
const filteredNames = names.filter(val =>
    val.toLowerCase().includes(searchValue.toLowerCase())
);

const handleKeyUp = (event) => {
    setSearchValue(event.target.value);
};

return (
    <div>
        <input type="text" className="list-filter-input" onKeyUp={handleKeyUp} placeholder="Search names...." value={searchValue} />
         <span style={{position:"absolute", right:"925px", marginTop:"1.5%"}}><i className="fa fa-fw fa-search"></i></span>
            <ul className="list-filter-ul">
                {filteredNames.map(name => (
                    <li key={name}><a href="#">{name}</a></li>
                ))}
            </ul>
    </div>
);


问:
BeautifulSoup not scraping anything from webpage
I am working on a web scraping project. In this project, I am trying to scrape all the product links on a particular page in amazon. this process will repeat as many times as required and scrape multiple pages from amazon.

Here is my code so far

```<code>def scrape_pages(headers, product, num_of_pages):

    product_links = []

    for page in range(1, num_of_pages+1):

        url = f'https://www.amazon.com/s?k={product}&page={page}&ref=nb_sb_noss'
        print(url)

        response = requests.get(url, headers=headers)
        soup = BeautifulSoup(response.content, features="lxml")
        data = soup.findAll('h2', attrs={'class':'a-size-mini'})

        for i in data:
            links = i.findAll('a')

            for a in links:
                product_links.append(f"https://www.amazon.com{a['href']}")
        print('TOTAL NUMBER OF PRODUCTS LINKS SCRAPPED: ', len(product_links))

    return product_links
</code>```

In the above code, I am trying to scrape links inside all h2 tags in a page. I am using user-agent to make the scraping possible.

My problem is this code does not run all the time. Some times it scrapes some of the links and some times it does not scrape any links.

Each page in amazon has around 48 products listed. If I were to scrape 5 pages then the product_links list should hold somewhere around 240 links in it. but I have done multiple tests and it is always less than 200 and sometimes it is 0.

I want to know what I am doing wrong

FYI this is the user-agent I am using

```<code>{'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/81.0.4044.138 Safari/537.36'}
</code>```

答:
I had same problem with before. You can use selenium with BeautifulSoup.

scroll the page up to end using selenium and after that you can use BeautifulSoup part to get whole source of the page. I tried it with google play. I can get the data as I expected.

Body:
I am working on a web scraping project. In this project, I am trying to scrape all the product links on a particular page in amazon. this process will repeat as many times as required and scrape multiple pages from amazon.

Here is my code so far

def scrape_pages(headers, product, num_of_pages):

    product_links = []

    for page in range(1, num_of_pages+1):

        url = f'https://www.amazon.com/s?k={product}&page={page}&ref=nb_sb_noss'
        print(url)

        response = requests.get(url, headers=headers)
        soup = BeautifulSoup(response.content, features="lxml")
        data = soup.findAll('h2', attrs={'class':'a-size-mini'})

        for i in data:
            links = i.findAll('a')

            for a in links:
                product_links.append(f"https://www.amazon.com{a['href']}")
        print('TOTAL NUMBER OF PRODUCTS LINKS SCRAPPED: ', len(product_links))

    return product_links

In the above code, I am trying to scrape links inside all h2 tags in a page. I am using user-agent to make the scraping possible.

My problem is this code does not run all the time. Some times it scrapes some of the links and some times it does not scrape any links.

Each page in amazon has around 48 products listed. If I were to scrape 5 pages then the product_links list should hold somewhere around 240 links in it. but I have done multiple tests and it is always less than 200 and sometimes it is 0.

I want to know what I am doing wrong

FYI this is the user-agent I am using

{'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/81.0.4044.138 Safari/537.36'}


问:
Is it possible to access and read localstorage for an electron application
I have built an electron app that allows the user to move elements such as divs around the screen, and saves their locations in localstorage as a class. This is so when the page reloads or is reopened after a session, the changes made persist. I can't get electron to access the local storage though, even on a page change, so I was wondering if there is anyway to make electron go and grab the localstorage classes, or if I can make the page itself do it. </p>

答:
You gets the entire localStorage and use it as you would do it in a browser.
The localStorage variable now is an object with key-values.

mainWindow.webContents
  .executeJavaScript('({...localStorage});', true)
  .then(localStorage => {
    console.log(localStorage);
  });
```


问:
PHP Sudo permissions only works for 'ALL' commands when using exec()
I need my PHP code to run scripts as a different user with exec(), and so in the sudoers file I added: www-data ALL=(csgo) NOPASSWD: WWW_COMMANDS where WWW_COMMANDS is an alias list of the scripts i need to run. While this works fine when I use su -s /bin/bash www-data to log in as php and test if it works through ssh, when I try to actually send the command on my site with exec("sudo -u csgo sh /path/to/script.sh") and print the output it tells me sudo: no tty present and no askpass program specified and the script will not have run. I also added Defaults:www-data !requiretty to my sudoers file to no effect. The only way I can get it to work when running the exec() on my page is to set www-data ALL=(csgo) NOPASSWD: ALL, which obviously isn't a great solution. Anyone know why this is happening / how to fix it.

答: I didn't even know a script would run without a . or a sh. meuh's comment worked, removing the sh before the command fixed the issue.</p>


问:
Mongo error "out of bounds" for lng 180, lat 68.9636
Getting the following error on MongoDB:

```<code>error MongoError: longitude/latitude is out of bounds, lng: 180 lat: 68.9636
...
operationTime: Timestamp { _bsontype: 'Timestamp', low_: 1, high_: 1590391393 },
ok: 0,
errmsg: 'longitude/latitude is out of bounds, lng: 180 lat: 68.9636',
code: 2,
codeName: 'BadValue',
'$clusterTime': {
  clusterTime: Timestamp { _bsontype: 'Timestamp', low_: 1, high_: 1590391393 },
  signature: { hash: [Binary], keyId: 0 }
},
name: 'MongoError',
[Symbol(mongoErrorContextSymbol)]: {}
</code>```

However, the bounds should be valid:

If specifying latitude and longitude coordinates, list the longitude
  first and then latitude:

Valid longitude values are between -180 and 180, both inclusive. Valid
  latitude values are between -90 and 90, both inclusive.

https://docs.mongodb.com/manual/reference/geojson/

For reference, my query is

```<code>Profiles.find(
  {
    'features.geometry': {
      $geoIntersects: {
        $geometry: geometry
      }
    }
  }
).fetch()
</code>```

(using Meteor)

The geometry can even be displayed:
https://gist.github.com/oleg131/19b17e25670d6a54a176a5c670fd9ce5

Has anyone seen this error for seemingly valid coordinates?

答: Turns out some features had longitude slightly higher than 180, which was rounded off to 180 when displayed in the error traceback.

Body:
Getting the following error on MongoDB:

error MongoError: longitude/latitude is out of bounds, lng: 180 lat: 68.9636
...
operationTime: Timestamp { _bsontype: 'Timestamp', low_: 1, high_: 1590391393 },
ok: 0,
errmsg: 'longitude/latitude is out of bounds, lng: 180 lat: 68.9636',
code: 2,
codeName: 'BadValue',
'$clusterTime': {
  clusterTime: Timestamp { _bsontype: 'Timestamp', low_: 1, high_: 1590391393 },
  signature: { hash: [Binary], keyId: 0 }
},
name: 'MongoError',
[Symbol(mongoErrorContextSymbol)]: {}

However, the bounds should be valid:

If specifying latitude and longitude coordinates, list the longitude
  first and then latitude:

Valid longitude values are between -180 and 180, both inclusive. Valid
  latitude values are between -90 and 90, both inclusive.

https://docs.mongodb.com/manual/reference/geojson/

For reference, my query is

Profiles.find(
  {
    'features.geometry': {
      $geoIntersects: {
        $geometry: geometry
      }
    }
  }
).fetch()

(using Meteor)

The geometry can even be displayed:
https://gist.github.com/oleg131/19b17e25670d6a54a176a5c670fd9ce5

Has anyone seen this error for seemingly valid coordinates?


问:
How to fetch a parameter value from parsed String (Json Request)
I have json request which I have parsed as a String and I need to fetch a param value of "sitename" that is "SIT-SITE-2219" from the long json request using Java.Please help .

"siteCounty":"UC",
         "alocCounty":"test2",
         "alocLat":"39.98",
         "siteName":"SIT-SITE-2219",
         "requestedBy":"UnitTester",
         "msc":"test",
```

答:
Use gson
YourClass yourClass = new Gson().fromJson("siteCounty":"UC",
         "alocCounty":"test2",
         "alocLat":"39.98",
         "siteName":"SIT-SITE-2219",
         "requestedBy":"UnitTester",
         "msc":"test", YourClass.class);

yourClass.getSiteName();