hypothesis for multiple string match

Home Forums OpenEars hypothesis for multiple string match

Viewing 8 posts - 1 through 8 (of 8 total)

  • Author
    Posts
  • #1019788
    davestrand
    Participant

    Hello again. First off, I admire your work ethic Halle. I don’t know what your hours of operation are but it would seem you never sleep.

    So, I’ve been working on this one problem for a couple days now and I seem to have hit a wall. If you could point me in the right direction, or even give me a hint, I think I could make it work. It’s probably more of a stackOverflow kind of question but I thought I’d ask here in case OpenEars had some specific method for it.

    Using a pair of words spoken, I would like to identify keyword matches and respond accordingly.

    So, for example someone says “DRINK BEER” that would be different than “SMASH BEER”. A beer happens to be available. Let’s call the appropriate method for the keyword match. I am utilizing a series of property list dictionaries, and attempting to use the dictionary’s key to identify the spoken word. Then taking the valueForKey to launch into a BEER function (I’m about to launch into my own BEER function). I am not opposed to switching the dictionaries to arrays, if that would be better programatically.

    The problem seems to be when I try to use something like rangeOfString with hypothesis and my dictionary, it’s having issues. I assume because of my inexperience in extracting Keys from dictionaries? Is there an easier way to ID when two specific words are uttered using the hypothesis and a plist? AllKeys?

    Using something like the code below, I can get close. It will work with two specific strings, but once I try to tie in my dictionary in different ways as a string it starts crashing on me.

    if ([hypothesis rangeOfString:@"DRINK"].location == NSNotFound && [hypothesis rangeOfString:@"BEER"].location == NSNotFound) { //if the words uttered contain drink and beer is equal to notFound.
            
            NSLog(@"You didn't say what we thought you would..  let's stop here."); 
            
        } else { 
            
            NSLog(@"Ah, you drink the beer. It is cold and refreshing."); 
      
        }
    

    I also seem to be okay when using single words, using valueForKey:hypothesis, maybe something along those lines? IDK. Again, now that I write it out, I’m starting to realize this isn’t exactly an OpenEars question, it’s more of a plist question, so I apologize.

    #1019789
    Halle Winkler
    Politepix

    Hi Dave,

    Thank you. Basically, I make a best-effort attempt to answer right as questions come in (if it’s feasible and wouldn’t be rude to someone I was with) so I never have a backlog, which lets me keep the support side pretty well under control. So I’d rather take :10 to answer a question in a laid-back way on a Saturday than start a Monday with a backlog that becomes its own time-management task. I usually find that if I can’t handle that approach because a lot more questions than usual are coming in, that indicates that something important is missing from the docs or tutorial.

    I think I can help you with your question since I do a lot of text munging and matching in OpenEars. Your approach sounds fine to me so I suspect an issue in your plist/dictionary code, can you show some?

    BTW, are you acquainted with the [NSString componentsSeparatedByString] method that returns an NSArray? I use it a lot to work with multiple substrings in combination with fast enumeration. rangeOfString is also fine and I frequently use it, but for what you’re doing you might like to have all the hypotheses dumped right into an ordered array for processing.

    Enjoy your BEER function!

    #1019793
    davestrand
    Participant

    Thanks! My code is a mess right now, I’ll put together my best effort and then post back. I am learning about componentSeparatedByString now. I was not familiar with that, thanks!

    #1019794
    davestrand
    Participant

    Okee dokes, hello again. My beer function helped me sleep on it, but I’m still missing something. Here’s some of my code I’m working on.

      objectsInRoom = [playerIsNowAt objectForKey:@"ObjectsInLocation"]; //Bringing objects based on location
    
    NSLog(@"Here are objects in room - %@", objectsInRoom); //logged below
    
        //Failed experiments
        //NSArray *objectWords = [objectsInRoom allKeys];
        //NSString *objectString = [NSString stringWithFormat:@"%@",objectWords];
        //NSArray *spokenWords = [hypothesis componentsSeparatedByString:@" "];
        //NSString *spokenString = [NSString stringWithFormat:@"%@",spokenWords];
       //if([hypothesis isEqualToString:@"BEER"]) { //only works if they just say BEER 
        
        
        if ([hypothesis rangeOfString:@"BEER"].location != NSNotFound){ // ok but how do i make it search thru allkeys for my dictionary??  maybe the next room has WINE or MIMOSA.
            
            NSLog(@"HOPE KEPT ALIVE");
            
        }

    THE LOG :
    Here are objects in room – {
    BEER = Beer;
    PEANUTS = Peanuts;
    READ = Menu;
    }

    So, as you see I can seem to pull single words in using Range, but am stuck on returning a value based on the dictionary.

    Other related code.. in .h
    @property (copy, nonatomic) NSDictionary *objectsInRoom;

    in .m
    @synthesize objectsInRoom; //hm, I think i’m supposed to not synthesize these days and use that underscore thingy?

    I’ve only been coding for a few months, so understanding is appreciated.

    #1019798
    Halle Winkler
    Politepix

    OK, this is how you can use fast enumeration (enumeration means looping through the objects in some container) to search for a match against all your keys:

    NSArray *keyArray = [objectsInRoom allKeys];
    
    for (NSString *key in keyArray) { 
       if([hypothesis rangeOfString:key].location != NSNotFound) {
            NSLog(@"I found a match in the hypothesis for the key %@ so I'm doing the action for that key and breaking.", key);
          if([key isEqualToString:@"BEER"]) {
             NSLog(@"I found BEER");
             [self doBeerThing];
          } else if([key isEqualToString:@"HAMBURGER"]) {
             NSLog(@"I found HAMBURGER");
             [self doHamburgerThing];
          } else {
             NSLog(@"I don't have an action for the hypothesis that I found.");
          }
    
          break; // Stop enumerating once we've found something from the keys.
       }
    // Next loop will begin if we get here and there are more keys to check
    }
    

    There are a few different ways this could be organized for efficiency/clarity. For instance you could skip the first general check for any match and go directly to checking for the specific matches you have in mind, and there are a few different ways you can manage the actual “calling a method having found a specific key” part which I haven’t addressed, but this is a simple and fast approach.

    #1019801
    davestrand
    Participant

    Sweet nectar of the Gods! Thank you so much, that totally makes sense now.

    I was kind of close with a couple attempts yesterday, I forgot to BREAK out of the For loop. :)

    #1019804
    davestrand
    Participant

    I ultimately modified your solution to be more generic using some ideas here.

    Thanks again, if you take tips email me a paypal address. You helped me out a bunch with this.

    #1019805
    Halle Winkler
    Politepix

    Super, I think that is a very good way to learn — get some basic pointers and then start iterating it so it fits your requirements until you get a sense of familiarity with the pattern or process.

Viewing 8 posts - 1 through 8 (of 8 total)
  • You must be logged in to reply to this topic.