import copy


def single_mutation_tuple_intSetRep(random, candidate, args):
    """Returns the mutant produced by a single mutation on the candidate (when the representation is a set of integers).
    The candidate size is maintained.

    Args:
        random  : the random number generator object
        candidate : the candidate solution
        args : a dictionary of keyword arguments

    Returns:
        Returns a  new candidate

    Notes:
        Optional keyword arguments in args:
        - *mutation_rate* -- the rate at which mutation is performed (default 0.1)
    """

    bounder = args["_ec"].bounder
    mutRate = args.setdefault("mutation_rate", 0.1)
    if random.random() > mutRate:
        return candidate
    mutant = copy.copy(candidate)
    r = random.random()
    indexTuple = 0 if r < 0.5 else 1  # choose if the mutation is done in the first or second int set.

    index = random.randint(0, len(mutant[indexTuple]) - 1) if len(mutant[indexTuple]) > 1 else 0
    newElem = random.randint(bounder.lower_bound[indexTuple], bounder.upper_bound[indexTuple])
    while newElem in mutant[indexTuple]:
        newElem = random.randint(bounder.lower_bound[indexTuple], bounder.upper_bound[indexTuple])
    mutantL = list(mutant[indexTuple])
    mutantL[index] = newElem

    if indexTuple == 0:
        mutant = (set(mutantL), mutant[1])
    else:
        mutant = (mutant[0], set(mutantL))
    return mutant