<SYSTEM_TASK:>
Solve the following problem using Python, implementing the functions described below, one line at a time
<END_TASK>
<USER_TASK:>
Description:
 def chooseBestDuplicates(tped, samples, oldSamples, completion, concordance_all, prefix):
 """Choose the best duplicates according to the completion rate. :param tped: the ``tped`` containing the duplicated samples. :param samples: the updated position of the samples in the tped containing only duplicated samples. :param oldSamples: the original duplicated sample positions. :param completion: the completion of each of the duplicated samples. :param concordance_all: the concordance of every duplicated samples. :param prefix: the prefix of all the files. :type tped: :py:class:`numpy.array` :type samples: dict :type oldSamples: dict :type completion: :py:class:`numpy.array` :type concordance_all: dict :type prefix: str :returns: a tuple where the first element is a list of the chosen samples' indexes, the second on is the completion and the last one is the concordance (a map). These are the steps to find the best duplicated sample: 1. Sort the list of concordances. 2. Sort the list of completions. 3. Choose the best of the concordance and put in a set. 4. Choose the best of the completion and put it in a set. 5. Compute the intersection of the two sets. If there is one sample or more, then randomly choose one sample. 6. If the intersection doesn't contain at least one sample, redo steps 3 and 4, but increase the number of chosen best by one. Redo step 5 and 6 (if required). The chosen samples are written in ``prefix.chosen_samples.info``. The rest are written in ``prefix.excluded_samples.info``. """

    # The output files
    chosenFile = None
    try:
        chosenFile = open(prefix + ".chosen_samples.info", "w")
    except IOError:
        msg = "%(prefix)s.chosen_samples.info: can't write file" % locals()
        raise ProgramError(msg)
    print >>chosenFile, "\t".join(["origIndex", "dupIndex", "famID", "indID"])

    excludedFile = None
    try:
        excludedFile = open(prefix + ".excluded_samples.info", "w")
    except IOError:
        msg = "%(prefix)s.excluded_samples.info: can't write file" % locals()
        raise ProgramError(msg)
    print >>excludedFile, "\t".join(["origIndex", "dupIndex", "famID",
                                     "indID"])

    # For each duplicated sample
    chosenIndexes = {}
    sampleConcordance = {}
    for sample, indexes in samples.iteritems():
        # Getting the completion for those duplicated samples
        currCompletion = completion[indexes]

        # Sorting those completion
        sortedCompletionIndexes = np.argsort(currCompletion)

        # Getting the concordance
        concordance = concordance_all[sample]
        currConcordance = [[] for i in xrange(len(indexes))]
        for i in xrange(len(indexes)):
            indexToKeep = list(set(range(len(indexes))) - set([i]))
            currConcordance[i] = np.mean(concordance[i, indexToKeep])
        currConcordance = np.array(currConcordance)
        if sample not in sampleConcordance:
            sampleConcordance[sample] = currConcordance

        # Sorting the concordance
        sortedConcordanceIndexes = np.argsort(currConcordance)

        # Trying to find the best duplicate to keep
        nbToCheck = 1
        chosenIndex = None
        while nbToCheck <= len(indexes):
            # Getting the `nbToCheck` best value (higher to lower)
            completionValue = currCompletion[
                sortedCompletionIndexes[nbToCheck*-1]
            ]
            concordanceValue = currConcordance[
                sortedConcordanceIndexes[nbToCheck*-1]
            ]

            # Getting the indexes to consider
            completionToConsider = set(
                np.where(currCompletion >= completionValue)[0]
            )
            concordanceToConsider = set(
                np.where(currConcordance >= concordanceValue)[0])

            # Getting the intersection of the indexes
            toConsider = concordanceToConsider & completionToConsider
            if len(toConsider) >= 1:
                chosenIndex = random.choice(list(toConsider))
                break
            nbToCheck += 1

        if chosenIndex is None:
            msg = "Could not choose the best sample ID for {}".format(sample)
            raise ProgramError(msg)

        # Printing the chosen samples
        print >>chosenFile, "\t".join([str(oldSamples[sample][chosenIndex]+1),
                                       str(indexes[chosenIndex]+1), sample[0],
                                       sample[1]])

        # Printing the excluded samples
        for i, index in enumerate(indexes):
            if i != chosenIndex:
                print >>excludedFile, "\t".join([str(oldSamples[sample][i]+1),
                                                 str(index+1), sample[0],
                                                 sample[1]])

        chosenIndexes[sample] = indexes[chosenIndex]

    # Closing the output files
    chosenFile.close()
    excludedFile.close()

    return chosenIndexes, completion, sampleConcordance