I have a set of objects of questions and answers and I need to return all possible combinations of each question and answer in a set of dictionaries. I am new to Python and have done some Google-ing but I don't think I know enough to even know how to search correctly.

Test has a one to many relationship to Question
Question has an id and string containing the actual question
Question has a one to many relationship to Answer
Answer has an id and string containing the actual Answer

So if there was two questions, first one with answers a and b, second with c and d,
the result set would be [{1:a,2:c},{1:a,2:d},{1:b,2:c},{1:b,2:d}]

Any help is greatly appreciated!

Recommended Answers

All 5 Replies

It appears to me that you have an incorrect understanding of your problem. As I see it:
each test has some questions (test has 1->N with question)
each question has some answers (question as 1->N with answer)

So: A question object has answers and a test object has questions. Like this:

class Answer:
  __init__(self,answer=None, index=None):
   if not answer:
     raise Exception("must provide answer")
   self.answer = answer
   if not index:
     index = getNextAnswerIndex() # def of getNextAnswerIndex is an exercise
   self.index = index

class Question:
  __init__(self, question=None, index=None, answers=None):
    if not question:
      raise Exception("must provide question")
    self.question = question
    if not index:
      index = getNextQuestionIndex() # def of getNextQuestionIndex is an exercise
    self.index = index
    self.answers = []
    if answers:
      self.answers.extend(answers)

class Test:
  __init__(self, questions=None)
    self.questions = []
    if questions:
      self.questions.extend(questions)

You will need to think about whether a list of lists is appropriate to the actual statement of the problem: Maybe you prefer to make a dictionary. This code snippet is just a sketch of how you might begin to think about it.

Does this make more sense as to what I'm trying to do?

class Test:
    '''
    Models a test composed of question and answer
   
    Each  question has a set of possible answers
    '''
    def __init__(self):
        '''
        Initialize the list of questions
        '''
        self.questions = []

       
class Question:
    '''
    Models a Question that is composed of a question and a set of possible answers
    '''
   
    def __init__(self):
        '''
        Initialize the id, question string and answers list
        '''
        self.id,self.question,self.answers=None,None,[]

       
class Answer:
    '''
    Models a possible answer to an intent question
   
    Corresponds with the XML "Answer" tag
    '''

    def __init__(self):
        '''
        Initialize the id and answers string
        '''
        self.id,self.answer=None,None

and once I build up an Object I want to be able to do this....

def process(test):
	'''
	Builds set of dictionaries of all question/answer paths in the form of a set of dictionaries

	test -- Contains all questions and answers
	'''
	#Take all possible combinations of questions and answers and return them in form [{}]

I'm working with a group so revamping the structure is not the best of options. Also, I apologize if I typed something completely wrong...I am a Python noob. Just started Monday.

The problem I had was with the phrase "all possible combinations of questions and answers" which made me think that question 2 might end up combined with an answer to question 1, for instance. I would have stated it a little differently, but your code makes the actual meaning clear (and matches what I thought the problem wanted). Comment: I would have made the process function a member function of the Test class.

I think the doc string for process may not be quite right: Sets are unordered but most tests have questions in a particular order. (Though if you are generating them on the fly, online for instance, you might want them in random order to help slow down the cheaters).


PS: Your code looks considerably past 'noobness' ...

I think you need only sequence, do not need explicit saved question numbers.

It is maybe worthwhile to check out the itertools module:
http://docs.python.org/library/itertools.html

def combinations(iterable, r):
    # combinations('ABCD', 2) --> AB AC AD BC BD CD
    # combinations(range(4), 3) --> 012 013 023 123
    pool = tuple(iterable)
    n = len(pool)
    if r > n:
        return
    indices = range(r)
    yield tuple(pool[i] for i in indices)
    while True:
        for i in reversed(range(r)):
            if indices[i] != i + n - r:
                break
        else:
            return
        indices[i] += 1
        for j in range(i+1, r):
            indices[j] = indices[j-1] + 1
        yield tuple(pool[i] for i in indices)

If you need numbers for questions do like this:

questions = ('q1','g2','q3','q4')
for qn,q in enumerate(questions):
    print ('%i: %s' % (qn+1,q)) ## numbers are zero based => +1

zip function would also be useful many times in this kind of program, check it out from Python documentation.

nested for loops?

questions = ("How are you?", "How old are you?")
answers = ("Good", "25")

for q in questions:
    for a in answers:
        print q, a

That should do it, but probably not that efficient

Be a part of the DaniWeb community

We're a friendly, industry-focused community of developers, IT pros, digital marketers, and technology enthusiasts meeting, networking, learning, and sharing knowledge.