Skip to content

Commit

Permalink
Add content-desc view selector, fix typos
Browse files Browse the repository at this point in the history
  • Loading branch information
connglli committed Mar 15, 2021
1 parent eeefbd6 commit 1858210
Show file tree
Hide file tree
Showing 2 changed files with 42 additions and 24 deletions.
66 changes: 42 additions & 24 deletions droidbot/input_script.py
Original file line number Diff line number Diff line change
Expand Up @@ -105,7 +105,7 @@ def parse_main(self):
if isinstance(action[0], str):
self.main[state_selector] = RoundRobinDroidBotAction(action, self, state_key_tag)
else:
self.main[state_selector] = ProbalisticDroidBotAction(action, self, state_key_tag)
self.main[state_selector] = ProbabilisticDroidBotAction(action, self, state_key_tag)

def get_operation_based_on_state(self, state):
"""
Expand Down Expand Up @@ -187,7 +187,7 @@ def check_grammar_action_is_valid(value, state, key_tag):
@staticmethod
def check_grammar_prob_operation_is_valid(value, key_tag):
if not isinstance(value, dict):
msg = '%s: probalistic operation must be a dict' % key_tag
msg = '%s: probabilistic operation must be a dict' % key_tag
raise ScriptSyntaxError(msg)
for key in ['op_id', 'prob']:
DroidBotScript.check_grammar_has_key(value.keys(), key, key_tag)
Expand Down Expand Up @@ -258,6 +258,7 @@ class ViewSelector(object):
selector_grammar = {
'text': REGEX_VAL,
'resource_id': REGEX_VAL,
'content_desc': REGEX_VAL,
'class': REGEX_VAL,
'out_coordinates': [[INTEGER_VAL, INTEGER_VAL]],
'in_coordinates': [[INTEGER_VAL, INTEGER_VAL]]
Expand All @@ -270,6 +271,7 @@ def __init__(self, view_selector_id, selector_dict, script):
self.text_re = None
self.resource_id_re = None
self.class_re = None
self.content_desc_re = None
self.script = script
self.out_coordinates = []
self.in_coordinates = []
Expand All @@ -287,6 +289,8 @@ def parse(self):
self.text_re = re.compile(selector_value)
elif selector_key == 'resource_id':
self.resource_id_re = re.compile(selector_value)
elif selector_key == 'content_desc':
self.content_desc_re = re.compile(selector_value)
elif selector_key == 'class':
self.class_re = re.compile(selector_value)
elif selector_key == 'out_coordinates':
Expand All @@ -313,6 +317,8 @@ def match(self, view_dict):
return False
if self.resource_id_re and not safe_re_match(self.resource_id_re, view_dict['resource_id']):
return False
if self.content_desc_re and not safe_re_match(self.content_desc_re, view_dict['content_description']):
return False
if self.class_re and not safe_re_match(self.class_re, view_dict['class']):
return False
bounds = view_dict['bounds']
Expand Down Expand Up @@ -404,7 +410,7 @@ def match(self, device_state):
return True


class DroidBotAction():
class DroidBotAction:
"""
an action is what DroidBot would do on device at specific states
"""
Expand All @@ -418,11 +424,17 @@ class RoundRobinDroidBotAction(DroidBotAction):
this action execute its operations round-robin
"""
def __init__(self, action, script, key_tag):
self.action = action
self.script = script
self.key_tag = key_tag
self.operations = []
for operation_id in action:
script.check_grammar_identifier_is_valid(operation_id)
script.check_grammar_key_is_valid(operation_id, script.operations, key_tag)
operation = script.operations[operation_id]
self.parse()

def parse(self):
for operation_id in self.action:
self.script.check_grammar_identifier_is_valid(operation_id)
self.script.check_grammar_key_is_valid(operation_id, self.script.operations, self.key_tag)
operation = self.script.operations[operation_id]
self.operations.append(operation)

def get_next_operation(self):
Expand All @@ -434,20 +446,26 @@ def get_next_operation(self):
return operation


class ProbalisticDroidBotAction(DroidBotAction):
class ProbabilisticDroidBotAction(DroidBotAction):
"""
this action execute its operations probalistically according to the probability
this action execute its operations probabilistically according to the probability
"""
def __init__(self, action, script, key_tag):
prob_sum = 0
self.prob_operations = []
for prob_operation in action:
script.check_grammar_prob_operation_is_valid(prob_operation, key_tag)
script.check_grammar_identifier_is_valid(prob_operation['op_id'])
script.check_grammar_key_is_valid(prob_operation['op_id'], script.operations, key_tag)
self.action = action
self.script = script
self.key_tag = key_tag
self.parse()

def parse(self):
prob_sum = 0
for prob_operation in self.action:
self.script.check_grammar_prob_operation_is_valid(prob_operation, self.key_tag)
self.script.check_grammar_identifier_is_valid(prob_operation['op_id'])
self.script.check_grammar_key_is_valid(prob_operation['op_id'], self.script.operations, self.key_tag)
tmp_prob_sum = prob_sum + prob_operation['prob']
operation = {
'operation': script.operations[prob_operation['op_id']],
'operation': self.script.operations[prob_operation['op_id']],
'prob_range': [prob_sum, tmp_prob_sum]
}
self.prob_operations.append(operation)
Expand All @@ -459,8 +477,8 @@ def __init__(self, action, script, key_tag):
'operation': None,
'prob_range': [prob_sum, 1]
})
elif prob_sum - 1> 1e-5: # greater than 1
msg = '%s: sum of probability must <=1, %f is given' % (key_tag, prob_sum)
elif prob_sum - 1 > 1e-5: # greater than 1
msg = '%s: sum of probability must <=1, %f is given' % (self.key_tag, prob_sum)
raise ScriptSyntaxError(msg)

def get_next_operation(self):
Expand Down Expand Up @@ -498,7 +516,7 @@ def parse(self):
self.events.append(script_event)


class ScriptEvent():
class ScriptEvent:
"""
an event defined in DroidBotScript
the grammar of ScriptEvent is similar with the InputEvent in dict format
Expand Down Expand Up @@ -553,7 +571,7 @@ class MockObject:
def __init__(self, state_dict):
self.__dict__.update(state_dict)

script = DroidBotScript(json.load(open("script_samples/probalistic_script.json", "r")))
test_script = DroidBotScript(json.load(open("script_samples/probabilistic_script.json", "r")))
welcome_state = MockObject({
'views': [
{
Expand All @@ -578,15 +596,15 @@ def __init__(self, state_dict):
})
swipe, skip, none, total = 0, 0, 0, 10000
for i in range(total):
operation = script.get_operation_based_on_state(welcome_state)
if not operation:
test_operation = test_script.get_operation_based_on_state(welcome_state)
if not test_operation:
none += 1
print('None')
else:
print('%s: %s' % (operation.id, operation.events))
if operation.id == 'swipe_operation':
print('%s: %s' % (test_operation.id, test_operation.events))
if test_operation.id == 'swipe_operation':
swipe += 1
elif operation.id == 'skip_operation':
elif test_operation.id == 'skip_operation':
skip += 1
print('swipe_operation: %f/%f (%f)' % (swipe, total, swipe / total))
print('skip_operation: %f/%f (%f)' % (skip, total, skip / total))
Expand Down
File renamed without changes.

0 comments on commit 1858210

Please sign in to comment.