in data/question-gen/engine.py [0:0]
def queryLogical(self, ent):
qns = []
rooms_done = set()
# the entities queue contains a list of object entities
for i in ent['elements']:
# ignore objects with (1) multiple and (2) no room names
if len(i.rooms[0].name) > 1:
if self.debug == True:
print(
'exception in queryLogical. room has multiple names.',
i.rooms[0].name)
continue
elif i.rooms[0].name == []:
if self.debug == True:
print('exception in queryLogical. room has no name.',
i.name, i.rooms[0].name)
continue
if i.rooms[0].name[0] in rooms_done: continue
# get list of all objects present in the same as room as the current object
# note that as we iterate throgh the ent queue, all the objects in the same room
# will generate identical list -- so we save the rooms processed in the room_done set
# For example : if the first obj is a bed inside a bedroom, and this bedroom has
# a total of 5 objects= : ['chair', 'bed', 'chair', 'dressing_table', 'curtains']
# Then, whenever any of these objects is encountered in the loop (for i in ent['elements'])
# we will end up generating the same list as shown
local_list = [(x, x.name) for x in ent['elements']
if len(x.rooms[0].name) == 1
and x.rooms[0].name[0] == i.rooms[0].name[0]]
local_objects_list_ = [obj for (obj, _) in local_list]
local_object_names_list = [name for (_, name) in local_list]
# get list of objects which are not present in the room where i resides.
# this list is also pruned based on frequency
# again, this list will be identical for all objects in the same room
objs_not_present = [
x[0] for x in self.global_obj_by_room[i.rooms[0].name[0]]
if x[0] not in local_object_names_list
]
both_present, both_absent, only_one_present = [], [], []
# print ("Room : %s" % i.rooms[0].name)
# populate objects for yes answer questions
for i_idx in range(len(local_object_names_list)):
for j_idx in range(i_idx + 1, len(local_object_names_list)):
if local_object_names_list[
i_idx] == local_object_names_list[j_idx]:
continue
both_present.append((local_object_names_list[i_idx],
local_object_names_list[j_idx]))
# populate objects for no answer questions -- part 1
for i_idx in range(len(objs_not_present)):
for j_idx in range(i_idx + 1, len(objs_not_present)):
if objs_not_present[i_idx] == objs_not_present[j_idx]:
continue
both_absent.append((objs_not_present[i_idx],
objs_not_present[j_idx]))
# populate objects for no answer questions -- part 2
for obj1 in local_object_names_list:
for obj2 in objs_not_present:
only_one_present.append((obj1, obj2))
# generate a question for each object pairs in the 3 lists
shuffle(both_present)
shuffle(both_absent)
shuffle(only_one_present)
num_yes = num_no = len(both_present)
only_one_present, both_absent = only_one_present[:int(
num_no - num_no / 2)], both_absent[:int(num_no / 2)]
for (obj1, obj2) in both_present:
obj1_entity, obj2_entity = objectEntity(obj1, {},
{}), objectEntity(
obj2, {}, {})
obj1_entity.rooms.append(i.rooms[0])
qns.append(
self.q_obj_builder('exist_logic',
[(obj1_entity, obj2_entity)], 'yes',
'exist_logical_positive'))
qns.append(
self.q_obj_builder('exist_logic',
[(obj1_entity, obj2_entity)], 'yes',
'exist_logical_or_positive_1'))
for (obj1, obj2) in both_absent:
obj1_entity, obj2_entity = objectEntity(obj1, {},
{}), objectEntity(
obj2, {}, {})
obj1_entity.rooms.append(
i.rooms[0]
) # this is not technically correct, just so that q_string_builder works
qns.append(
self.q_obj_builder('exist_logic',
[(obj1_entity, obj2_entity)], 'no',
'exist_logical_negative_1'))
qns.append(
self.q_obj_builder('exist_logic',
[(obj1_entity, obj2_entity)], 'no',
'exist_logical_or_negative'))
for (obj1, obj2) in only_one_present:
obj1_entity, obj2_entity = objectEntity(obj1, {},
{}), objectEntity(
obj2, {}, {})
obj1_entity.rooms.append(i.rooms[0])
qns.append(
self.q_obj_builder('exist_logic',
[(obj1_entity, obj2_entity)], 'no',
'exist_logical_negative_2'))
qns.append(
self.q_obj_builder('exist_logic',
[(obj1_entity, obj2_entity)], 'yes',
'exist_logical_or_positive_2'))
# mark room as done
rooms_done.add(i.rooms[0].name[0])
return qns