def random(self, user=None):
if not self.sorted:<EOL><INDENT>self._sort()<EOL><DEDENT>self._log.info('<STR_LIT>')<EOL>failed_conditions = []<EOL>passed_conditions = {}<EOL>successful_response = None<EOL>for priority, responses in self._responses.items():<EOL><INDENT>self._log.debug('<STR_LIT>'.format(priority=priority))<EOL>response_pool = []<EOL>for response in responses:<EOL><INDENT>condition = self._conditionals[response] if response in self._conditionals else None<EOL>if condition:<EOL><INDENT>if condition in failed_conditions:<EOL><INDENT>self._log.debug('<STR_LIT>')<EOL>continue<EOL><DEDENT>elif condition in passed_conditions:<EOL><INDENT>if response in passed_conditions[condition]:<EOL><INDENT>self._log.debug('<STR_LIT>')<EOL><DEDENT>else:<EOL><INDENT>self._log.debug('<STR_LIT>'<EOL>'<STR_LIT>')<EOL>continue<EOL><DEDENT><DEDENT>elif condition not in passed_conditions:<EOL><INDENT>self._log.debug('<STR_LIT>')<EOL>evaluated = condition.evaluate(user)<EOL>if not evaluated:<EOL><INDENT>self._log.debug('<STR_LIT>')<EOL>failed_conditions.append(condition)<EOL>continue<EOL><DEDENT>self._log.debug('<STR_LIT>'<EOL>'<STR_LIT>')<EOL>passed_conditions[condition] = evaluated<EOL>if response in passed_conditions[condition]:<EOL><INDENT>self._log.debug('<STR_LIT>')<EOL><DEDENT>else:<EOL><INDENT>self._log.debug('<STR_LIT>')<EOL>continue<EOL><DEDENT><DEDENT><DEDENT>if user and user.is_limited(response):<EOL><INDENT>if response.ulimit_blocking:<EOL><INDENT>self._log.debug('<STR_LIT>'<EOL>'<STR_LIT>'.format(uid=user.id))<EOL>raise LimitError<EOL><DEDENT>self._log.debug('<STR_LIT>'<EOL>'<STR_LIT>'.format(uid=user.id))<EOL>continue<EOL><DEDENT>if response.agentml.is_limited(response):<EOL><INDENT>if response.glimit_blocking:<EOL><INDENT>self._log.debug('<STR_LIT>'<EOL>'<STR_LIT>')<EOL>raise LimitError<EOL><DEDENT>self._log.debug('<STR_LIT>')<EOL>continue<EOL><DEDENT>self._log.debug('<STR_LIT>'<EOL>.format(weight=response.weight))<EOL>response_pool.append((response, response.weight))<EOL><DEDENT>if not response_pool:<EOL><INDENT>self._log.debug('<STR_LIT>'<EOL>'<STR_LIT>'.format(priority=priority))<EOL>continue<EOL><DEDENT>while True:<EOL><INDENT>response = weighted_choice(response_pool)<EOL>if not response:<EOL><INDENT>break<EOL><DEDENT>if response.chance is None or response.chance == <NUM_LIT:100>:<EOL><INDENT>successful_response = response<EOL>break<EOL><DEDENT>if response.chance >= random.uniform(<NUM_LIT:0>, <NUM_LIT:100>):<EOL><INDENT>self._log.info('<STR_LIT>'<EOL>.format(chance=response.chance))<EOL>successful_response = response<EOL>break<EOL><DEDENT>else:<EOL><INDENT>if response.chance_blocking:<EOL><INDENT>self._log.info('<STR_LIT>'<EOL>'<STR_LIT>'.format(chance=response.chance))<EOL>raise ChanceError<EOL><DEDENT>self._log.info('<STR_LIT>'<EOL>.format(chance=response.chance))<EOL>response_pool = [r for r in response_pool if r[<NUM_LIT:0>] is not response]<EOL>continue<EOL><DEDENT><DEDENT>if successful_response is None:<EOL><INDENT>self._log.debug('<STR_LIT>'<EOL>'<STR_LIT>'<EOL>.format(priority=priority))<EOL>continue<EOL><DEDENT>if user:<EOL><INDENT>successful_response.apply_reactions(user)<EOL><DEDENT>return successful_response<EOL><DEDENT>self._log.info('<STR_LIT>')<EOL>
Retrieve a random Response
:param user: The user to test for active limitations and to apply response actions on
:type  user: agentml.User or None

:return: A randomly selected Response object
:rtype : parser.trigger.response.Response