#!/usr/bin/env python
# coding: utf-8
import datetime

import nltk
from operator import add
from pprint import pprint
from random import random, uniform

import rospy
from std_msgs.msg import String




import os
import csv
#nltk.download('punkt')


object_ = ['chip', 'senbei', 'pringles', 'peanut', 'candy', 'chewing gum', 'cup star', 'curry', 'fries', 'jelly', 'noodle', 'paprika', 'melon', 'sushi', 'flake', 'bread', 'corn', 'onion', 'radish', 'tea', 'beer', 'coke', 'sake', 'aquarius', 'cold brew', 'green tea', 'soap', 'cloth', 'sponge', 'bowl', 'mug', 'glass', 'tray', 'plate', 'box', 'bag', 'soup container', 'apple', 'orange', 'asience', 'hair spray', 'moisturizer', 'shampoo', 'chopstick', 'fork', 'spoon', 'chair', 'plant', 'book', 'umbrella', 'basket', 'blanket', 'pillow', 'cushion', 'toy', 'rug', 'chiar', 'pastel', 'pencil', 'clock', 'tintintin', 'lamp', 'ball', 'hook', 'pen', 'egg', 'jar', 'tomato', 'eggplant', 'chili', 'shaker', 'teaspoon', 'knife', 'sink', 'detergent', 'stove', 'dishwasher', 'pepper', 'salt', 'pasta', 'spatula', 'ornament', 'scale', 'microwave', 'portrait', 'frame', 'window', 'bottle']

object_plural = ['chips', 'senbeis', 'peanuts', 'candies', 'chewing gums', 'cup stars', 'curries', 'jellies', 'noodles', 'paprikas', 'melons', 'sushies', 'flakes', 'corns', 'onions', 'radishes', 'green tea', 'soaps', 'clothes', 'sponges', 'bowls', 'mugs', 'glasses', 'trays', 'plates', 'boxes', 'bags', 'soup containers', 'apples', 'oranges', 'asiences', 'hair sprays', 'moisturizers', 'shampoos', 'chopsticks', 'forks', 'spoons', 'chairs', 'plants', 'books', 'umbrellas', 'baskets', 'blankets', 'pilows', 'cushions', 'toys', 'rugs', 'chiars', 'pastels', 'pencils', 'clocks', 'tintintins', 'lamps', 'balls', 'hooks', 'pens', 'eggs', 'jars', 'tomatoes', 'eggplants', 'chilis', 'shakers', 'teaspoons', 'knifes', 'sinks', 'detergents', 'stoves', 'dishwashers', 'peppers', 'salts', 'pastas', 'spatulas', 'ornaments', 'scales', 'microwaves', 'portraits', 'frames', 'windows', 'clothes hanger', 'toy hanger', 'bottles']

category = ['snack', 'food', 'drink', 'toiletry', 'container', 'fruit', 'cleaning stuff', 'cutlery', 'none']

category_plural = ['snacks', 'foods', 'drinks', 'toiletries', 'containers', 'fruits', 'cleaning stuffs', 'cutleries']

room = ['bedroom', 'living room', 'office', 'kitchen', 'corridor', 'bathroom', 'entrance', 'balcony']

location = ['none', 'bed', 'bedside', 'tv stand', 'shelf', 'sideshelf', 'cabinet', 'living table', 'dining table', 'desk', 'bar', 'fridge',  'teepee', 'right rack', 'left rack', 'sofa', 'bistro table', 'door', 'sideboard', 'left plank', 'right plank', 'kitchen table', 'kitchen shelf', 'kitchen rack', 'entrance shelf', 'balcony shelf', 'kitchen counter', 'little desk', 'bookcase', 'tv', 'hanger']

location_plural = ['beds', 'bedsides', 'tv stands', 'shelves', 'sideshelves', 'cabinets', 'living tables', 'dining tables', 'desks', 'bars', 'fridges',  'teepees', 'racks', 'sofas', 'bistro tables', 'doors', 'sideboards', 'planks']

shape = ['cuboid', 'cylinder', 'cone', 'sphere', 'hexagon', 'triangle']

size = ['small', 'medium', 'large', 'biggest', 'smallest', 'largest', 'smaller', 'larger', 'bigger']

weight = ['light', 'medium', 'heavy', 'heaviest', 'lightest', 'heavier', 'lighter']

quantity = ['nan', 'inf', '1', '2', '3', '4', '5', '6', '7', '8', '9', '10']

color = ['black', 'white', 'red', 'orange', 'yellow', 'green', 'blue', 'purple', 'transparency', 'brown', 'grey', 'pink']

gesture = ['lying', 'sitting', 'standing', 'pointing left', 'pointing right', 'rising left arm', 'rising right arm']

gender_values = ['man', 'woman']

gender = ['man', 'woman', 'male', 'female', 'boy', 'girl']

gender_plural = ['men', 'women',  'males', 'females', 'boys', 'girls']

age = ['child', 'adult', 'elder', 'old']

age_plural = ['children', 'adults', 'elders', 'olds']

plural_words = object_plural + category_plural + location_plural + gender_plural + age_plural

operator = ['i']

city = ['nagoya']

year = ['2017']

keywords = ['where', 'room', 'category', 'belong', 'where', 'find', 'what', 'objects', 'color', 'colour',
'smaller', 'bigger', 'lighter', 'heavier', 'how', 'many', 'size', 'number', 'crowd', 'people',
'time', 'today', 'last', 'computer', 'bug', 'compiler', 'B', 'C', 'who', 'when', 'highest', 'capital',
'people', 'Japan', 'flag', 'Sakura', 'emperor', 'RoboCup', 'city', 'year', 'open', 'social standard',
'domestic standard', 'dreams', 'name', 'team']

homophones = {
    'write': 'right',
    'sighs': 'size',
    'ear': 'year',
    'serial': 'cereal',
    'blew': 'blue',
    'read': 'red',
    'thyme': 'time',
    'wee': 'we',
    'mince': 'mints',
    'tee': 'tea',
    'bier': 'beer',
    'plait': 'plate',
    'bee': 'b',
    'cheep': 'chip',
    'robocop': 'robocup',
    'spear': 'sphere',
    'eye': 'i',
    'bad': 'bed',
    'tp': 'teepee',
    'france': 'plank',
    'tpr': 'teepee',
	'thanks': 'planks',
	'ppr': 'teepee' }



locations = [{'location': 'door', 'room': 'living room'},
               {'location': 'door', 'room': 'living room'},
               {'location': 'living table', 'room': 'living room'},
               {'location': 'shelf', 'room': 'living room'},
               {'location': 'door', 'room': 'bedroom'},
               {'location': 'desk', 'room': 'bedroom'},
               {'location': 'bed', 'room': 'bedroom'},
               {'location': 'door', 'room': 'kitchen'},
               {'location': 'sink', 'room': 'kitchen'},
               {'location': 'sideshelf', 'room': 'kitchen'},
               {'location': 'shelf', 'room': 'kitchen'},
               {'location': 'dining table', 'room': 'kitchen'},
               {'location': 'fridge', 'room': 'kitchen'}]

objects = [{'category': 'toiletry',
              'color': 'red',
              'location': 'living table',
              'object': 'shampoo',
              'quantity': 2,
              'room': 'living room',
              'shape': 'cylinder',
              'size': 'medium',
              'weight': 'medium'},
             {'category': 'food',
              'color': 'orange',
              'location': 'living table',
              'object': 'noodle',
              'quantity': 1,
              'room': 'living room',
              'shape': 'cylinder',
              'size': 'medium',
              'weight': 'light'},
             {'category': 'candy',
              'color': 'green',
              'location': 'living table',
              'object': 'chocolate egg',
              'quantity': 1,
              'room': 'living room',
              'shape': 'sphere',
              'size': 'small',
              'weight': 'light'},
             {'category': 'candy',
              'color': 'orange',
              'location': 'living table',
              'object': 'chocolate egg',
              'quantity': 1,
              'room': 'living room',
              'shape': 'sphere',
              'size': 'small',
              'weight': 'light'},
             {'category': 'snack',
              'color': 'red',
              'location': 'shelf',
              'object': 'chip',
              'quantity': 1,
              'room': 'living room',
              'shape': 'cuboid',
              'size': 'medium',
              'weight': 'light'},
             {'category': 'snack',
              'color': 'green',
              'location': 'shelf',
              'object': 'chip',
              'quantity': 1,
              'room': 'living room',
              'shape': 'cuboid',
              'size': 'large',
              'weight': 'medium'},
             {'category': 'candy',
              'color': 'black',
              'location': 'desk',
              'object': 'chocolate bar',
              'quantity': 2,
              'room': 'bedroom',
              'shape': 'cuboid',
              'size': 'medium',
              'weight': 'medium'},
             {'category': 'container',
              'color': 'blue',
              'location': 'bed',
              'object': 'box',
              'quantity': 1,
              'room': 'bedroom',
              'shape': 'cuboid',
              'size': 'large',
              'weight': 'medium'}]



spr_examples1 = [
    # Computer
    'where does the term computer bug come from',
    'who invented the c programming language',
    'when was invented the c programming language',
    'when was invented the b programming language',
    'who invented the first compiler',
    # Japan
    'what is the highest point in japan',
    'what city is the capital of the japan',
    'how many people live in the japan',
    'what are the colours of the japanese flag',
    'what is a sakura',
    'who is the emperor of japan',
    # Robocup
    'in which city will next year\'s robocup be hosted',
    'in which year was robocup@home founded',
    'which robot is used in the open platform league',
    'which robot is used in the social standard platform league',
    'which robot is used in the domestic standard platform league',
    # Nonsense
    'do you have dreams',
    # Team
    'what is your name',
    'what is your team\'s name',
    'what\s the name of your team',
    # Additional function required
    'what time is it',
    'what day is today',
    'what was the last question',
]

spr_examples2 = [
    # Arena
    'where is located the sink',
    'where is the shelf',
    'in which room is the fridge', #placement, beacon ?
    'how many shelves are in the living room',
    'how many doors has the bedroom',
    'how many chairs are in the dining room',
    # Object
    'to which category belong the chips',
    'how many drinks there are',
    'where can I find a chips',
    'what objects are stored in the bed',
    'what objects are stored in the dining table',
    'what objects are in the shelf',
    'what\'s the colour of the bread',
    'what\'s the color of the orange',
    'between the plate and coke, which one is smaller',
    'between the noodles and chips, which one is heavier',
    'between the chocolate bar and cloth, which one is lighter',
    'how many food are in the dining table',
    'which is the lightest drinks',
    'which is the heaviest food',
    'which is the biggest candies',
    'what\'s the smallest food',
    # Crowd
    'how many people in the crowd are rising right arm',
    'how many people in the crowd are standing or sitting',
    'tell me the number of males in the crowd',
    'tell me the number of women in the crowd',
    'how many females are in the crowd',
    'how many children are in the crowd',
    'how many adults are in the crowd',
    'how many elders are in the crowd',
    'tell me the number of elders in the crowd',
    'tell me how many people were wearing blue',
    'was the standing person boy or girl',
    'was the standing person man or woman',
    'tell me if the standing person was a boy',
    'how old do you think i am',
    'am i a man or a woman'
]

spr_examples3=[
'Where can I find a orange?',
'What\'s the colour of the orange?',
'How many oranges are in the kitchen?',
'To which category belong the orange?',
'Do the apple and orange belong to the same category?',
'Between the apple and orange, which one is lighter?'


]

spr_examples4 = [
#1. Arena
'where is the cup star',
'where does a candy locate',
'in which room is the rack',
'in which room does the little desk belong to',
'how many doors are in the bedroom',
'how many forks are in the kitchen',
'how many shampoos are in the balcony',
#2. Object
'what is the smallest food',
'Which is the smallest object',
'what is the largest fruit',
'what is the lightest drink',
'what is the heaviest cutlery',
'to which category do forks belong to',
'to which category belong the peanuts',
'do the apple and orange belong to the same category',
'where can I find some onion',   #NOT
'where can I find a shampoo',
'where can I find a red hair spray',
'what is the color of the soup container',
'what is the color of the apple',
'what is the color of an apple',
'what is the shape of jellies',
'what is the shape of the candy',
'what does a chewing gum look like',
'what objects are stored in the rack',
'what is in the teepee',
'what can I find on the sofa',
'between bread and corn, which one is lighter',
'asience and moisturizer, which one is heavier',
'which one is bigger, fork and spoon',
'How many drinks are there',
'How many objects are in the sideboard',
'How many drinks are on the kitchen counter',
'How many chopsticks are in the left plank'
]

spr_examples_pr = [
'Who invented the C programming language?',
'When was invented the C programming language?',
'When was invented the B programming language?',
'Where does the term computer bug come from?',
'Who invented the first compiler',
'Which robot is used in the Open Platform League',
'Which robot is used in the Domestic Standard Platform League',
'Which robot is used in the Social Standard Platform League',
'How many people live in the Japan?',
'What are the colours of the Japanese flag?',
'What city is the capital of the Japan?',
'What is the highest point in Japan',
'What is sakura',
'Who is the emperor of Japan?',
'What\'s the name of your team?',
'What time is it?',
'What day is today?',
'Do you have dreams?',
'In which city will next year\'s RoboCup be hosted?'
]

spr_examples_pr_2018 = [
'Who invented the C programming language?',
'When was the C programming language invented?',
'When was the B programming language invented?',
'Where does the term computer bug come from?',
'Who invented the first compiler',
'Which robot is used in the Open Platform League',
'Which robot is used in the Domestic Standard Platform League',
'Which robot is used in the Social Standard Platform League',
'What\'s the name of your team?',
'What time is it?',
'What day is today?',
'Do you have dreams?',
'In which city will next year\'s RoboCup be hosted?',
'What is the origin of the name Canada?',
'What is the capital of the name Canada?',
'What is the national anthem of Canada?',
]

















ex = [
'Where is located the bed?',
'In which room is the bed',
'How many doors has the bedroom?',
'How many desks are in the living room?'
]

ex2 = [
    'to which category belong the oranges',
    'how many oranges are in the dining table',
    'how many apples are in the dining table',
    'where can I find a oranges'
]

ex3 = [
'how many children are in the crowd',
'how many elders are in the crowd',
'how many boys are in the crowd'

]


attribute_map = {'object': object_, 'category': category, 'room': room, 'location': location, 'shape': shape, 'size': size, 'weight': weight, 'quantity': quantity, 'color': color, 'gesture': gesture, 'gender': gender, 'age': age, 'operator': operator, 'city': city, 'year': year}
all_words_b4_split = (object_ + category + room + location + shape + size + weight + quantity + color + gesture + gender + age + operator + city + year + plural_words + keywords)
all_words_duplicate = []
for i in range(len(all_words_b4_split)): all_words_duplicate = all_words_duplicate + all_words_b4_split[i].split()
all_words = list(set(all_words_duplicate))
singular_words = list(set(all_words) - set(plural_words))


def count(s, tokens, attribute_words, count_multiple_occurences_for_single_attribute_word=False):
    if not count_multiple_occurences_for_single_attribute_word:
        return reduce(add, [int((word in s) if ' ' in word else (word in tokens)) for word in attribute_words])
    else:
        return reduce(add, [s.count(word) if ' ' in word else tokens.count(word) for word in attribute_words])

def to_count_list(d):
    ret = [0] * 12
    if 'object' in d: ret[0] += d['object']
    if 'category' in d: ret[1] += d['category']
    if 'room' in d: ret[2] += d['room']
    if 'location' in d: ret[3] += d['location']
    if 'shape' in d: ret[4] += d['shape']
    if 'size' in d: ret[5] += d['size']
    if 'weight' in d: ret[6] += d['weight']
    if 'color' in d: ret[7] += d['color']
    if 'gesture' in d: ret[8] += d['gesture']
    if 'gender' in d: ret[9] += d['gender']
    if 'age' in d: ret[10] += d['age']
    if 'operator' in d: ret[11] += d['operator']
    return ret


'''
arguments in get(), count_entities(), compare_pair_nominal(), compare_pair_ordinal(), compare_set()

olp: one of objects, locations, or people (all of them are a list of dictionaries)

name_attribute: the name of an attribute of entities
    e.g., 'object'
    # compare_objs_in_weight_given_cat
    # Which is the lightest drinks?
pair_attribute_values: a pair of attribute values of entities
    e.g., ('bowl', 'apple')
    # Do the bowl and apple belong to the same category?

givens: a (nested) list of dictionaries
    # {‘attribute’: ‘an_attribute’, ‘value’: ‘a_value’} of conditions
    # cf. [[a,b], [c, d]] = (a and b) or (c and d) = ab + cd
    # e.g., {‘attribute’: ‘category’, ‘value’: ‘snack’}
    e.g., {'attribute': 'gender', 'value': 'man'}
    e.g., {'attribute': 'object', 'value': 'sink'}
    # [[{'attribute': 'object', 'value': 'sink'}]]

has_qty: True if an element in an array has the quantity attribute
    objects have the quantity attribute
    locations and people do not have the quantity attribute

in_terms: an attribute in terms of which instances are compared
    e.g.,'category', 'size', 'weight'
    # compare_obj1_obj2_in_cat
    # Do the bowl and apple belong to the same category?
'''

def get(olp, name_attribute, givens=None):
    # returns the set of attribute values (no duplicates) of an attribute named name_attribute given givens
    # https://stackoverflow.com/questions/3013449/list-filtering-list-comprehension-vs-lambda-filter
    # givens = [[{'attribute': 'object', 'value': 'pringles'}]]
    # get(objects, 'category', givens)
    if givens is not None:
        given_gesture = (givens[0][0]['attribute'] == 'gesture')
        if not(given_gesture):
            olp_conditioned = [x for x in olp if (givens[0][0]['attribute'] in x) and (x[givens[0][0]['attribute']] == givens[0][0]['value'])]
        else:
            olp_conditioned = [x for x in olp if (givens[0][0]['attribute'] in x) and (givens[0][0]['value'] in x[givens[0][0]['attribute']])]
    else:
        olp_conditioned = olp
    list_entities = [x[name_attribute] for x in olp_conditioned]
    return list(set(list_entities))

def get_random_age(): #JUST RETURN 25 (?)
    age_interval = [10, 20, 30, 40, 50, 60]
    distr = [0.05, 0.4, 0.25, 0.15, 0.1, 0.05]
    default_age = 25
    return default_age

def count_entities(olp, givens, has_qty):
    # returns the number of entities (allowing duplicates) given givens by multiplying the quantities if has_qty is True
    count = 0
    # givens = [
    #     [{'attribute': 'location', 'value': 'shelf'}, {'attribute': 'room', 'value': 'living room'}],
    #     [{'attribute': 'location', 'value': 'fridge'}, {'attribute': 'room', 'value': 'kitchen'}]
    # ]
    # givens = [
    #     [{'attribute': 'ucolor', 'value': 'gray'}, {'attribute': 'gesture', 'value': 'sitting'}],
    #     [{'attribute': 'ucolor', 'value': 'red'}, {'attribute': 'gesture', 'value': 'pointing left'}],
    #     [{'attribute': 'ucolor', 'value': 'red'}]
    # ]
    print(givens)

    found = []

    if givens == None or len(givens) == 0:
        found = olp
    else:
        given_gesture = (givens[0][0]['attribute'] == 'gesture')
        for obj in olp:
            for props in givens: # props to be ORed
                matched = True

                for prop in props: # prop to be ANDed
                    if not(given_gesture) and (prop['attribute'] not in obj or obj[prop['attribute']] != prop['value']):
                        matched = False
                        break
                    elif given_gesture and (prop['attribute'] not in obj or prop['value'] not in obj[prop['attribute']]):
                        matched = False
                        break

                if matched:
                    print(obj)
                    break

            if matched:
                found.append(obj)

    for obj in found:
        if 'quantity' in obj and obj['quantity'] != 'inf':
            count += obj['quantity']
        else:
            count += 1

    print("count_entities will return " + str(count))
    return count

def compare_pair_nominal(olp, pair_attribute_values, in_terms):
    # objects, ('bowl', 'apple'), 'category'
    # objects, ('pringles', 'peanuts'), 'category'
    # objects, ('chocolate bar', 'chocolate egg'), 'category'
    x, y = pair_attribute_values # (bowl, apple)
    x_list = [z for z in olp if z['object'] == x] # TODO: make it general (future)
    y_list = [z for z in olp if z['object'] == y]
    if len(x_list) == 0 or len(y_list) == 0:
        return False
    else:
        if x_list[0][in_terms] == y_list[0][in_terms]:
            return True, x_list[0][in_terms]
        else:
            return False, None
# returns True if they are the same
# or returns False if they are different

def compare_pair_ordinal(olp, pair_attribute_values, in_terms, comparing_word):
    # inputs: objects, ('plate', 'coke'), 'size', 'smaller'
    # returns the list of entities preferable in terms of in_terms given givens

    # comparing_word: 'smaller', 'larger', 'bigger', 'lighter', 'heavier'
    # size: 'small', 'medium', 'large'
    # weight: 'light', 'medium', 'heavy'
    x, y = pair_attribute_values

    x_list = [z for z in olp if z['object'] == x] # TODO: make it general (future)
    if len(x_list) == 0:
        x_list = [z for z in olp if z['object'] == x + 's'] # compare with plural object values

    y_list = [z for z in olp if z['object'] == y]
    if len(y_list) == 0:
        y_list = [z for z in olp if z['object'] == y + 's'] # compare with plural object values

    if len(x_list) == 0 or len(y_list) == 0:
        return [] # no such object, so unknown
    else:
        if in_terms == 'size':
            if x_list[0][in_terms] == 'small':
                x_in_terms = 0
            elif x_list[0][in_terms] == 'medium':
                x_in_terms = 1
            elif x_list[0][in_terms] == 'large':
                x_in_terms = 2
            else:
                print('unexpected size in compare_pair_ordinal for x')
            if y_list[0][in_terms] == 'small':
                y_in_terms = 0
            elif y_list[0][in_terms] == 'medium':
                y_in_terms = 1
            elif y_list[0][in_terms] == 'large':
                y_in_terms = 2
            else:
                print('unexpected size in compare_pair_ordinal for y')
        elif in_terms == 'weight':
            if x_list[0][in_terms] == 'light':
                x_in_terms = 0
            elif x_list[0][in_terms] == 'medium':
                x_in_terms = 1
            elif x_list[0][in_terms] == 'heavy':
                x_in_terms = 2
            else:
                print('unexpected weight in compare_pair_ordinal for x')
            if y_list[0][in_terms] == 'light':
                y_in_terms = 0
            elif y_list[0][in_terms] == 'medium':
                y_in_terms = 1
            elif y_list[0][in_terms] == 'heavy':
                y_in_terms = 2
            else:
                print('unexpected weight in compare_pair_ordinal for y')
        else:
            print('unexpected terms in compare_pair_ordinal')

    if comparing_word == 'smaller' or comparing_word == 'lighter':
        if x_in_terms < y_in_terms:
            return [x]
        elif x_in_terms == y_in_terms:
            return [x, y]
        elif x_in_terms > y_in_terms:
            return [y]
    elif comparing_word == 'larger' or comparing_word == 'bigger' or comparing_word == 'heavier':
        if x_in_terms < y_in_terms:
            return [y]
        elif x_in_terms == y_in_terms:
            return [x, y]
        elif x_in_terms > y_in_terms:
            return [x]
    else:
        print('unexpected comparing word in compare_pair_ordinal')

def give_conditions(olp, givens):
    olp_conditioned = [] # givens to olp_conditioned
    if givens == None or len(givens) == 0:
        olp_conditioned = olp
    else:
        for entity in olp:
            for props in givens: # props to be ORed
                matched = True
                for prop in props: # prop to be ANDed
                    if prop['attribute'] not in entity or entity[prop['attribute']] != prop['value']:
                        matched = False
                        break

                if matched:
                    print(entity)
                    break

            if matched:
                olp_conditioned.append(entity)

    return olp_conditioned

def word2num(olp, in_terms):
    olp_in_terms = [0] * len(olp)
    if in_terms == 'size':
        for i in xrange(len(olp)):
            if olp[i][in_terms] == 'small':
                olp_in_terms[i] = 0
            elif olp[i][in_terms] == 'medium':
                olp_in_terms[i] = 1
            elif olp[i][in_terms] == 'large':
                olp_in_terms[i] = 2
            else:
                print('unexpected size in word2num for olp')
    elif in_terms == 'weight':
        for i in xrange(len(olp)):
            if olp[i][in_terms] == 'light':
                olp_in_terms[i] = 0
            elif olp[i][in_terms] == 'medium':
                olp_in_terms[i] = 1
            elif olp[i][in_terms] == 'heavy':
                olp_in_terms[i] = 2
            else:
                print('unexpected weight in word2num for olp')
    else:
        print('unexpected terms in word2num:', in_terms)

    return olp_in_terms

def list_duplicates(list_num,num):
    #indexes of num in list_num
    start_at = -1
    indices = []
    while True:
        try:
            idx = list_num.index(num,start_at+1)
        except ValueError:
            break
        else:
            indices.append(idx)
            start_at = idx
    return indices

def get_idx_min(list_num):
    #indexes of min value
    if len(list_num) == 0:
        return []

    val = min(list_num)
    list_idx = list_duplicates(list_num = list_num, num = val)
    return list_idx

def get_idx_max(list_num):
    #indexes of max value
    # https://stackoverflow.com/questions/2474015/getting-the-index-of-the-returned-max-or-min-item-using-max-min-on-a-list
    # https://stackoverflow.com/questions/5419204/index-of-duplicates-items-in-a-python-list
    if len(list_num) == 0:
        return []

    val = max(list_num)
    list_idx = list_duplicates(list_num = list_num, num = val)
    return list_idx

def get_idx_opt(list_num, opt):
    if len(list_num) == 0:
        return []

    if opt == 'min':
        return get_idx_min(list_num)
    elif opt == 'max':
        return get_idx_max(list_num)
    else:
        print('unexpected opt:', opt)

def get_set_values_given_name_idx(olp, name_attribute, idx):
    # https://stackoverflow.com/questions/18272160/access-multiple-elements-of-list-knowing-their-index
    print('olp:',  olp)
    print('name_attribute:', name_attribute)
    if len(idx)>0:
        print('olp[0]:',  olp[0])
        print('olp[0][name_attribute]:',  olp[0][name_attribute])

    c = [ olp[i][name_attribute] for i in idx]
    return list(set(c))

def compare_set(olp, name_attribute, in_terms, givens, comparing_word):
    print comparing_word
    # returns the list of entities preferable in terms of in_terms given givens
    # [Procedures]
    # choose entities given givens (givens)
    # change qualitative words to numbers (in_terms)
    # choose entities least or greatest according to comparing_word (comparing_word)
    # return the set of attribute values of those entities
    # (Choose entities given givens)
    olp_conditioned = give_conditions(olp, givens)
    print('olp_conditioned:')
    pprint(olp_conditioned)
    olp_in_terms = word2num(olp_conditioned, in_terms)
    #print(olp_in_terms)
    if comparing_word == 'smallest' or comparing_word == 'lightest':
        idx_opt = get_idx_opt(olp_in_terms, 'min')
    elif comparing_word == 'largest' or comparing_word == 'biggest' or comparing_word == 'heaviest':
        idx_opt = get_idx_opt(olp_in_terms, 'max')
    else:
        print('unexpected comparing word in compare_set')

    print('idx_opt:', idx_opt)
    set_attribute_values = get_set_values_given_name_idx(olp_conditioned, name_attribute, idx_opt)
    print('set_attribute_values:', set_attribute_values)
    return set_attribute_values

def get_givens(s, tokens, attribute):
    mk_dict = lambda x: {'attribute': attribute, 'value': x}
    ret = []
    for x in attribute_map[attribute]:
        if ' ' in x:
            if x in s:
                ret += [mk_dict(x)]
        else:
            if x in tokens:
                ret += [mk_dict(x)]
    return ret

def get_pair_attribute_values(s, tokens, attribute):
    ret = []
    for x in attribute_map[attribute]:
        if ' ' in x:
            if x in s:
                ret += [x]
        else:
            if x in tokens:
                ret += [x]
    return tuple(ret)


def singularize(word):
    if len(word) > 3 and word[-3:] == 'ves': # shelves
        return word[:-3] + 'f'
    elif word == 'children': # children
        return 'child'
    elif len(word) > 3 and (word[-3:] == 'les' or  word[-3:] == 'ges' or  word[-3:] == 'tes' or  word[-3:] == 'des' or  word[-3:] == 'kes'): # pringles, males, sponges, plates, bedsides, flakes
        return word[:-1]
    elif len(word) > 3 and (word[-3:] == 'ies'): # candies, toiletries
        return word[:-3] + 'y'
    elif  len(word) > 2 and word[-2:] == 'en': # men, women
        return word[:-2] + 'an'
    elif len(word) > 2 and word[-2:] == 'es':
        return word[:-2]
    else:
        return word[:-1]

def sing_plurize(word, num):
    # singularize or plurize word or is according to num
    if word == 'is' or word == 'are':
        return sing_plurize_is(num)
    if word == 'person' or word == 'people':
        return sing_plurize_pp(num)
    if (word in singular_words and num > 1):
	for w in plural_words:
	    if singularize(w) == word:
		ret = w
		break
	    ret = word
    elif (word in plural_words and num <= 1):
	ret = singularize(word)
    else:
        ret = word
    return ret+' '

def sing_plurize_is(num):
    if num > 1:
	return 'are '
    else:
	return 'is '

def sing_plurize_pp(num):
    if num > 1:
	return 'people '
    else:
	return 'person '

def nogada(s, olp, question_prev):
    # If-elses for every question type
    for plural_word in plural_words: s = s.replace(plural_word, singularize(plural_word))
    s = s.replace('female', 'woman')
    s = s.replace('male', 'man')
    s = s.replace('girl', 'woman')
    s = s.replace('boy', 'man')
    s = s.replace('dining room', 'kitchen')
    s = s.replace('dining table', 'kitchen table')
    s = s.replace('so far', 'sofa')
    s = s.replace('shooting', 'sitting')
    s = s.replace('searching', 'sitting')
    tokens = nltk.word_tokenize(s)

    # homophones
    keys = homophones.keys()
    while True:
        flag = True
        for key in keys:
            if key in tokens:
                s = s.replace(key, homophones[key])
                tokens = nltk.word_tokenize(s)
                flag = False
                break
        if flag:
            break

    object_for_count = list(object_)
    n_object = count(s, tokens, object_)
    n_category = count(s, tokens, category)
    n_room = count(s, nltk.word_tokenize(s.replace('kitchen counter', 'kitchencounter').replace('kitchen table', 'kitchentable').replace('kitchen rack', 'kitchenrack').replace('kitchen shelf', 'kitchenshelf').replace('entrance shelf', 'entranceshelf').replace('balcony shelf', 'balconyshelf')), room)
    n_location = count(s, nltk.word_tokenize(s.replace('chocolate bar', 'chocolatebar')), location)
    n_shape = count(s, tokens, shape)
    n_size = count(s, tokens, size)
    n_weight = count(s, tokens, weight)
    n_color = count(s, tokens, color)
    n_gesture = count(s, tokens, gesture)
    n_gender = count(s, tokens, gender)
    n_age = count(s, tokens, age)
    n_operator = count(s, tokens, operator)

    count_list = [n_object, n_category, n_room, n_location, n_shape, n_size, n_weight, n_color, n_gesture, n_gender, n_age, n_operator]

    print count_list

    givens = None
    pair_attribute_values = None

    answer_to_be_returned = "I'm sorry. I couldn't understand your intention."

    if 'where' in s or 'room' in s:
        if count_list == to_count_list({'location': 1}):
            # question = 'where is located the sink?'
            givens = [get_givens(s, tokens, 'location')]
            print 'get_room_given_loc'
            rooms_returned = get(
            olp = olp['locations'],
            name_attribute = 'room',
            givens = givens
            )
            print(rooms_returned)
            if rooms_returned:
		answer_to_be_returned = [ 'The ' + givens[0][0]['value'] + ' is in the ' + rooms_returned[0] ]
	    else:
		answer_to_be_returned = ['There is no '+ givens[0][0]['value'] + ' in the ' + rooms_returned[0]]

    if count_list == to_count_list({'room': 1, 'location': 1})  :
        #question = 'how many shelves are in the living room?'
        givens = [get_givens(s, tokens, 'location') + get_givens(s, tokens, 'room')]
        print 'count_loc_given_room'
        num_locations_returned = count_entities(
        olp = olp['locations'],
        givens = givens,
        has_qty = False
        )
        print(num_locations_returned)
        if num_locations_returned:
	    answer_to_be_returned = [ 'There '+sing_plurize_is(num_locations_returned) + str(num_locations_returned) + ' ' + sing_plurize(givens[0][0]['value'],num_locations_returned) + 'in the ' + givens[0][1]['value']  ]
	else:
	    answer_to_be_returned = [ 'There is no ' + givens[0][0]['value'] + ' in the ' + givens[0][1]['value']  ]

    if count_list == to_count_list({'object': 1, 'room': 1}) or (count_list == to_count_list({'object': 1, 'room': 1, 'color': 1}) and 'orange' in s)  :
        # 'how many chairs are in the dining room?'
        givens = [get_givens(s, tokens, 'object') + get_givens(s, tokens, 'room')]
        print 'count_obj_given_room'
        num_objects_returned = count_entities(
        olp = olp['objects'],
        givens = givens,
        has_qty = True
        )
        print(num_objects_returned)
        if num_objects_returned:
	    answer_to_be_returned = [ 'There '+sing_plurize_is(num_objects_returned) + str(num_objects_returned) +' '+  sing_plurize(givens[0][0]['value'],num_objects_returned) + 'in the ' + givens[0][1]['value']]
	else:
	    answer_to_be_returned = [ 'There is no ' +  givens[0][0]['value'] + ' in the ' + givens[0][1]['value']]

    if count_list == to_count_list({'object': 1, 'location': 1})or ( count_list == to_count_list({'object': 1, 'location': 1, 'color': 1}) and 'orange' in s ):
        # 'how many chairs are in the dining table?'
        givens = [get_givens(s, tokens, 'object') + get_givens(s, tokens, 'location')]
        print 'count_obj_given_loc'
        num_objects_returned = count_entities(
        olp = olp['objects'],
        givens = givens,
        has_qty = True
        )
        print(num_objects_returned)
        if num_objects_returned:
	    answer_to_be_returned = ['There '+sing_plurize_is(num_objects_returned) + str(num_objects_returned) + ' ' + sing_plurize(givens[0][0]['value'],num_objects_returned) +' in the ' + givens[0][1]['value']]

	else:
	    answer_to_be_returned = ['There is no ' + givens[0][0]['value'] +' in the ' + givens[0][1]['value']]


    if 'category' in s or 'belong' in s:
        if count_list == to_count_list({'object': 1})or ( count_list == to_count_list({'object': 1, 'color': 1}) and 'orange' in s) :
            #question = 'to which category belong the chips?'
            givens = [get_givens(s, tokens, 'object')]
            print 'get_cat_given_obj'
            categories_returned = get(
            olp = olp['objects'],
            name_attribute = 'category',
            givens = givens
            )
            print(categories_returned)
            if categories_returned:
		answer_to_be_returned = [ 'The ' + givens[0][0]['value'] + ' belongs to '+ categories_returned[0] ]
	    else:
		answer_to_be_returned = ['There is no such object']

        if count_list == to_count_list({'object': 2}) or ( count_list == to_count_list({'object': 2, 'color': 1}) and 'orange' in s)    :
            #question = 'do the bowl and apple belong to the same category?'
            givens = [get_givens(s, tokens, 'category')]
            pair_attribute_values = get_pair_attribute_values(s, tokens, 'object')
            print 'compare_obj1_obj2_in_cat'
            equality_returned, category_returned = compare_pair_nominal(
            olp = olp['objects'],
            pair_attribute_values = pair_attribute_values,
            in_terms = 'category'
            )
            print(equality_returned)
            if equality_returned:
		answer_to_be_returned = ['Yes, they both belong to ' + category_returned]
	    else:
		answer_to_be_returned = ['They do not belong to the same category.']

    if 'shape' in s and count_list == to_count_list({'object': 1}):
	# Not used
        givens = [get_givens(s, tokens, 'object')]
        print 'get_shape_given_obj'
        categories_returned = get(
        olp = olp['objects'],
        name_attribute = 'shape',
        givens = givens
        )
        print(categories_returned)
        answer_to_be_returned = categories_returned

    if count_list == to_count_list({'category': 1}):
        #'how many drinks there are?'
        givens = [get_givens(s, tokens, 'object') + get_givens(s, tokens, 'category')]
        print 'count_obj_given_cat'
        num_objects_returned = count_entities(
        olp = olp['objects'],
        givens = givens,
        has_qty = True
        )
        print(num_objects_returned)
        if num_objects_returned:
	    answer_to_be_returned = ['There '+sing_plurize_is(num_objects_returned) + str(num_objects_returned) + ' ' + sing_plurize(givens[0][0]['value'],num_objects_returned)]
	else:
	    answer_to_be_returned = ['There is no '+givens[0][0]['value']]
####LALA
    if 'where' in s or 'find' in s:
        if count_list == to_count_list({'object': 1}) or count_list == to_count_list({'object': 1, 'operator': 1}) or count_list == to_count_list({'object': 1, 'operator': 1, 'color': 1}):
            #question = 'where can I find a chips?'
            givens = [get_givens(s, tokens, 'object')]
            print 'get_loc_given_obj'
            locations_returned = get(
            olp = olp['objects'],
            name_attribute = 'location',
            givens = givens
            )
            print(locations_returned)
            if locations_returned:
		answer_to_be_returned = [ 'The ' + givens[0][0]['value'] +' is in the '+ locations_returned[0] ]

    if 'what' in s or 'objects' in s:
        if count_list == to_count_list({'location': 1}):
            #question = 'What objects are in the shelf?'
            givens = [get_givens(s, tokens, 'location')]
            print 'get_obj_given_loc'
            objects_returned = get(
            olp = olp['objects'],
            name_attribute = 'object',
            givens = givens
            )
            print(objects_returned)
            if objects_returned:
		answer_to_be_returned = " ".join(str(x+', ') for x in objects_returned) + sing_plurize_is(len(objects_returned))+ ('in the ' + givens[0][0]['value'])
	    else:
		answer_to_be_returned = ['There is nothing.']

    if 'color' in s or 'colour' in s:
        if count_list == to_count_list({'object': 1}) or 'orange' in s:
            #question = "what's the colour of the chocolate bar?"
            givens = [get_givens(s, tokens, 'object')]
            print 'get_color_given_obj'
            colors_returned = get(
            olp = olp['objects'],
            name_attribute = 'color',
            givens = givens
            )
            print(colors_returned)
            if colors_returned:
		answer_to_be_returned = ['The color of the ' +  givens[0][0]['value'] + ' is ' + colors_returned[0] ]
	    else:
		answer_to_be_returned = ['I do not know']

    if 'smaller' in tokens or 'bigger' in tokens:
        if count_list == to_count_list({'object': 2, 'size':1}) or ( count_list == to_count_list({'object': 2, 'size':1, 'color':1}) and 'orange' in s):
            #question = 'between the plate and coke, which one is smaller?'
            pair_attribute_values = get_pair_attribute_values(s, tokens, 'object')
            print 'compare_obj1_obj2_in_size'
            objects_returned = compare_pair_ordinal(
            olp = olp['objects'],
            pair_attribute_values = pair_attribute_values,
            in_terms = 'size',
            comparing_word = ('smaller' if 'smaller' in tokens else 'bigger')
            )
            print(objects_returned)
            if len(objects_returned) == 1:
		answer_to_be_returned = [ 'The '+objects_returned[0] + ' is ' + ('smaller' if 'smaller' in s else 'bigger')]
	    elif len(objects_returned) == 2:
		answer_to_be_returned = ['They have the same size']
	    else:
		answer_to_be_returned = ['I do not know']

    if 'lighter' in s or 'heavier' in s:
        if count_list == to_count_list({'object': 2, 'weight':1}) or (count_list == to_count_list({'object': 2, 'weight':1, 'color':1}) and 'orange' in s):
            #question = 'between the chocolate bar and cloth, which one is lighter?'
            pair_attribute_values = get_pair_attribute_values(s, tokens, 'object')
            print 'compare_obj1_obj2_in_weight'
            objects_returned = compare_pair_ordinal(
            olp = olp['objects'],
            pair_attribute_values = pair_attribute_values,
            in_terms = 'weight',
            comparing_word = ('lighter' if 'lighter' in tokens else 'heavier')
            )
            if len(objects_returned) == 1:
		answer_to_be_returned = ['The ' + objects_returned[0] + ' is ' + ('lighter' if 'lighter' in s else 'heavier')]
	    elif len(objects_returned) == 2:
		answer_to_be_returned = ['They have the same weight']
	    else:
		answer_to_be_returned = ['I do not know']

    if count_list == to_count_list({'category': 1, 'location': 1}):
        #question = 'how many food are in the dining table?'
        givens = [get_givens(s, tokens, 'object') + get_givens(s, tokens, 'category') + get_givens(s, tokens, 'location')]
        print 'count_obj_given_cat_loc'
        num_objects_returned = count_entities(
        olp = olp['objects'],
        givens = givens,
        has_qty = True
        )
        print(num_objects_returned)
        if num_objects_returned:
	    answer_to_be_returned = ['There '+sing_plurize_is(num_objects_returned) + str(num_objects_returned) + ' ' + sing_plurize(givens[0][1]['value'], num_objects_returned)]
	else:
	    answer_to_be_returned = ['There is no ' + givens[0][0]['value'] +' in the '+ givens[0][1]['value']]

    if count_list == to_count_list({'category': 1, 'size': 1}):
        #question = 'which is the biggest food?'
        comparing_word = ''
        for w in size: # 'size'
            if w in tokens:
                comparing_word = w
                break
        givens = [get_givens(s, tokens, 'category')]
        print 'compare_objs_in_size_given_cat'
        objects_returned = compare_set(
        olp = olp['objects'],
        name_attribute = 'object',
        in_terms = 'size',
        givens = givens,
        comparing_word= comparing_word
        )
        print(objects_returned)
        if objects_returned:
	    answer_to_be_returned = ['The '+ comparing_word + ' ' + sing_plurize(givens[0][0]['value'],len(objects_returned)) + sing_plurize_is(len(objects_returned)) + ''.join(str(x+', ')for x in objects_returned) ]
	else:
	    answer_to_be_returned = ['I do not know.']
    '''
    From here, edit examples
    '''

    if count_list == to_count_list({'category': 1, 'weight': 1}):
        #question = 'Which is the heaviest food?'
        for w in weight: # 'weight'
            if w in tokens:
                comparing_word = w
                break
        givens = [get_givens(s, tokens, 'category')]
        print 'compare_objs_in_weight_given_cat'
        objects_returned = compare_set(
        olp = olp['objects'],
        name_attribute = 'object',
        in_terms = 'weight',
        givens = givens,
        comparing_word=comparing_word
        )
        print(objects_returned)
        if objects_returned:
	    answer_to_be_returned = ['The '+ comparing_word + ' ' + sing_plurize(givens[0][0]['value'],len(objects_returned)) + sing_plurize_is(len(objects_returned))+ ''.join(str(x+', ')for x in objects_returned)  ]
	else:
	    answer_to_be_returned = ['I do not know.']

    if ('japan' not in s) and ('how many' in s or 'size' in s or 'number' in s) and ('crowd' in s or 'people' in s):
        if count_list == to_count_list({}):
            '''
            question = 'how many chairs are in the dining room?'
            process_question(question, olp, '')
            '''
            print 'count_people'
            num_people_returned = count_entities(
            olp = olp['people'],
            givens = givens,
            has_qty = False
            )
            print(num_people_returned)
            if num_people_returned:
		answer_to_be_returned = ['There '+ sing_plurize_is(num_people_returned) + str(num_people_returned) + sing_plurize_pp(num_people_returned)]
	    else:
		answer_to_be_returned = ['There is nobody']

    if count_list == to_count_list({'gesture': 1}):
        #question = 'how many people in the crowd are rising right arm?'
        givens = [get_givens(s, tokens, 'gesture')]
        print 'count_people_given_gesture'
        num_people_returned = count_entities(
        olp = olp['people'],
        givens = givens,
        has_qty = False
        )
        print(num_people_returned)
        if num_people_returned:
	    answer_to_be_returned = [str(num_people_returned) + ' '+sing_plurize_pp(num_people_returned)+ sing_plurize_is(num_people_returned) +givens[0][0]['value']]
	else:
	    answer_to_be_returned = ['There is no person '+givens[0][0]['value']]


    if count_list == to_count_list({'gesture': 2}):
        #question = 'how many people in the crowd are standing or sitting?'
        a = get_givens(s, tokens, 'gesture')
        givens = [[a[0]], [a[1]]]
        print 'count_people_given_gesture1_or_gesture2'
        num_people_returned = count_entities(
        olp = olp['people'],
        givens = givens,
        has_qty = False
        )
        print(num_people_returned)
        if num_people_returned:
	    answer_to_be_returned = [str(num_people_returned) + ' '+sing_plurize_pp(num_people_returned)+ sing_plurize_is(num_people_returned) + givens[0][0]['value']+ ' or ' + givens[1][0]['value']]
	else:
	    answer_to_be_returned = ['There is no person '+givens[0][0]['value']+ ' or ' + givens[1][0]['value']]

    if count_list == to_count_list({'gender': 1}):
        #question = 'tell me the number of males in the crowd'
        givens = [get_givens(s, tokens, 'gender')]
        print 'count_people_given_gender'
        num_people_returned = count_entities(
        olp = olp['people'],
        givens = givens,
        has_qty = False
        )
        print(num_people_returned)
        if num_people_returned:
	    answer_to_be_returned = ['There '+ sing_plurize_is(num_people_returned) +str(num_people_returned)+' ' + sing_plurize(givens[0][0]['value'],num_people_returned)]
	else:
	    answer_to_be_returned = ['There is no '+givens[0][0]['value']]

    if count_list == to_count_list({'age': 1}):
        #question = 'how many children are in the crowd'
        #question = 'tell me the number of elders in the crowd'
        givens = [get_givens(s, tokens, 'age')]
        print 'count_people_given_age'
        num_people_returned = count_entities(
        olp = olp['people'],
        givens = givens,
        has_qty = False
        )
        print(num_people_returned)
        if num_people_returned:
	    answer_to_be_returned = ['There '+ sing_plurize_is(num_people_returned) +str(num_people_returned)+' ' + sing_plurize(givens[0][0]['value'],num_people_returned)]
	else:
	    answer_to_be_returned = ['There is no '+givens[0][0]['value']]

    if count_list == to_count_list({'color': 1}):
        #question = 'tell me how many people were wearing blue'
        givens = [get_givens(s, tokens, 'color')]
	givens[0][0]['attribute'] = 'ucolor'
        print 'count_people_given_color'
        num_people_returned = count_entities(
        olp = olp['people'],
        givens = givens,
        has_qty = False
        )
        print(num_people_returned)
        if num_people_returned:
	    answer_to_be_returned = ['There ' + sing_plurize_is(num_people_returned) + str(num_people_returned)+' ' +sing_plurize_pp(num_people_returned) +'wearing ' + givens[0][0]['value']]
	else:
	    answer_to_be_returned = ['There is no person wearing '+givens[0][0]['value']]

    if count_list == to_count_list({'gender': 1, 'operator': 1}) or count_list == to_count_list({'gender': 2, 'operator': 1}):
        # 'Am I a man or a woman?'
        # givens = 'I'
        print 'get_gender_given_op'
        gender_returned = get(
        olp = olp['op'],
        name_attribute = 'gender')
        print(gender_returned)
        answer_to_be_returned = ['You are a ' + gender_returned[0]]

    if count_list == to_count_list({'age': 1, 'operator': 1}):
        '''
        question = 'how old do you think i am'
        process_question(question, olp, '')
        '''
        print 'get_age_given_op'
        answer_to_be_returned = ['GET_AGE'] #get age in scenario code

    if count_list == to_count_list({'gesture': 1, 'gender': 1}) or count_list == to_count_list({'gesture': 1, 'gender': 2}):
        #question = 'was the standing person boy or girl?'
        givens = [get_givens(s, tokens, 'gesture')]
        print 'get_gender_given_gesture'
        gender_returned = get(
        olp = olp['people'],
        name_attribute = 'gender',
        givens = givens
        )
        print(gender_returned)
        answer_to_be_returned = ['The '+givens[0][0]['value'] + ' person was a ' + gender_returned[0] ]

    if count_list == to_count_list({'gesture': 1, 'gender': 1, 'age': 1}):
	#??/ i think it's not used
        givens = [get_givens(s, tokens, 'gesture')]
        print 'get_gender_age_given_gesture'
        gender_returned = get(
        olp = olp['people'],
        name_attribute = 'gender',
        givens = givens
        )
        age_returned = get(
        olp = olp['people'],
        name_attribute = 'age',
        givens = givens
        )
        print(gender_returned)
        print(age_returned)
	#TODO
        answer_to_be_returned = gender_returned # disregard age

    #predefined
    if 'time' in s:
        print 'get_time'
        answer_to_be_returned = 'get_time'
        now = datetime.datetime.now()
        answer_to_be_returned = now.strftime("%H %M")

    if 'today' in s:
        print 'get_today'
        answer_to_be_returned = 'get_today'
        now = datetime.datetime.now()
        answer_to_be_returned = now.strftime("%B %d %Y")

    if 'last' in s:
        print 'get_last_question'
        answer_to_be_returned = question_prev

    if 'computer' in s or 'bug' in s:
        print 'get_predefined_1'
        answer_to_be_returned = 'From a moth trapped in a relay'

    if 'compiler' in s:
        print 'get_predefined_2'
        # print('<NAME> invented it')
        answer_to_be_returned = '<NAME> invented it'

    if 'b' in tokens or 'B' in tokens or 'bee' in tokens:
        print 'get_predefined_3'
        answer_to_be_returned = 'B was developed circa 1969 at Bell Labs'

    if 'lives' not in s and 'who' in s and ('c' in tokens or 'see' in s or 'sea' in s):
        print 'get_predefined_4'
        answer_to_be_returned = '<NAME> and <NAME>'

    if 'when' in s and ('c' in tokens or 'see' in s or 'sea' in s):
        print 'get_predefined_5'
        # print('C was developed after B in 1972 at Bell Labs')
        answer_to_be_returned = 'C was developed after B in 1972 at Bell Labs'

    if ('highest' in s or 'mountain' in s) and 'japan' in s:
        print 'get_predefined_6'
        # print('The highest point in Japan is Mount Fuji, which reaches 3776m above sea level')
        answer_to_be_returned = 'The highest point in Japan is Mount Fuji, which reaches 3776m above sea level'

    if 'capital' in s:
        print 'get_predefined_7'
        answer_to_be_returned = 'The capical of Canada is Ottawa'

    if 'origin' in s and 'canada' in s:
      answer_to_be_returned = 'The name Canada comes from the Iroquois word Kanata, meaning village or settlement.'

    if 'national' in s and 'canada' in s:
      answer_to_be_returned = 'O Canada'


    # if 'people' in s and 'japan' in s:
    #     print 'get_predefined_8'
    #     print('A little over 80 million')
    #     answer_to_be_returned = 'A little over 80 million'
    #
    # if 'flag' in s:
    #     print 'get_predefined_9'
    #     print('Japanese flag is a red circle centred over white')
    #     answer_to_be_returned = 'Japanese flag is a red circle centred over white'
    #
    # if 'emperor' in s:
    #     print 'get_predefined_10'
    #     print('His Majesty Akihito sama is the emperor in Japan since January 7, 1989')
    #     answer_to_be_returned = 'His Majesty Akihito sama is the emperor in Japan since January 7, 1989'

    if ('robocup' in s or 'robocop' in s) and 'city' in s and 'next year' in s:
        print 'get_predefined_11'
        # print("It hasn't been announced yet.")
        answer_to_be_returned = "It hasn't been announced yet."

    if ('robocup' in s or 'robocop' in s) and 'which year' in s:
        print 'get_predefined_12'
        # print('The first official RoboCup games and conference was held in 1997')
        answer_to_be_returned = 'The first official RoboCup games and conference was held in 1997'

    if 'open' in s:
        print 'get_predefined_13'
        answer_to_be_returned = 'There is no standard defined for OPL'

    if 'social standard' in s:
        print 'get_predefined_14'
        answer_to_be_returned = 'The SoftBank Robotics Pepper'

    if 'domestic standard' in s:
        print 'get_predefined_15'
        answer_to_be_returned = 'The Toyota Human Support Robot'

    if 'dreams' in s:
        print 'get_predefined_16'
        answer_to_be_returned = 'I dream of Electric Sheep.'

    if 'your name' in s:
        print 'get_predefined_17'
        # print('My name is Pepper.')
        answer_to_be_returned = 'My name is HSR.'

    if 'name' in s and 'team' in s:
        print 'get_predefined_18'
        # print('Our team name is Aupair.')
        answer_to_be_returned = 'Our team name is Team PNU.'

    # if 'sakura' in s or 'Sakura' in s:
    #     print 'get_predefined_19'
    #     print('Sakura is the Japanese term for ornamental cherry blossom and its tree.')
    #     answer_to_be_returned = 'Sakura is the Japanese term for ornamental cherry blossom and its tree.'

    if ('city' in s or 'cities' in s) and 'next' not in s and 'capital' not in s:
        print 'get_predefined_20'
        answer_to_be_returned = 'Montreal.'

    if  'year' in s and ('participate' in s or 'participates' in s or 'years' in s):
        print 'get_predefined_21'
        print('32.')
        answer_to_be_returned = '32.'

    # if 'popular' in s or 'vote' in s or 'election' in s:
    #     print 'get_predefined_22'
    #     print('<NAME>')
    #     answer_to_be_returned = '<NAME>.'
    '''
    if 'standard' in s or 'platforms' in s or 'platform' in s:
        print 'get_predefined_23'
        print('Pepper and HSR.')
        answer_to_be_returned = 'Pepper and HSR.'
    '''
    if 'dspl' in s:
        print 'get_predefined_24'
        print('Domestic Standard Platform League.')
        answer_to_be_returned = 'Domestic Standard Platform League.'

    if 'sspl' in s:
        print 'get_predefined_25'
        print('Social Standard Platform League.')
        answer_to_be_returned = 'Social Standard Platform League.'

    if 'alphabet' in s or 'sell' in s or 'boston' in s or 'dynamics' in s or 'dynamics' in s:
        print 'get_predefined_26'
        print('SoftBank.')
        answer_to_be_returned = 'SoftBank.'

    if 'nagoya' in s or 'train' in s or 'stations' in s or 'station' in s or 'world' in s:
        print 'get_predefined_27'
        print('over 410000 square metres.')
        answer_to_be_returned = 'over 410000 square metres.'

    if 'team' in s and 'home' in s:
        print 'get_predefined_28'
        print('Seoul.')
        answer_to_be_returned = 'Seoul.'

    if 'created' in s or 'star' in s or 'wars' in s or 'war' in s:
        print 'get_predefined_29'
        print('<NAME>.')
        answer_to_be_returned = '<NAME>.'

    if ('lives' in s or 'live' in s) and 'sea' in s :
        print 'get_predefined_30'
        print('<NAME> Squarepants!')
        answer_to_be_returned = 'Sp<NAME> Squarepants!'

    if ('grace' in s or 'hopper' in s) and 'invent' in s:
        print 'get_predefined_31'
        print('the inventor of the first compiler.')
        answer_to_be_returned = 'the inventor of the first compiler.'

    print str(answer_to_be_returned)

    if type(answer_to_be_returned) is list:
        n_elem = len(answer_to_be_returned)
        if n_elem == 0:
            answer_to_be_returned = 'nothing'
        elif n_elem == 1:
            answer_to_be_returned = str(answer_to_be_returned[0])
        else:
            answer_to_be_returned = answer_to_be_returned[:-1] +  ['and'] + answer_to_be_returned[-1:]
            answer_to_be_returned = " ".join([str(a) for a in answer_to_be_returned])

    return ('the answer is ' + str(answer_to_be_returned)) if (str(answer_to_be_returned) != "I'm sorry. I couldn't understand your intention.") else str(answer_to_be_returned)






people = [{'gender': 'man',
             'lcolor': '',
             'gesture': ['pointing left'],
             'ucolor': 'black',
	            'age': 'child' },

             {'gender': 'man',
             'lcolor': '',
             'gesture': ['rising left arm', 'rising right arm'],
             'ucolor': 'blue',
	            'age': 'adult' },

             {'gender': 'woman',
             'lcolor': '',
             'gesture': ['standing'],
             'ucolor': 'blue',
	            'age': 'elder' }]

op =  [{'gender': 'man',
        'lcolor': '',
        'gesture': ['standing'],
        'ucolor': 'black',
	'age': 'adult'}]

olp = {'objects': objects,'locations':locations, 'people': people, 'op': op}
q_prev = ''



pub_answer=rospy.Publisher('/pnu/answer',String,queue_size=2)


# def process_question(question, olp, question_prev):
#     return nogada(question.lower(), olp, question_prev)


question_prev=""

def question_callback(data):
  global question_prev
  question=data.data
  str=nogada(question.lower(), olp, question_prev)
  question_prev=question.lower()
  msg=String()
  msg.data=str
  pub_answer.publish(msg)


rospy.init_node('spragent')
rospy.Subscriber("/pnu/question", String, question_callback)
rospy.spin()


#
# def main():
#
#     # locations, objects = import_csv()
#     print '-----------------------'
#     print people
#     print '-----------------------'
#
#
#
#     prev_example="none"
#     #for example in spr_examples1:
#     #for example in spr_examples_pr_2018:
#     for example in spr_examples2:
#         print '-' * 50
#         print example
#         process_question(example, {'objects': objects, 'locations': locations, 'people': people, 'op': op}, prev_example)
#         prev_example=example
#
# if __name__ == '__main__':
#     main()

#!/usr/bin/env python
# coding: utf-8
import datetime

import nltk
from operator import add
from pprint import pprint
from random import random, uniform

import rospy
from std_msgs.msg import String




import os
import csv
#nltk.download('punkt')


object_ = ['chip', 'senbei', 'pringles', 'peanut', 'candy', 'chewing gum', 'cup star', 'curry', 'fries', 'jelly', 'noodle', 'paprika', 'melon', 'sushi', 'flake', 'bread', 'corn', 'onion', 'radish', 'tea', 'beer', 'coke', 'sake', 'aquarius', 'cold brew', 'green tea', 'soap', 'cloth', 'sponge', 'bowl', 'mug', 'glass', 'tray', 'plate', 'box', 'bag', 'soup container', 'apple', 'orange', 'asience', 'hair spray', 'moisturizer', 'shampoo', 'chopstick', 'fork', 'spoon', 'chair', 'plant', 'book', 'umbrella', 'basket', 'blanket', 'pillow', 'cushion', 'toy', 'rug', 'chiar', 'pastel', 'pencil', 'clock', 'tintintin', 'lamp', 'ball', 'hook', 'pen', 'egg', 'jar', 'tomato', 'eggplant', 'chili', 'shaker', 'teaspoon', 'knife', 'sink', 'detergent', 'stove', 'dishwasher', 'pepper', 'salt', 'pasta', 'spatula', 'ornament', 'scale', 'microwave', 'portrait', 'frame', 'window', 'bottle']

object_plural = ['chips', 'senbeis', 'peanuts', 'candies', 'chewing gums', 'cup stars', 'curries', 'jellies', 'noodles', 'paprikas', 'melons', 'sushies', 'flakes', 'corns', 'onions', 'radishes', 'green tea', 'soaps', 'clothes', 'sponges', 'bowls', 'mugs', 'glasses', 'trays', 'plates', 'boxes', 'bags', 'soup containers', 'apples', 'oranges', 'asiences', 'hair sprays', 'moisturizers', 'shampoos', 'chopsticks', 'forks', 'spoons', 'chairs', 'plants', 'books', 'umbrellas', 'baskets', 'blankets', 'pilows', 'cushions', 'toys', 'rugs', 'chiars', 'pastels', 'pencils', 'clocks', 'tintintins', 'lamps', 'balls', 'hooks', 'pens', 'eggs', 'jars', 'tomatoes', 'eggplants', 'chilis', 'shakers', 'teaspoons', 'knifes', 'sinks', 'detergents', 'stoves', 'dishwashers', 'peppers', 'salts', 'pastas', 'spatulas', 'ornaments', 'scales', 'microwaves', 'portraits', 'frames', 'windows', 'clothes hanger', 'toy hanger', 'bottles']

category = ['snack', 'food', 'drink', 'toiletry', 'container', 'fruit', 'cleaning stuff', 'cutlery', 'none']

category_plural = ['snacks', 'foods', 'drinks', 'toiletries', 'containers', 'fruits', 'cleaning stuffs', 'cutleries']

room = ['bedroom', 'living room', 'office', 'kitchen', 'corridor', 'bathroom', 'entrance', 'balcony']

location = ['none', 'bed', 'bedside', 'tv stand', 'shelf', 'sideshelf', 'cabinet', 'living table', 'dining table', 'desk', 'bar', 'fridge',  'teepee', 'right rack', 'left rack', 'sofa', 'bistro table', 'door', 'sideboard', 'left plank', 'right plank', 'kitchen table', 'kitchen shelf', 'kitchen rack', 'entrance shelf', 'balcony shelf', 'kitchen counter', 'little desk', 'bookcase', 'tv', 'hanger']

location_plural = ['beds', 'bedsides', 'tv stands', 'shelves', 'sideshelves', 'cabinets', 'living tables', 'dining tables', 'desks', 'bars', 'fridges',  'teepees', 'racks', 'sofas', 'bistro tables', 'doors', 'sideboards', 'planks']

shape = ['cuboid', 'cylinder', 'cone', 'sphere', 'hexagon', 'triangle']

size = ['small', 'medium', 'large', 'biggest', 'smallest', 'largest', 'smaller', 'larger', 'bigger']

weight = ['light', 'medium', 'heavy', 'heaviest', 'lightest', 'heavier', 'lighter']

quantity = ['nan', 'inf', '1', '2', '3', '4', '5', '6', '7', '8', '9', '10']

color = ['black', 'white', 'red', 'orange', 'yellow', 'green', 'blue', 'purple', 'transparency', 'brown', 'grey', 'pink']

gesture = ['lying', 'sitting', 'standing', 'pointing left', 'pointing right', 'rising left arm', 'rising right arm']

gender_values = ['man', 'woman']

gender = ['man', 'woman', 'male', 'female', 'boy', 'girl']

gender_plural = ['men', 'women',  'males', 'females', 'boys', 'girls']

age = ['child', 'adult', 'elder', 'old']

age_plural = ['children', 'adults', 'elders', 'olds']

plural_words = object_plural + category_plural + location_plural + gender_plural + age_plural

operator = ['i']

city = ['nagoya']

year = ['2017']

keywords = ['where', 'room', 'category', 'belong', 'where', 'find', 'what', 'objects', 'color', 'colour',
'smaller', 'bigger', 'lighter', 'heavier', 'how', 'many', 'size', 'number', 'crowd', 'people',
'time', 'today', 'last', 'computer', 'bug', 'compiler', 'B', 'C', 'who', 'when', 'highest', 'capital',
'people', 'Japan', 'flag', 'Sakura', 'emperor', 'RoboCup', 'city', 'year', 'open', 'social standard',
'domestic standard', 'dreams', 'name', 'team']

homophones = {
    'write': 'right',
    'sighs': 'size',
    'ear': 'year',
    'serial': 'cereal',
    'blew': 'blue',
    'read': 'red',
    'thyme': 'time',
    'wee': 'we',
    'mince': 'mints',
    'tee': 'tea',
    'bier': 'beer',
    'plait': 'plate',
    'bee': 'b',
    'cheep': 'chip',
    'robocop': 'robocup',
    'spear': 'sphere',
    'eye': 'i',
    'bad': 'bed',
    'tp': 'teepee',
    'france': 'plank',
    'tpr': 'teepee',
	'thanks': 'planks',
	'ppr': 'teepee' }



locations = [{'location': 'door', 'room': 'living room'},
               {'location': 'door', 'room': 'living room'},
               {'location': 'living table', 'room': 'living room'},
               {'location': 'shelf', 'room': 'living room'},
               {'location': 'door', 'room': 'bedroom'},
               {'location': 'desk', 'room': 'bedroom'},
               {'location': 'bed', 'room': 'bedroom'},
               {'location': 'door', 'room': 'kitchen'},
               {'location': 'sink', 'room': 'kitchen'},
               {'location': 'sideshelf', 'room': 'kitchen'},
               {'location': 'shelf', 'room': 'kitchen'},
               {'location': 'dining table', 'room': 'kitchen'},
               {'location': 'fridge', 'room': 'kitchen'}]

objects = [{'category': 'toiletry',
              'color': 'red',
              'location': 'living table',
              'object': 'shampoo',
              'quantity': 2,
              'room': 'living room',
              'shape': 'cylinder',
              'size': 'medium',
              'weight': 'medium'},
             {'category': 'food',
              'color': 'orange',
              'location': 'living table',
              'object': 'noodle',
              'quantity': 1,
              'room': 'living room',
              'shape': 'cylinder',
              'size': 'medium',
              'weight': 'light'},
             {'category': 'candy',
              'color': 'green',
              'location': 'living table',
              'object': 'chocolate egg',
              'quantity': 1,
              'room': 'living room',
              'shape': 'sphere',
              'size': 'small',
              'weight': 'light'},
             {'category': 'candy',
              'color': 'orange',
              'location': 'living table',
              'object': 'chocolate egg',
              'quantity': 1,
              'room': 'living room',
              'shape': 'sphere',
              'size': 'small',
              'weight': 'light'},
             {'category': 'snack',
              'color': 'red',
              'location': 'shelf',
              'object': 'chip',
              'quantity': 1,
              'room': 'living room',
              'shape': 'cuboid',
              'size': 'medium',
              'weight': 'light'},
             {'category': 'snack',
              'color': 'green',
              'location': 'shelf',
              'object': 'chip',
              'quantity': 1,
              'room': 'living room',
              'shape': 'cuboid',
              'size': 'large',
              'weight': 'medium'},
             {'category': 'candy',
              'color': 'black',
              'location': 'desk',
              'object': 'chocolate bar',
              'quantity': 2,
              'room': 'bedroom',
              'shape': 'cuboid',
              'size': 'medium',
              'weight': 'medium'},
             {'category': 'container',
              'color': 'blue',
              'location': 'bed',
              'object': 'box',
              'quantity': 1,
              'room': 'bedroom',
              'shape': 'cuboid',
              'size': 'large',
              'weight': 'medium'}]



spr_examples1 = [
    # Computer
    'where does the term computer bug come from',
    'who invented the c programming language',
    'when was invented the c programming language',
    'when was invented the b programming language',
    'who invented the first compiler',
    # Japan
    'what is the highest point in japan',
    'what city is the capital of the japan',
    'how many people live in the japan',
    'what are the colours of the japanese flag',
    'what is a sakura',
    'who is the emperor of japan',
    # Robocup
    'in which city will next year\'s robocup be hosted',
    'in which year was robocup@home founded',
    'which robot is used in the open platform league',
    'which robot is used in the social standard platform league',
    'which robot is used in the domestic standard platform league',
    # Nonsense
    'do you have dreams',
    # Team
    'what is your name',
    'what is your team\'s name',
    'what\s the name of your team',
    # Additional function required
    'what time is it',
    'what day is today',
    'what was the last question',
]

spr_examples2 = [
    # Arena
    'where is located the sink',
    'where is the shelf',
    'in which room is the fridge', #placement, beacon ?
    'how many shelves are in the living room',
    'how many doors has the bedroom',
    'how many chairs are in the dining room',
    # Object
    'to which category belong the chips',
    'how many drinks there are',
    'where can I find a chips',
    'what objects are stored in the bed',
    'what objects are stored in the dining table',
    'what objects are in the shelf',
    'what\'s the colour of the bread',
    'what\'s the color of the orange',
    'between the plate and coke, which one is smaller',
    'between the noodles and chips, which one is heavier',
    'between the chocolate bar and cloth, which one is lighter',
    'how many food are in the dining table',
    'which is the lightest drinks',
    'which is the heaviest food',
    'which is the biggest candies',
    'what\'s the smallest food',
    # Crowd
    'how many people in the crowd are rising right arm',
    'how many people in the crowd are standing or sitting',
    'tell me the number of males in the crowd',
    'tell me the number of women in the crowd',
    'how many females are in the crowd',
    'how many children are in the crowd',
    'how many adults are in the crowd',
    'how many elders are in the crowd',
    'tell me the number of elders in the crowd',
    'tell me how many people were wearing blue',
    'was the standing person boy or girl',
    'was the standing person man or woman',
    'tell me if the standing person was a boy',
    'how old do you think i am',
    'am i a man or a woman'
]

spr_examples3=[
'Where can I find a orange?',
'What\'s the colour of the orange?',
'How many oranges are in the kitchen?',
'To which category belong the orange?',
'Do the apple and orange belong to the same category?',
'Between the apple and orange, which one is lighter?'


]

spr_examples4 = [
#1. Arena
'where is the cup star',
'where does a candy locate',
'in which room is the rack',
'in which room does the little desk belong to',
'how many doors are in the bedroom',
'how many forks are in the kitchen',
'how many shampoos are in the balcony',
#2. Object
'what is the smallest food',
'Which is the smallest object',
'what is the largest fruit',
'what is the lightest drink',
'what is the heaviest cutlery',
'to which category do forks belong to',
'to which category belong the peanuts',
'do the apple and orange belong to the same category',
'where can I find some onion',   #NOT
'where can I find a shampoo',
'where can I find a red hair spray',
'what is the color of the soup container',
'what is the color of the apple',
'what is the color of an apple',
'what is the shape of jellies',
'what is the shape of the candy',
'what does a chewing gum look like',
'what objects are stored in the rack',
'what is in the teepee',
'what can I find on the sofa',
'between bread and corn, which one is lighter',
'asience and moisturizer, which one is heavier',
'which one is bigger, fork and spoon',
'How many drinks are there',
'How many objects are in the sideboard',
'How many drinks are on the kitchen counter',
'How many chopsticks are in the left plank'
]

spr_examples_pr = [
'Who invented the C programming language?',
'When was invented the C programming language?',
'When was invented the B programming language?',
'Where does the term computer bug come from?',
'Who invented the first compiler',
'Which robot is used in the Open Platform League',
'Which robot is used in the Domestic Standard Platform League',
'Which robot is used in the Social Standard Platform League',
'How many people live in the Japan?',
'What are the colours of the Japanese flag?',
'What city is the capital of the Japan?',
'What is the highest point in Japan',
'What is sakura',
'Who is the emperor of Japan?',
'What\'s the name of your team?',
'What time is it?',
'What day is today?',
'Do you have dreams?',
'In which city will next year\'s RoboCup be hosted?'
]

spr_examples_pr_2018 = [
'Who invented the C programming language?',
'When was the C programming language invented?',
'When was the B programming language invented?',
'Where does the term computer bug come from?',
'Who invented the first compiler',
'Which robot is used in the Open Platform League',
'Which robot is used in the Domestic Standard Platform League',
'Which robot is used in the Social Standard Platform League',
'What\'s the name of your team?',
'What time is it?',
'What day is today?',
'Do you have dreams?',
'In which city will next year\'s RoboCup be hosted?',
'What is the origin of the name Canada?',
'What is the capital of the name Canada?',
'What is the national anthem of Canada?',
]

















ex = [
'Where is located the bed?',
'In which room is the bed',
'How many doors has the bedroom?',
'How many desks are in the living room?'
]

ex2 = [
    'to which category belong the oranges',
    'how many oranges are in the dining table',
    'how many apples are in the dining table',
    'where can I find a oranges'
]

ex3 = [
'how many children are in the crowd',
'how many elders are in the crowd',
'how many boys are in the crowd'

]


attribute_map = {'object': object_, 'category': category, 'room': room, 'location': location, 'shape': shape, 'size': size, 'weight': weight, 'quantity': quantity, 'color': color, 'gesture': gesture, 'gender': gender, 'age': age, 'operator': operator, 'city': city, 'year': year}
all_words_b4_split = (object_ + category + room + location + shape + size + weight + quantity + color + gesture + gender + age + operator + city + year + plural_words + keywords)
all_words_duplicate = []
for i in range(len(all_words_b4_split)): all_words_duplicate = all_words_duplicate + all_words_b4_split[i].split()
all_words = list(set(all_words_duplicate))
singular_words = list(set(all_words) - set(plural_words))


def count(s, tokens, attribute_words, count_multiple_occurences_for_single_attribute_word=False):
    if not count_multiple_occurences_for_single_attribute_word:
        return reduce(add, [int((word in s) if ' ' in word else (word in tokens)) for word in attribute_words])
    else:
        return reduce(add, [s.count(word) if ' ' in word else tokens.count(word) for word in attribute_words])

def to_count_list(d):
    ret = [0] * 12
    if 'object' in d: ret[0] += d['object']
    if 'category' in d: ret[1] += d['category']
    if 'room' in d: ret[2] += d['room']
    if 'location' in d: ret[3] += d['location']
    if 'shape' in d: ret[4] += d['shape']
    if 'size' in d: ret[5] += d['size']
    if 'weight' in d: ret[6] += d['weight']
    if 'color' in d: ret[7] += d['color']
    if 'gesture' in d: ret[8] += d['gesture']
    if 'gender' in d: ret[9] += d['gender']
    if 'age' in d: ret[10] += d['age']
    if 'operator' in d: ret[11] += d['operator']
    return ret


'''
arguments in get(), count_entities(), compare_pair_nominal(), compare_pair_ordinal(), compare_set()

olp: one of objects, locations, or people (all of them are a list of dictionaries)

name_attribute: the name of an attribute of entities
    e.g., 'object'
    # compare_objs_in_weight_given_cat
    # Which is the lightest drinks?
pair_attribute_values: a pair of attribute values of entities
    e.g., ('bowl', 'apple')
    # Do the bowl and apple belong to the same category?

givens: a (nested) list of dictionaries
    # {‘attribute’: ‘an_attribute’, ‘value’: ‘a_value’} of conditions
    # cf. [[a,b], [c, d]] = (a and b) or (c and d) = ab + cd
    # e.g., {‘attribute’: ‘category’, ‘value’: ‘snack’}
    e.g., {'attribute': 'gender', 'value': 'man'}
    e.g., {'attribute': 'object', 'value': 'sink'}
    # [[{'attribute': 'object', 'value': 'sink'}]]

has_qty: True if an element in an array has the quantity attribute
    objects have the quantity attribute
    locations and people do not have the quantity attribute

in_terms: an attribute in terms of which instances are compared
    e.g.,'category', 'size', 'weight'
    # compare_obj1_obj2_in_cat
    # Do the bowl and apple belong to the same category?
'''

def get(olp, name_attribute, givens=None):
    # returns the set of attribute values (no duplicates) of an attribute named name_attribute given givens
    # https://stackoverflow.com/questions/3013449/list-filtering-list-comprehension-vs-lambda-filter
    # givens = [[{'attribute': 'object', 'value': 'pringles'}]]
    # get(objects, 'category', givens)
    if givens is not None:
        given_gesture = (givens[0][0]['attribute'] == 'gesture')
        if not(given_gesture):
            olp_conditioned = [x for x in olp if (givens[0][0]['attribute'] in x) and (x[givens[0][0]['attribute']] == givens[0][0]['value'])]
        else:
            olp_conditioned = [x for x in olp if (givens[0][0]['attribute'] in x) and (givens[0][0]['value'] in x[givens[0][0]['attribute']])]
    else:
        olp_conditioned = olp
    list_entities = [x[name_attribute] for x in olp_conditioned]
    return list(set(list_entities))

def get_random_age(): #JUST RETURN 25 (?)
    age_interval = [10, 20, 30, 40, 50, 60]
    distr = [0.05, 0.4, 0.25, 0.15, 0.1, 0.05]
    default_age = 25
    return default_age

def count_entities(olp, givens, has_qty):
    # returns the number of entities (allowing duplicates) given givens by multiplying the quantities if has_qty is True
    count = 0
    # givens = [
    #     [{'attribute': 'location', 'value': 'shelf'}, {'attribute': 'room', 'value': 'living room'}],
    #     [{'attribute': 'location', 'value': 'fridge'}, {'attribute': 'room', 'value': 'kitchen'}]
    # ]
    # givens = [
    #     [{'attribute': 'ucolor', 'value': 'gray'}, {'attribute': 'gesture', 'value': 'sitting'}],
    #     [{'attribute': 'ucolor', 'value': 'red'}, {'attribute': 'gesture', 'value': 'pointing left'}],
    #     [{'attribute': 'ucolor', 'value': 'red'}]
    # ]
    print(givens)

    found = []

    if givens == None or len(givens) == 0:
        found = olp
    else:
        given_gesture = (givens[0][0]['attribute'] == 'gesture')
        for obj in olp:
            for props in givens: # props to be ORed
                matched = True

                for prop in props: # prop to be ANDed
                    if not(given_gesture) and (prop['attribute'] not in obj or obj[prop['attribute']] != prop['value']):
                        matched = False
                        break
                    elif given_gesture and (prop['attribute'] not in obj or prop['value'] not in obj[prop['attribute']]):
                        matched = False
                        break

                if matched:
                    print(obj)
                    break

            if matched:
                found.append(obj)

    for obj in found:
        if 'quantity' in obj and obj['quantity'] != 'inf':
            count += obj['quantity']
        else:
            count += 1

    print("count_entities will return " + str(count))
    return count

def compare_pair_nominal(olp, pair_attribute_values, in_terms):
    # objects, ('bowl', 'apple'), 'category'
    # objects, ('pringles', 'peanuts'), 'category'
    # objects, ('chocolate bar', 'chocolate egg'), 'category'
    x, y = pair_attribute_values # (bowl, apple)
    x_list = [z for z in olp if z['object'] == x] # TODO: make it general (future)
    y_list = [z for z in olp if z['object'] == y]
    if len(x_list) == 0 or len(y_list) == 0:
        return False
    else:
        if x_list[0][in_terms] == y_list[0][in_terms]:
            return True, x_list[0][in_terms]
        else:
            return False, None
# returns True if they are the same
# or returns False if they are different

def compare_pair_ordinal(olp, pair_attribute_values, in_terms, comparing_word):
    # inputs: objects, ('plate', 'coke'), 'size', 'smaller'
    # returns the list of entities preferable in terms of in_terms given givens

    # comparing_word: 'smaller', 'larger', 'bigger', 'lighter', 'heavier'
    # size: 'small', 'medium', 'large'
    # weight: 'light', 'medium', 'heavy'
    x, y = pair_attribute_values

    x_list = [z for z in olp if z['object'] == x] # TODO: make it general (future)
    if len(x_list) == 0:
        x_list = [z for z in olp if z['object'] == x + 's'] # compare with plural object values

    y_list = [z for z in olp if z['object'] == y]
    if len(y_list) == 0:
        y_list = [z for z in olp if z['object'] == y + 's'] # compare with plural object values

    if len(x_list) == 0 or len(y_list) == 0:
        return [] # no such object, so unknown
    else:
        if in_terms == 'size':
            if x_list[0][in_terms] == 'small':
                x_in_terms = 0
            elif x_list[0][in_terms] == 'medium':
                x_in_terms = 1
            elif x_list[0][in_terms] == 'large':
                x_in_terms = 2
            else:
                print('unexpected size in compare_pair_ordinal for x')
            if y_list[0][in_terms] == 'small':
                y_in_terms = 0
            elif y_list[0][in_terms] == 'medium':
                y_in_terms = 1
            elif y_list[0][in_terms] == 'large':
                y_in_terms = 2
            else:
                print('unexpected size in compare_pair_ordinal for y')
        elif in_terms == 'weight':
            if x_list[0][in_terms] == 'light':
                x_in_terms = 0
            elif x_list[0][in_terms] == 'medium':
                x_in_terms = 1
            elif x_list[0][in_terms] == 'heavy':
                x_in_terms = 2
            else:
                print('unexpected weight in compare_pair_ordinal for x')
            if y_list[0][in_terms] == 'light':
                y_in_terms = 0
            elif y_list[0][in_terms] == 'medium':
                y_in_terms = 1
            elif y_list[0][in_terms] == 'heavy':
                y_in_terms = 2
            else:
                print('unexpected weight in compare_pair_ordinal for y')
        else:
            print('unexpected terms in compare_pair_ordinal')

    if comparing_word == 'smaller' or comparing_word == 'lighter':
        if x_in_terms < y_in_terms:
            return [x]
        elif x_in_terms == y_in_terms:
            return [x, y]
        elif x_in_terms > y_in_terms:
            return [y]
    elif comparing_word == 'larger' or comparing_word == 'bigger' or comparing_word == 'heavier':
        if x_in_terms < y_in_terms:
            return [y]
        elif x_in_terms == y_in_terms:
            return [x, y]
        elif x_in_terms > y_in_terms:
            return [x]
    else:
        print('unexpected comparing word in compare_pair_ordinal')

def give_conditions(olp, givens):
    olp_conditioned = [] # givens to olp_conditioned
    if givens == None or len(givens) == 0:
        olp_conditioned = olp
    else:
        for entity in olp:
            for props in givens: # props to be ORed
                matched = True
                for prop in props: # prop to be ANDed
                    if prop['attribute'] not in entity or entity[prop['attribute']] != prop['value']:
                        matched = False
                        break

                if matched:
                    print(entity)
                    break

            if matched:
                olp_conditioned.append(entity)

    return olp_conditioned

def word2num(olp, in_terms):
    olp_in_terms = [0] * len(olp)
    if in_terms == 'size':
        for i in xrange(len(olp)):
            if olp[i][in_terms] == 'small':
                olp_in_terms[i] = 0
            elif olp[i][in_terms] == 'medium':
                olp_in_terms[i] = 1
            elif olp[i][in_terms] == 'large':
                olp_in_terms[i] = 2
            else:
                print('unexpected size in word2num for olp')
    elif in_terms == 'weight':
        for i in xrange(len(olp)):
            if olp[i][in_terms] == 'light':
                olp_in_terms[i] = 0
            elif olp[i][in_terms] == 'medium':
                olp_in_terms[i] = 1
            elif olp[i][in_terms] == 'heavy':
                olp_in_terms[i] = 2
            else:
                print('unexpected weight in word2num for olp')
    else:
        print('unexpected terms in word2num:', in_terms)

    return olp_in_terms

def list_duplicates(list_num,num):
    #indexes of num in list_num
    start_at = -1
    indices = []
    while True:
        try:
            idx = list_num.index(num,start_at+1)
        except ValueError:
            break
        else:
            indices.append(idx)
            start_at = idx
    return indices

def get_idx_min(list_num):
    #indexes of min value
    if len(list_num) == 0:
        return []

    val = min(list_num)
    list_idx = list_duplicates(list_num = list_num, num = val)
    return list_idx

def get_idx_max(list_num):
    #indexes of max value
    # https://stackoverflow.com/questions/2474015/getting-the-index-of-the-returned-max-or-min-item-using-max-min-on-a-list
    # https://stackoverflow.com/questions/5419204/index-of-duplicates-items-in-a-python-list
    if len(list_num) == 0:
        return []

    val = max(list_num)
    list_idx = list_duplicates(list_num = list_num, num = val)
    return list_idx

def get_idx_opt(list_num, opt):
    if len(list_num) == 0:
        return []

    if opt == 'min':
        return get_idx_min(list_num)
    elif opt == 'max':
        return get_idx_max(list_num)
    else:
        print('unexpected opt:', opt)

def get_set_values_given_name_idx(olp, name_attribute, idx):
    # https://stackoverflow.com/questions/18272160/access-multiple-elements-of-list-knowing-their-index
    print('olp:',  olp)
    print('name_attribute:', name_attribute)
    if len(idx)>0:
        print('olp[0]:',  olp[0])
        print('olp[0][name_attribute]:',  olp[0][name_attribute])

    c = [ olp[i][name_attribute] for i in idx]
    return list(set(c))

def compare_set(olp, name_attribute, in_terms, givens, comparing_word):
    print comparing_word
    # returns the list of entities preferable in terms of in_terms given givens
    # [Procedures]
    # choose entities given givens (givens)
    # change qualitative words to numbers (in_terms)
    # choose entities least or greatest according to comparing_word (comparing_word)
    # return the set of attribute values of those entities
    # (Choose entities given givens)
    olp_conditioned = give_conditions(olp, givens)
    print('olp_conditioned:')
    pprint(olp_conditioned)
    olp_in_terms = word2num(olp_conditioned, in_terms)
    #print(olp_in_terms)
    if comparing_word == 'smallest' or comparing_word == 'lightest':
        idx_opt = get_idx_opt(olp_in_terms, 'min')
    elif comparing_word == 'largest' or comparing_word == 'biggest' or comparing_word == 'heaviest':
        idx_opt = get_idx_opt(olp_in_terms, 'max')
    else:
        print('unexpected comparing word in compare_set')

    print('idx_opt:', idx_opt)
    set_attribute_values = get_set_values_given_name_idx(olp_conditioned, name_attribute, idx_opt)
    print('set_attribute_values:', set_attribute_values)
    return set_attribute_values

def get_givens(s, tokens, attribute):
    mk_dict = lambda x: {'attribute': attribute, 'value': x}
    ret = []
    for x in attribute_map[attribute]:
        if ' ' in x:
            if x in s:
                ret += [mk_dict(x)]
        else:
            if x in tokens:
                ret += [mk_dict(x)]
    return ret

def get_pair_attribute_values(s, tokens, attribute):
    ret = []
    for x in attribute_map[attribute]:
        if ' ' in x:
            if x in s:
                ret += [x]
        else:
            if x in tokens:
                ret += [x]
    return tuple(ret)


def singularize(word):
    if len(word) > 3 and word[-3:] == 'ves': # shelves
        return word[:-3] + 'f'
    elif word == 'children': # children
        return 'child'
    elif len(word) > 3 and (word[-3:] == 'les' or  word[-3:] == 'ges' or  word[-3:] == 'tes' or  word[-3:] == 'des' or  word[-3:] == 'kes'): # pringles, males, sponges, plates, bedsides, flakes
        return word[:-1]
    elif len(word) > 3 and (word[-3:] == 'ies'): # candies, toiletries
        return word[:-3] + 'y'
    elif  len(word) > 2 and word[-2:] == 'en': # men, women
        return word[:-2] + 'an'
    elif len(word) > 2 and word[-2:] == 'es':
        return word[:-2]
    else:
        return word[:-1]

def sing_plurize(word, num):
    # singularize or plurize word or is according to num
    if word == 'is' or word == 'are':
        return sing_plurize_is(num)
    if word == 'person' or word == 'people':
        return sing_plurize_pp(num)
    if (word in singular_words and num > 1):
	for w in plural_words:
	    if singularize(w) == word:
		ret = w
		break
	    ret = word
    elif (word in plural_words and num <= 1):
	ret = singularize(word)
    else:
        ret = word
    return ret+' '

def sing_plurize_is(num):
    if num > 1:
	return 'are '
    else:
	return 'is '

def sing_plurize_pp(num):
    if num > 1:
	return 'people '
    else:
	return 'person '

def nogada(s, olp, question_prev):
    # If-elses for every question type
    for plural_word in plural_words: s = s.replace(plural_word, singularize(plural_word))
    s = s.replace('female', 'woman')
    s = s.replace('male', 'man')
    s = s.replace('girl', 'woman')
    s = s.replace('boy', 'man')
    s = s.replace('dining room', 'kitchen')
    s = s.replace('dining table', 'kitchen table')
    s = s.replace('so far', 'sofa')
    s = s.replace('shooting', 'sitting')
    s = s.replace('searching', 'sitting')
    tokens = nltk.word_tokenize(s)

    # homophones
    keys = homophones.keys()
    while True:
        flag = True
        for key in keys:
            if key in tokens:
                s = s.replace(key, homophones[key])
                tokens = nltk.word_tokenize(s)
                flag = False
                break
        if flag:
            break

    object_for_count = list(object_)
    n_object = count(s, tokens, object_)
    n_category = count(s, tokens, category)
    n_room = count(s, nltk.word_tokenize(s.replace('kitchen counter', 'kitchencounter').replace('kitchen table', 'kitchentable').replace('kitchen rack', 'kitchenrack').replace('kitchen shelf', 'kitchenshelf').replace('entrance shelf', 'entranceshelf').replace('balcony shelf', 'balconyshelf')), room)
    n_location = count(s, nltk.word_tokenize(s.replace('chocolate bar', 'chocolatebar')), location)
    n_shape = count(s, tokens, shape)
    n_size = count(s, tokens, size)
    n_weight = count(s, tokens, weight)
    n_color = count(s, tokens, color)
    n_gesture = count(s, tokens, gesture)
    n_gender = count(s, tokens, gender)
    n_age = count(s, tokens, age)
    n_operator = count(s, tokens, operator)

    count_list = [n_object, n_category, n_room, n_location, n_shape, n_size, n_weight, n_color, n_gesture, n_gender, n_age, n_operator]

    print count_list

    givens = None
    pair_attribute_values = None

    answer_to_be_returned = "I'm sorry. I couldn't understand your intention."

    if 'where' in s or 'room' in s:
        if count_list == to_count_list({'location': 1}):
            # question = 'where is located the sink?'
            givens = [get_givens(s, tokens, 'location')]
            print 'get_room_given_loc'
            rooms_returned = get(
            olp = olp['locations'],
            name_attribute = 'room',
            givens = givens
            )
            print(rooms_returned)
            if rooms_returned:
		answer_to_be_returned = [ 'The ' + givens[0][0]['value'] + ' is in the ' + rooms_returned[0] ]
	    else:
		answer_to_be_returned = ['There is no '+ givens[0][0]['value'] + ' in the ' + rooms_returned[0]]

    if count_list == to_count_list({'room': 1, 'location': 1})  :
        #question = 'how many shelves are in the living room?'
        givens = [get_givens(s, tokens, 'location') + get_givens(s, tokens, 'room')]
        print 'count_loc_given_room'
        num_locations_returned = count_entities(
        olp = olp['locations'],
        givens = givens,
        has_qty = False
        )
        print(num_locations_returned)
        if num_locations_returned:
	    answer_to_be_returned = [ 'There '+sing_plurize_is(num_locations_returned) + str(num_locations_returned) + ' ' + sing_plurize(givens[0][0]['value'],num_locations_returned) + 'in the ' + givens[0][1]['value']  ]
	else:
	    answer_to_be_returned = [ 'There is no ' + givens[0][0]['value'] + ' in the ' + givens[0][1]['value']  ]

    if count_list == to_count_list({'object': 1, 'room': 1}) or (count_list == to_count_list({'object': 1, 'room': 1, 'color': 1}) and 'orange' in s)  :
        # 'how many chairs are in the dining room?'
        givens = [get_givens(s, tokens, 'object') + get_givens(s, tokens, 'room')]
        print 'count_obj_given_room'
        num_objects_returned = count_entities(
        olp = olp['objects'],
        givens = givens,
        has_qty = True
        )
        print(num_objects_returned)
        if num_objects_returned:
	    answer_to_be_returned = [ 'There '+sing_plurize_is(num_objects_returned) + str(num_objects_returned) +' '+  sing_plurize(givens[0][0]['value'],num_objects_returned) + 'in the ' + givens[0][1]['value']]
	else:
	    answer_to_be_returned = [ 'There is no ' +  givens[0][0]['value'] + ' in the ' + givens[0][1]['value']]

    if count_list == to_count_list({'object': 1, 'location': 1})or ( count_list == to_count_list({'object': 1, 'location': 1, 'color': 1}) and 'orange' in s ):
        # 'how many chairs are in the dining table?'
        givens = [get_givens(s, tokens, 'object') + get_givens(s, tokens, 'location')]
        print 'count_obj_given_loc'
        num_objects_returned = count_entities(
        olp = olp['objects'],
        givens = givens,
        has_qty = True
        )
        print(num_objects_returned)
        if num_objects_returned:
	    answer_to_be_returned = ['There '+sing_plurize_is(num_objects_returned) + str(num_objects_returned) + ' ' + sing_plurize(givens[0][0]['value'],num_objects_returned) +' in the ' + givens[0][1]['value']]

	else:
	    answer_to_be_returned = ['There is no ' + givens[0][0]['value'] +' in the ' + givens[0][1]['value']]


    if 'category' in s or 'belong' in s:
        if count_list == to_count_list({'object': 1})or ( count_list == to_count_list({'object': 1, 'color': 1}) and 'orange' in s) :
            #question = 'to which category belong the chips?'
            givens = [get_givens(s, tokens, 'object')]
            print 'get_cat_given_obj'
            categories_returned = get(
            olp = olp['objects'],
            name_attribute = 'category',
            givens = givens
            )
            print(categories_returned)
            if categories_returned:
		answer_to_be_returned = [ 'The ' + givens[0][0]['value'] + ' belongs to '+ categories_returned[0] ]
	    else:
		answer_to_be_returned = ['There is no such object']

        if count_list == to_count_list({'object': 2}) or ( count_list == to_count_list({'object': 2, 'color': 1}) and 'orange' in s)    :
            #question = 'do the bowl and apple belong to the same category?'
            givens = [get_givens(s, tokens, 'category')]
            pair_attribute_values = get_pair_attribute_values(s, tokens, 'object')
            print 'compare_obj1_obj2_in_cat'
            equality_returned, category_returned = compare_pair_nominal(
            olp = olp['objects'],
            pair_attribute_values = pair_attribute_values,
            in_terms = 'category'
            )
            print(equality_returned)
            if equality_returned:
		answer_to_be_returned = ['Yes, they both belong to ' + category_returned]
	    else:
		answer_to_be_returned = ['They do not belong to the same category.']

    if 'shape' in s and count_list == to_count_list({'object': 1}):
	# Not used
        givens = [get_givens(s, tokens, 'object')]
        print 'get_shape_given_obj'
        categories_returned = get(
        olp = olp['objects'],
        name_attribute = 'shape',
        givens = givens
        )
        print(categories_returned)
        answer_to_be_returned = categories_returned

    if count_list == to_count_list({'category': 1}):
        #'how many drinks there are?'
        givens = [get_givens(s, tokens, 'object') + get_givens(s, tokens, 'category')]
        print 'count_obj_given_cat'
        num_objects_returned = count_entities(
        olp = olp['objects'],
        givens = givens,
        has_qty = True
        )
        print(num_objects_returned)
        if num_objects_returned:
	    answer_to_be_returned = ['There '+sing_plurize_is(num_objects_returned) + str(num_objects_returned) + ' ' + sing_plurize(givens[0][0]['value'],num_objects_returned)]
	else:
	    answer_to_be_returned = ['There is no '+givens[0][0]['value']]
####LALA
    if 'where' in s or 'find' in s:
        if count_list == to_count_list({'object': 1}) or count_list == to_count_list({'object': 1, 'operator': 1}) or count_list == to_count_list({'object': 1, 'operator': 1, 'color': 1}):
            #question = 'where can I find a chips?'
            givens = [get_givens(s, tokens, 'object')]
            print 'get_loc_given_obj'
            locations_returned = get(
            olp = olp['objects'],
            name_attribute = 'location',
            givens = givens
            )
            print(locations_returned)
            if locations_returned:
		answer_to_be_returned = [ 'The ' + givens[0][0]['value'] +' is in the '+ locations_returned[0] ]

    if 'what' in s or 'objects' in s:
        if count_list == to_count_list({'location': 1}):
            #question = 'What objects are in the shelf?'
            givens = [get_givens(s, tokens, 'location')]
            print 'get_obj_given_loc'
            objects_returned = get(
            olp = olp['objects'],
            name_attribute = 'object',
            givens = givens
            )
            print(objects_returned)
            if objects_returned:
		answer_to_be_returned = " ".join(str(x+', ') for x in objects_returned) + sing_plurize_is(len(objects_returned))+ ('in the ' + givens[0][0]['value'])
	    else:
		answer_to_be_returned = ['There is nothing.']

    if 'color' in s or 'colour' in s:
        if count_list == to_count_list({'object': 1}) or 'orange' in s:
            #question = "what's the colour of the chocolate bar?"
            givens = [get_givens(s, tokens, 'object')]
            print 'get_color_given_obj'
            colors_returned = get(
            olp = olp['objects'],
            name_attribute = 'color',
            givens = givens
            )
            print(colors_returned)
            if colors_returned:
		answer_to_be_returned = ['The color of the ' +  givens[0][0]['value'] + ' is ' + colors_returned[0] ]
	    else:
		answer_to_be_returned = ['I do not know']

    if 'smaller' in tokens or 'bigger' in tokens:
        if count_list == to_count_list({'object': 2, 'size':1}) or ( count_list == to_count_list({'object': 2, 'size':1, 'color':1}) and 'orange' in s):
            #question = 'between the plate and coke, which one is smaller?'
            pair_attribute_values = get_pair_attribute_values(s, tokens, 'object')
            print 'compare_obj1_obj2_in_size'
            objects_returned = compare_pair_ordinal(
            olp = olp['objects'],
            pair_attribute_values = pair_attribute_values,
            in_terms = 'size',
            comparing_word = ('smaller' if 'smaller' in tokens else 'bigger')
            )
            print(objects_returned)
            if len(objects_returned) == 1:
		answer_to_be_returned = [ 'The '+objects_returned[0] + ' is ' + ('smaller' if 'smaller' in s else 'bigger')]
	    elif len(objects_returned) == 2:
		answer_to_be_returned = ['They have the same size']
	    else:
		answer_to_be_returned = ['I do not know']

    if 'lighter' in s or 'heavier' in s:
        if count_list == to_count_list({'object': 2, 'weight':1}) or (count_list == to_count_list({'object': 2, 'weight':1, 'color':1}) and 'orange' in s):
            #question = 'between the chocolate bar and cloth, which one is lighter?'
            pair_attribute_values = get_pair_attribute_values(s, tokens, 'object')
            print 'compare_obj1_obj2_in_weight'
            objects_returned = compare_pair_ordinal(
            olp = olp['objects'],
            pair_attribute_values = pair_attribute_values,
            in_terms = 'weight',
            comparing_word = ('lighter' if 'lighter' in tokens else 'heavier')
            )
            if len(objects_returned) == 1:
		answer_to_be_returned = ['The ' + objects_returned[0] + ' is ' + ('lighter' if 'lighter' in s else 'heavier')]
	    elif len(objects_returned) == 2:
		answer_to_be_returned = ['They have the same weight']
	    else:
		answer_to_be_returned = ['I do not know']

    if count_list == to_count_list({'category': 1, 'location': 1}):
        #question = 'how many food are in the dining table?'
        givens = [get_givens(s, tokens, 'object') + get_givens(s, tokens, 'category') + get_givens(s, tokens, 'location')]
        print 'count_obj_given_cat_loc'
        num_objects_returned = count_entities(
        olp = olp['objects'],
        givens = givens,
        has_qty = True
        )
        print(num_objects_returned)
        if num_objects_returned:
	    answer_to_be_returned = ['There '+sing_plurize_is(num_objects_returned) + str(num_objects_returned) + ' ' + sing_plurize(givens[0][1]['value'], num_objects_returned)]
	else:
	    answer_to_be_returned = ['There is no ' + givens[0][0]['value'] +' in the '+ givens[0][1]['value']]

    if count_list == to_count_list({'category': 1, 'size': 1}):
        #question = 'which is the biggest food?'
        comparing_word = ''
        for w in size: # 'size'
            if w in tokens:
                comparing_word = w
                break
        givens = [get_givens(s, tokens, 'category')]
        print 'compare_objs_in_size_given_cat'
        objects_returned = compare_set(
        olp = olp['objects'],
        name_attribute = 'object',
        in_terms = 'size',
        givens = givens,
        comparing_word= comparing_word
        )
        print(objects_returned)
        if objects_returned:
	    answer_to_be_returned = ['The '+ comparing_word + ' ' + sing_plurize(givens[0][0]['value'],len(objects_returned)) + sing_plurize_is(len(objects_returned)) + ''.join(str(x+', ')for x in objects_returned) ]
	else:
	    answer_to_be_returned = ['I do not know.']
    '''
    From here, edit examples
    '''

    if count_list == to_count_list({'category': 1, 'weight': 1}):
        #question = 'Which is the heaviest food?'
        for w in weight: # 'weight'
            if w in tokens:
                comparing_word = w
                break
        givens = [get_givens(s, tokens, 'category')]
        print 'compare_objs_in_weight_given_cat'
        objects_returned = compare_set(
        olp = olp['objects'],
        name_attribute = 'object',
        in_terms = 'weight',
        givens = givens,
        comparing_word=comparing_word
        )
        print(objects_returned)
        if objects_returned:
	    answer_to_be_returned = ['The '+ comparing_word + ' ' + sing_plurize(givens[0][0]['value'],len(objects_returned)) + sing_plurize_is(len(objects_returned))+ ''.join(str(x+', ')for x in objects_returned)  ]
	else:
	    answer_to_be_returned = ['I do not know.']

    if ('japan' not in s) and ('how many' in s or 'size' in s or 'number' in s) and ('crowd' in s or 'people' in s):
        if count_list == to_count_list({}):
            '''
            question = 'how many chairs are in the dining room?'
            process_question(question, olp, '')
            '''
            print 'count_people'
            num_people_returned = count_entities(
            olp = olp['people'],
            givens = givens,
            has_qty = False
            )
            print(num_people_returned)
            if num_people_returned:
		answer_to_be_returned = ['There '+ sing_plurize_is(num_people_returned) + str(num_people_returned) + sing_plurize_pp(num_people_returned)]
	    else:
		answer_to_be_returned = ['There is nobody']

    if count_list == to_count_list({'gesture': 1}):
        #question = 'how many people in the crowd are rising right arm?'
        givens = [get_givens(s, tokens, 'gesture')]
        print 'count_people_given_gesture'
        num_people_returned = count_entities(
        olp = olp['people'],
        givens = givens,
        has_qty = False
        )
        print(num_people_returned)
        if num_people_returned:
	    answer_to_be_returned = [str(num_people_returned) + ' '+sing_plurize_pp(num_people_returned)+ sing_plurize_is(num_people_returned) +givens[0][0]['value']]
	else:
	    answer_to_be_returned = ['There is no person '+givens[0][0]['value']]


    if count_list == to_count_list({'gesture': 2}):
        #question = 'how many people in the crowd are standing or sitting?'
        a = get_givens(s, tokens, 'gesture')
        givens = [[a[0]], [a[1]]]
        print 'count_people_given_gesture1_or_gesture2'
        num_people_returned = count_entities(
        olp = olp['people'],
        givens = givens,
        has_qty = False
        )
        print(num_people_returned)
        if num_people_returned:
	    answer_to_be_returned = [str(num_people_returned) + ' '+sing_plurize_pp(num_people_returned)+ sing_plurize_is(num_people_returned) + givens[0][0]['value']+ ' or ' + givens[1][0]['value']]
	else:
	    answer_to_be_returned = ['There is no person '+givens[0][0]['value']+ ' or ' + givens[1][0]['value']]

    if count_list == to_count_list({'gender': 1}):
        #question = 'tell me the number of males in the crowd'
        givens = [get_givens(s, tokens, 'gender')]
        print 'count_people_given_gender'
        num_people_returned = count_entities(
        olp = olp['people'],
        givens = givens,
        has_qty = False
        )
        print(num_people_returned)
        if num_people_returned:
	    answer_to_be_returned = ['There '+ sing_plurize_is(num_people_returned) +str(num_people_returned)+' ' + sing_plurize(givens[0][0]['value'],num_people_returned)]
	else:
	    answer_to_be_returned = ['There is no '+givens[0][0]['value']]

    if count_list == to_count_list({'age': 1}):
        #question = 'how many children are in the crowd'
        #question = 'tell me the number of elders in the crowd'
        givens = [get_givens(s, tokens, 'age')]
        print 'count_people_given_age'
        num_people_returned = count_entities(
        olp = olp['people'],
        givens = givens,
        has_qty = False
        )
        print(num_people_returned)
        if num_people_returned:
	    answer_to_be_returned = ['There '+ sing_plurize_is(num_people_returned) +str(num_people_returned)+' ' + sing_plurize(givens[0][0]['value'],num_people_returned)]
	else:
	    answer_to_be_returned = ['There is no '+givens[0][0]['value']]

    if count_list == to_count_list({'color': 1}):
        #question = 'tell me how many people were wearing blue'
        givens = [get_givens(s, tokens, 'color')]
	givens[0][0]['attribute'] = 'ucolor'
        print 'count_people_given_color'
        num_people_returned = count_entities(
        olp = olp['people'],
        givens = givens,
        has_qty = False
        )
        print(num_people_returned)
        if num_people_returned:
	    answer_to_be_returned = ['There ' + sing_plurize_is(num_people_returned) + str(num_people_returned)+' ' +sing_plurize_pp(num_people_returned) +'wearing ' + givens[0][0]['value']]
	else:
	    answer_to_be_returned = ['There is no person wearing '+givens[0][0]['value']]

    if count_list == to_count_list({'gender': 1, 'operator': 1}) or count_list == to_count_list({'gender': 2, 'operator': 1}):
        # 'Am I a man or a woman?'
        # givens = 'I'
        print 'get_gender_given_op'
        gender_returned = get(
        olp = olp['op'],
        name_attribute = 'gender')
        print(gender_returned)
        answer_to_be_returned = ['You are a ' + gender_returned[0]]

    if count_list == to_count_list({'age': 1, 'operator': 1}):
        '''
        question = 'how old do you think i am'
        process_question(question, olp, '')
        '''
        print 'get_age_given_op'
        answer_to_be_returned = ['GET_AGE'] #get age in scenario code

    if count_list == to_count_list({'gesture': 1, 'gender': 1}) or count_list == to_count_list({'gesture': 1, 'gender': 2}):
        #question = 'was the standing person boy or girl?'
        givens = [get_givens(s, tokens, 'gesture')]
        print 'get_gender_given_gesture'
        gender_returned = get(
        olp = olp['people'],
        name_attribute = 'gender',
        givens = givens
        )
        print(gender_returned)
        answer_to_be_returned = ['The '+givens[0][0]['value'] + ' person was a ' + gender_returned[0] ]

    if count_list == to_count_list({'gesture': 1, 'gender': 1, 'age': 1}):
	#??/ i think it's not used
        givens = [get_givens(s, tokens, 'gesture')]
        print 'get_gender_age_given_gesture'
        gender_returned = get(
        olp = olp['people'],
        name_attribute = 'gender',
        givens = givens
        )
        age_returned = get(
        olp = olp['people'],
        name_attribute = 'age',
        givens = givens
        )
        print(gender_returned)
        print(age_returned)
	#TODO
        answer_to_be_returned = gender_returned # disregard age

    #predefined
    if 'time' in s:
        print 'get_time'
        answer_to_be_returned = 'get_time'
        now = datetime.datetime.now()
        answer_to_be_returned = now.strftime("%H %M")

    if 'today' in s:
        print 'get_today'
        answer_to_be_returned = 'get_today'
        now = datetime.datetime.now()
        answer_to_be_returned = now.strftime("%B %d %Y")

    if 'last' in s:
        print 'get_last_question'
        answer_to_be_returned = question_prev

    if 'computer' in s or 'bug' in s:
        print 'get_predefined_1'
        answer_to_be_returned = 'From a moth trapped in a relay'

    if 'compiler' in s:
        print 'get_predefined_2'
        # print('<NAME> invented it')
        answer_to_be_returned = '<NAME> invented it'

    if 'b' in tokens or 'B' in tokens or 'bee' in tokens:
        print 'get_predefined_3'
        answer_to_be_returned = 'B was developed circa 1969 at Bell Labs'

    if 'lives' not in s and 'who' in s and ('c' in tokens or 'see' in s or 'sea' in s):
        print 'get_predefined_4'
        answer_to_be_returned = '<NAME> and <NAME>'

    if 'when' in s and ('c' in tokens or 'see' in s or 'sea' in s):
        print 'get_predefined_5'
        # print('C was developed after B in 1972 at Bell Labs')
        answer_to_be_returned = 'C was developed after B in 1972 at Bell Labs'

    if ('highest' in s or 'mountain' in s) and 'japan' in s:
        print 'get_predefined_6'
        # print('The highest point in Japan is Mount Fuji, which reaches 3776m above sea level')
        answer_to_be_returned = 'The highest point in Japan is Mount Fuji, which reaches 3776m above sea level'

    if 'capital' in s:
        print 'get_predefined_7'
        answer_to_be_returned = 'The capical of Canada is Ottawa'

    if 'origin' in s and 'canada' in s:
      answer_to_be_returned = 'The name Canada comes from the Iroquois word Kanata, meaning village or settlement.'

    if 'national' in s and 'canada' in s:
      answer_to_be_returned = 'O Canada'


    # if 'people' in s and 'japan' in s:
    #     print 'get_predefined_8'
    #     print('A little over 80 million')
    #     answer_to_be_returned = 'A little over 80 million'
    #
    # if 'flag' in s:
    #     print 'get_predefined_9'
    #     print('Japanese flag is a red circle centred over white')
    #     answer_to_be_returned = 'Japanese flag is a red circle centred over white'
    #
    # if 'emperor' in s:
    #     print 'get_predefined_10'
    #     print('His Majesty Akihito sama is the emperor in Japan since January 7, 1989')
    #     answer_to_be_returned = 'His Majesty Akihito sama is the emperor in Japan since January 7, 1989'

    if ('robocup' in s or 'robocop' in s) and 'city' in s and 'next year' in s:
        print 'get_predefined_11'
        # print("It hasn't been announced yet.")
        answer_to_be_returned = "It hasn't been announced yet."

    if ('robocup' in s or 'robocop' in s) and 'which year' in s:
        print 'get_predefined_12'
        # print('The first official RoboCup games and conference was held in 1997')
        answer_to_be_returned = 'The first official RoboCup games and conference was held in 1997'

    if 'open' in s:
        print 'get_predefined_13'
        answer_to_be_returned = 'There is no standard defined for OPL'

    if 'social standard' in s:
        print 'get_predefined_14'
        answer_to_be_returned = 'The SoftBank Robotics Pepper'

    if 'domestic standard' in s:
        print 'get_predefined_15'
        answer_to_be_returned = 'The Toyota Human Support Robot'

    if 'dreams' in s:
        print 'get_predefined_16'
        answer_to_be_returned = 'I dream of Electric Sheep.'

    if 'your name' in s:
        print 'get_predefined_17'
        # print('My name is Pepper.')
        answer_to_be_returned = 'My name is HSR.'

    if 'name' in s and 'team' in s:
        print 'get_predefined_18'
        # print('Our team name is Aupair.')
        answer_to_be_returned = 'Our team name is Team PNU.'

    # if 'sakura' in s or 'Sakura' in s:
    #     print 'get_predefined_19'
    #     print('Sakura is the Japanese term for ornamental cherry blossom and its tree.')
    #     answer_to_be_returned = 'Sakura is the Japanese term for ornamental cherry blossom and its tree.'

    if ('city' in s or 'cities' in s) and 'next' not in s and 'capital' not in s:
        print 'get_predefined_20'
        answer_to_be_returned = 'Montreal.'

    if  'year' in s and ('participate' in s or 'participates' in s or 'years' in s):
        print 'get_predefined_21'
        print('32.')
        answer_to_be_returned = '32.'

    # if 'popular' in s or 'vote' in s or 'election' in s:
    #     print 'get_predefined_22'
    #     print('<NAME>')
    #     answer_to_be_returned = '<NAME>.'
    '''
    if 'standard' in s or 'platforms' in s or 'platform' in s:
        print 'get_predefined_23'
        print('Pepper and HSR.')
        answer_to_be_returned = 'Pepper and HSR.'
    '''
    if 'dspl' in s:
        print 'get_predefined_24'
        print('Domestic Standard Platform League.')
        answer_to_be_returned = 'Domestic Standard Platform League.'

    if 'sspl' in s:
        print 'get_predefined_25'
        print('Social Standard Platform League.')
        answer_to_be_returned = 'Social Standard Platform League.'

    if 'alphabet' in s or 'sell' in s or 'boston' in s or 'dynamics' in s or 'dynamics' in s:
        print 'get_predefined_26'
        print('SoftBank.')
        answer_to_be_returned = 'SoftBank.'

    if 'nagoya' in s or 'train' in s or 'stations' in s or 'station' in s or 'world' in s:
        print 'get_predefined_27'
        print('over 410000 square metres.')
        answer_to_be_returned = 'over 410000 square metres.'

    if 'team' in s and 'home' in s:
        print 'get_predefined_28'
        print('Seoul.')
        answer_to_be_returned = 'Seoul.'

    if 'created' in s or 'star' in s or 'wars' in s or 'war' in s:
        print 'get_predefined_29'
        print('<NAME>.')
        answer_to_be_returned = '<NAME>.'

    if ('lives' in s or 'live' in s) and 'sea' in s :
        print 'get_predefined_30'
        print('<NAME> Squarepants!')
        answer_to_be_returned = 'Sp<NAME> Squarepants!'

    if ('grace' in s or 'hopper' in s) and 'invent' in s:
        print 'get_predefined_31'
        print('the inventor of the first compiler.')
        answer_to_be_returned = 'the inventor of the first compiler.'

    print str(answer_to_be_returned)

    if type(answer_to_be_returned) is list:
        n_elem = len(answer_to_be_returned)
        if n_elem == 0:
            answer_to_be_returned = 'nothing'
        elif n_elem == 1:
            answer_to_be_returned = str(answer_to_be_returned[0])
        else:
            answer_to_be_returned = answer_to_be_returned[:-1] +  ['and'] + answer_to_be_returned[-1:]
            answer_to_be_returned = " ".join([str(a) for a in answer_to_be_returned])

    return ('the answer is ' + str(answer_to_be_returned)) if (str(answer_to_be_returned) != "I'm sorry. I couldn't understand your intention.") else str(answer_to_be_returned)






people = [{'gender': 'man',
             'lcolor': '',
             'gesture': ['pointing left'],
             'ucolor': 'black',
	            'age': 'child' },

             {'gender': 'man',
             'lcolor': '',
             'gesture': ['rising left arm', 'rising right arm'],
             'ucolor': 'blue',
	            'age': 'adult' },

             {'gender': 'woman',
             'lcolor': '',
             'gesture': ['standing'],
             'ucolor': 'blue',
	            'age': 'elder' }]

op =  [{'gender': 'man',
        'lcolor': '',
        'gesture': ['standing'],
        'ucolor': 'black',
	'age': 'adult'}]

olp = {'objects': objects,'locations':locations, 'people': people, 'op': op}
q_prev = ''



pub_answer=rospy.Publisher('/pnu/answer',String,queue_size=2)


# def process_question(question, olp, question_prev):
#     return nogada(question.lower(), olp, question_prev)


question_prev=""

def question_callback(data):
  global question_prev
  question=data.data
  str=nogada(question.lower(), olp, question_prev)
  question_prev=question.lower()
  msg=String()
  msg.data=str
  pub_answer.publish(msg)


rospy.init_node('spragent')
rospy.Subscriber("/pnu/question", String, question_callback)
rospy.spin()


#
# def main():
#
#     # locations, objects = import_csv()
#     print '-----------------------'
#     print people
#     print '-----------------------'
#
#
#
#     prev_example="none"
#     #for example in spr_examples1:
#     #for example in spr_examples_pr_2018:
#     for example in spr_examples2:
#         print '-' * 50
#         print example
#         process_question(example, {'objects': objects, 'locations': locations, 'people': people, 'op': op}, prev_example)
#         prev_example=example
#
# if __name__ == '__main__':
#     main()

#!/usr/bin/env python # coding: utf-8 #nltk.download('punkt') # Computer # Japan # Robocup # Nonsense # Team # Additional function required # Arena #placement, beacon ? # Object # Crowd #1. Arena #2. Object #NOT arguments in get(), count_entities(), compare_pair_nominal(), compare_pair_ordinal(), compare_set()  olp: one of objects, locations, or people (all of them are a list of dictionaries)  name_attribute: the name of an attribute of entities     e.g., 'object'     # compare_objs_in_weight_given_cat     # Which is the lightest drinks? pair_attribute_values: a pair of attribute values of entities     e.g., ('bowl', 'apple')     # Do the bowl and apple belong to the same category?  givens: a (nested) list of dictionaries     # {‘attribute’: ‘an_attribute’, ‘value’: ‘a_value’} of conditions     # cf. [[a,b], [c, d]] = (a and b) or (c and d) = ab + cd     # e.g., {‘attribute’: ‘category’, ‘value’: ‘snack’}     e.g., {'attribute': 'gender', 'value': 'man'}     e.g., {'attribute': 'object', 'value': 'sink'}     # [[{'attribute': 'object', 'value': 'sink'}]]  has_qty: True if an element in an array has the quantity attribute     objects have the quantity attribute     locations and people do not have the quantity attribute  in_terms: an attribute in terms of which instances are compared     e.g.,'category', 'size', 'weight'     # compare_obj1_obj2_in_cat     # Do the bowl and apple belong to the same category? # returns the set of attribute values (no duplicates) of an attribute named name_attribute given givens # https://stackoverflow.com/questions/3013449/list-filtering-list-comprehension-vs-lambda-filter # givens = [[{'attribute': 'object', 'value': 'pringles'}]] # get(objects, 'category', givens) #JUST RETURN 25 (?) # returns the number of entities (allowing duplicates) given givens by multiplying the quantities if has_qty is True # givens = [ #     [{'attribute': 'location', 'value': 'shelf'}, {'attribute': 'room', 'value': 'living room'}], #     [{'attribute': 'location', 'value': 'fridge'}, {'attribute': 'room', 'value': 'kitchen'}] # ] # givens = [ #     [{'attribute': 'ucolor', 'value': 'gray'}, {'attribute': 'gesture', 'value': 'sitting'}], #     [{'attribute': 'ucolor', 'value': 'red'}, {'attribute': 'gesture', 'value': 'pointing left'}], #     [{'attribute': 'ucolor', 'value': 'red'}] # ] # props to be ORed # prop to be ANDed # objects, ('bowl', 'apple'), 'category' # objects, ('pringles', 'peanuts'), 'category' # objects, ('chocolate bar', 'chocolate egg'), 'category' # (bowl, apple) # TODO: make it general (future) # returns True if they are the same # or returns False if they are different # inputs: objects, ('plate', 'coke'), 'size', 'smaller' # returns the list of entities preferable in terms of in_terms given givens # comparing_word: 'smaller', 'larger', 'bigger', 'lighter', 'heavier' # size: 'small', 'medium', 'large' # weight: 'light', 'medium', 'heavy' # TODO: make it general (future) # compare with plural object values # compare with plural object values # no such object, so unknown # givens to olp_conditioned # props to be ORed # prop to be ANDed #indexes of num in list_num #indexes of min value #indexes of max value # https://stackoverflow.com/questions/2474015/getting-the-index-of-the-returned-max-or-min-item-using-max-min-on-a-list # https://stackoverflow.com/questions/5419204/index-of-duplicates-items-in-a-python-list # https://stackoverflow.com/questions/18272160/access-multiple-elements-of-list-knowing-their-index # returns the list of entities preferable in terms of in_terms given givens # [Procedures] # choose entities given givens (givens) # change qualitative words to numbers (in_terms) # choose entities least or greatest according to comparing_word (comparing_word) # return the set of attribute values of those entities # (Choose entities given givens) #print(olp_in_terms) # shelves # children # pringles, males, sponges, plates, bedsides, flakes # candies, toiletries # men, women # singularize or plurize word or is according to num # If-elses for every question type # homophones # question = 'where is located the sink?' #question = 'how many shelves are in the living room?' # 'how many chairs are in the dining room?' # 'how many chairs are in the dining table?' #question = 'to which category belong the chips?' #question = 'do the bowl and apple belong to the same category?' # Not used #'how many drinks there are?' ####LALA #question = 'where can I find a chips?' #question = 'What objects are in the shelf?' #question = "what's the colour of the chocolate bar?" #question = 'between the plate and coke, which one is smaller?' #question = 'between the chocolate bar and cloth, which one is lighter?' #question = 'how many food are in the dining table?' #question = 'which is the biggest food?' # 'size' From here, edit examples #question = 'Which is the heaviest food?' # 'weight' question = 'how many chairs are in the dining room?'             process_question(question, olp, '') #question = 'how many people in the crowd are rising right arm?' #question = 'how many people in the crowd are standing or sitting?' #question = 'tell me the number of males in the crowd' #question = 'how many children are in the crowd' #question = 'tell me the number of elders in the crowd' #question = 'tell me how many people were wearing blue' # 'Am I a man or a woman?' # givens = 'I' question = 'how old do you think i am'         process_question(question, olp, '') #get age in scenario code #question = 'was the standing person boy or girl?' #??/ i think it's not used #TODO # disregard age #predefined # print('<NAME> invented it') # print('C was developed after B in 1972 at Bell Labs') # print('The highest point in Japan is Mount Fuji, which reaches 3776m above sea level') # if 'people' in s and 'japan' in s: #     print 'get_predefined_8' #     print('A little over 80 million') #     answer_to_be_returned = 'A little over 80 million' # # if 'flag' in s: #     print 'get_predefined_9' #     print('Japanese flag is a red circle centred over white') #     answer_to_be_returned = 'Japanese flag is a red circle centred over white' # # if 'emperor' in s: #     print 'get_predefined_10' #     print('His Majesty Akihito sama is the emperor in Japan since January 7, 1989') #     answer_to_be_returned = 'His Majesty Akihito sama is the emperor in Japan since January 7, 1989' # print("It hasn't been announced yet.") # print('The first official RoboCup games and conference was held in 1997') # print('My name is Pepper.') # print('Our team name is Aupair.') # if 'sakura' in s or 'Sakura' in s: #     print 'get_predefined_19' #     print('Sakura is the Japanese term for ornamental cherry blossom and its tree.') #     answer_to_be_returned = 'Sakura is the Japanese term for ornamental cherry blossom and its tree.' # if 'popular' in s or 'vote' in s or 'election' in s: #     print 'get_predefined_22' #     print('<NAME>') #     answer_to_be_returned = '<NAME>.' if 'standard' in s or 'platforms' in s or 'platform' in s:         print 'get_predefined_23'         print('Pepper and HSR.')         answer_to_be_returned = 'Pepper and HSR.' # def process_question(question, olp, question_prev): #     return nogada(question.lower(), olp, question_prev) # # def main(): # #     # locations, objects = import_csv() #     print '-----------------------' #     print people #     print '-----------------------' # # # #     prev_example="none" #     #for example in spr_examples1: #     #for example in spr_examples_pr_2018: #     for example in spr_examples2: #         print '-' * 50 #         print example #         process_question(example, {'objects': objects, 'locations': locations, 'people': people, 'op': op}, prev_example) #         prev_example=example # # if __name__ == '__main__': #     main()