This is what I came up with:
from collections import Counter
import random
# the number of question ids I need returned to
# assign to the exam
needed = 3
# the "pool" of possible question ids the user has access to
possible = [1,2,3,4,5]
# examples of lists of question ids I might see that represent
# questions a user has already answered
answered1 = []
answered2 = [1,3]
answered3 = [5,4,3,2]
answered4 = [5,4,3,2,1,1,2]
answered5 = [5,4,3,2,1,1,2,3,4,5,1]
answered6 = [5,4,3,2,1]
def getdiff(answered):
diff = set(possible) - set(answered)
still_needed = needed - len(diff)
if still_needed > 0:
not_already_selected = list(set(possible) - diff)
random.shuffle(not_already_selected)
diff = list(diff) + not_already_selected[0:still_needed]
random.shuffle(diff)
return diff
diff = list(diff)
random.shuffle(diff)
if still_needed == 0:
return diff
return diff[0:needed]
def workit(answered):
""" based on frequency, reduce the list down to only
those questions we want to consider "answered"
"""
have_count = 0
if len(possible) > len(answered):
return getdiff(answered)
counted = Counter(answered)
max_count = max(counted.values())
# the key here is to think of "answered" questions as
# only those that have been seen with max frequency
new_answered = []
for value, count in counted.iteritems():
if count == max_count:
new_answered.append(value)
return getdiff(new_answered)
print 1, workit(answered1)
print 2, workit(answered2)
print 3, workit(answered3)
print 4, workit(answered4)
print 5, workit(answered5)
print 6, workit(answered6)
"""
>>>
1 [2, 4, 3]
2 [2, 5, 4]
3 [5, 2, 1]
4 [5, 3, 4]
5 [2, 4, 3]
6 [2, 3, 5]
>>> ================================ RESTART ================================
>>>
1 [3, 1, 4]
2 [5, 2, 4]
3 [2, 4, 1]
4 [5, 4, 3]
5 [4, 5, 3]
6 [1, 5, 3]
>>> ================================ RESTART ================================
>>>
1 [1, 2, 3]
2 [4, 2, 5]
3 [4, 1, 5]
4 [5, 4, 3]
5 [2, 5, 4]
6 [2, 1, 4]
"""