<SYSTEM_TASK:>
Solve the following problem using Python, implementing the functions described below, one line at a time
<END_TASK>
<USER_TASK:>
Description:
 def _get_violations(self, query, record):
 """Reverse-engineer the query to figure out why a record was selected. :param query: MongoDB query :type query: MongQuery :param record: Record in question :type record: dict :return: Reasons why bad :rtype: list(ConstraintViolation) """

        # special case, when no constraints are given
        if len(query.all_clauses) == 0:
            return [NullConstraintViolation()]
        # normal case, check all the constraints
        reasons = []
        for clause in query.all_clauses:
            var_name = None
            key = clause.constraint.field.name
            op = clause.constraint.op
            fval = mongo_get(record, key)
            if fval is None:
                expected = clause.constraint.value
                reasons.append(ConstraintViolation(clause.constraint, 'missing', expected))
                continue
            if op.is_variable():
                # retrieve value for variable
                var_name = clause.constraint.value
                value = mongo_get(record, var_name, default=None)
                if value is None:
                    reasons.append(ConstraintViolation(clause.constraint, 'missing', var_name))
                    continue
                clause.constraint.value = value         # swap out value, temporarily
            # take length for size
            if op.is_size():
                if isinstance(fval, str) or not hasattr(fval, '__len__'):
                    reasons.append(ConstraintViolation(clause.constraint, type(fval), 'sequence'))
                    if op.is_variable():
                        clause.constraint.value = var_name      # put original value back
                    continue
                fval = len(fval)
            ok, expected = clause.constraint.passes(fval)
            if not ok:
                reasons.append(ConstraintViolation(clause.constraint, fval, expected))
            if op.is_variable():
                clause.constraint.value = var_name      # put original value back
        return reasons