# -*- coding: utf-8 -*- from django.http import HttpResponse, Http404 from django.db.models import Q, Count from random import randint from models import * from forms import * from game import Game import myv_oahpa.settings try: DEFAULT_DIALECT = settings.DEFAULT_DIALECT except: DEFAULT_DIALECT = None class QAGame(Game): test = 0 def __init__(self, *args, **kwargs): self.generated_syntaxes = list() super(QAGame, self).__init__(*args, **kwargs) self.init_tags() def init_tags(self): """ Initialize the grammatical information. This information should be moved to parameters """ self.num_fields = 6 self.syntax =('MAINV','SUBJ','HAB') self.qtype_verbs = set(['V-COND','V-IMPRT','V-POT', 'PRS','PRT', 'V-PRS', 'V-PRT', 'V-GER', 'V-PRF']) # Default tense and mood for testing self.tense = "Prs" self.mood = "Ind" self.gametype = "morfa" # why morfa? it is "qa" # TODO: check this in smeoahpa, possible source of error. # Values for pairs QPN-APN # spørsmål: svar: # mun don # don mun # son son # # moai doai # doai moai # soai soai # # mii dii # dii mii # sii sii # # Noun Sg son # Noun Pl sii self.QAPN={ 'Sg':'Sg', # 'Pl':'Pl', # 'Sg1':'Sg2', # Mun? Don. 'Sg2':'Sg1', # Don? Mun. 'Sg3':'Sg3', # Son? Son. 'Du1':'Du2', # Moai? Doai. 'Du2':'Du1', # Doai? Moai. 'Du3':'Du3', # Soai? Soai. 'Pl1':'Pl2', # Mii? Dii. 'Pl2':'Pl1', # Dii? Mii. 'Pl3':'Pl3'} # Sii? Sii. # Values for subject-verb agreement: # e.g. Subject with N+Sg+Nom requires verb with Sg3. self.SVPN={'Sg1':'Sg1','Sg2':'Sg2','Sg3':'Sg3','Sg':'Sg3',\ 'Pl1':'Pl1','Pl2':'Pl2','Pl3':'Pl3','Pl':'Pl3',\ 'Du1':'Du1','Du2':'Du2','Du3':'Du3'} # Available values for Number self.PronPN=['Sg1','Sg2','Sg3','Pl1','Pl2','Pl3','Du1','Du2','Du3'] self.PronPNBase={'Sg1':'mun','Sg2':'don','Sg3':u'son',\ 'Pl1':'mii','Pl2':'dii','Pl3':'sii',\ 'Du1':'moai','Du2':'doai','Du3':'soai'} self.NounPN=['Sg','Pl'] self.NountoPronPN={'Sg':'Sg3','Pl':'Pl3'} def get_qword(self, qelement, tag_el): """ Note: attempting to reduce amount of queries run here, there are still some that are repeated, but these should reduced once we come along to testing numbers. """ if self.settings.has_key('dialect'): dialect = self.settings['dialect'] else: dialect = DEFAULT_DIALECT word=None if tag_el.pos=="Num" and self.settings.has_key('num_level') and str(self.settings['num_level'])=="1": smallnum = ["1","2","3","4","5","6","7","8","9","10"] word = Word.objects.filter(wordqelement__qelement=qelement, form__tag=tag_el.id) if word.count() > 0: word = word.order_by('?')[0] else: # Do not filter dialect here possible_words = Word.objects.filter(wordqelement__qelement=qelement, form__tag=tag_el.id) if possible_words.count() > 0: word = possible_words.order_by('?')[0] #print 'word', word form_set_filter = self.filter_forms_by_dialect( word.form_set.filter(tag=tag_el.id)) if word and form_set_filter.count()>0: form = form_set_filter[0] else: return None # TODO: better error handling here-- this needs to point out # that the DB is not installing properly, but I need to check # first that the code doesn't depend on returning None # sometimes. # Test by raising Form.DoesNotExist? word_id = word.id fullform = form.fullform info = { 'word' : word_id, 'tag' : tag_el.id, 'fullform' : [ fullform ], 'qelement' : qelement } return info # Select a word matching semtype and return full form. def get_words(self, qelement, tag_el=None, lemma=None, word_id=None): """ Select word from possible options in the element. """ words = [] # If there are no information available for these elements, try to use other info. word = None form = None if lemma and tag_el: form_set = self.filter_forms_by_dialect(tag_el.form_set.all()) if qelement: if qelement.semtype: form_set = form_set.filter(word__semtype=qelement.semtype) form = form_set[0] else: if word_id and tag_el: ### word_set = Word.objects.filter(id=word_id) ### if qelement: ### if qelement.semtype: ### word_set.filter(semtype=qelement.semtype) ### word = word_set[0] word = Word.objects.get(id=word_id) # if qelement: # if qelement.semtype: # word_set.filter(semtype=qelement.semtype) # word = word_set[0] form_set = self.filter_forms_by_dialect(word.form_set.filter(tag=tag_el)) form = form_set[0] if form: fullform = form.fullform info = {'word': form.word.id, 'tag': tag_el.id, 'fullform': [ fullform ]} words.append(info) elif word: form_list = self.filter_forms_by_dialect(word.form_set.all()) if tag_el: form_list = form_list.filter(tag=tag_el) # We do not want to filter by dialect here, because we want # all forms to be accepted regardless of dialect if not form_list: if self.test: raise Http404(qelement.id + " " + tag_el.id + " " + word.id) return [] fullform = form_list[0].fullform info = {'word': word.id, 'tag' : tag_el.id, 'fullform' : [ fullform ] } words.append(info) else: if self.test: raise Http404("not word " + str(qelement.id)) return [] return words def get_elements(self, question_element, identifier): elements = QElement.objects.filter(question=question_element, identifier=identifier) if elements.count() > 0: return elements else: return None def generate_question(self, question, qtype): """ Generate question for the form. Only one question is generated. """ qtext=question.string #print "QUESTION " + str(question.id) + " " + qtext qwords = {} # Find out syntax elements qwords_list=[] for w in qtext.split(): if w== "": continue qwords_list.append(w) # Handle all grammatical elements one at the time # 1. SUBJ-MAINV argreement #if self.test: raise Http404(question.id,qwords_list) # print qwords_list if 'SUBJ' in set(qwords_list): qwords['SUBJ'] = {} # Select randomly an element, if there are more than one available. # This way there is only one subject and tag for each question. subj_elements=self.get_elements(question, 'SUBJ') if not subj_elements: return None subj_el = subj_elements[randint(0, len(subj_elements)-1)] tag_el_count = subj_el.tags.count() # If there was no tag elements, there is nothing to do. # Subject tag is needed for everything else. if tag_el_count == 0: if self.test: raise Http404("0 tag count" + " " + qwords_list) return None tag_el = subj_el.tags.all()[randint(0, tag_el_count-1)] # Get number information for subject subjword = {} if tag_el.pos == "Pron": # NOTE: mii is interrogative and mii is personal # filtering by 'pronbase' isn't enough here. subjnumber = tag_el.personnumber if not subjnumber: raise Http404("Tag Element missing personnumber. Database may be improperly installed for tags.") pronbase = self.PronPNBase[subjnumber] word_el = Word.objects.filter(lemma=pronbase, form__tag=tag_el)[0] words_ = self.get_words(None, tag_el, None, word_el.id) try: info = words_[0] except IndexError: info = False # print subjnumber # print pronbase # print word_el # print info # print '--' else: subjnumber = tag_el.number info = self.get_qword(subj_el, tag_el) if not info: if self.test: raise Http404("not info " + " ".join(qwords_list)) return None subjword = info subjword['number'] = subjnumber qwords['SUBJ'] = subjword # print qwords['SUBJ'] if 'HAB' in set(qwords_list): qwords['HAB'] = {} # Select randomly an element, if there are more than one available. # This way there is only one habect and tag for each question. hab_elements = self.get_elements(question, 'HAB') if not hab_elements: return None hab_el = hab_elements[randint(0, len(hab_elements)-1)] tag_el_count = hab_el.tags.count() # If there was no tag elements, there is nothing to do. # Subject tag is needed for everything else. if tag_el_count == 0: if self.test: raise Http404("0 tag count" + " " + qwords_list) return None tag_el = hab_el.tags.all()[randint(0, tag_el_count-1)] # Get number information for habect habword = {} if tag_el.pos == "Pron": habnumber = tag_el.personnumber pronbase = self.PronPNBase[habnumber] word_el = Word.objects.filter(lemma=pronbase)[0] words_ = self.get_words(None, tag_el, None, word_el.id) try: info = words_[0] except IndexError: info = False # print habnumber # print pronbase # print word_el # print info # print '--' else: habnumber = tag_el.number info = self.get_qword(hab_el, tag_el) if not info: if self.test: raise Http404("not info " + " ".join(qwords_list)) return None habword = info habword['number'] = habnumber qwords['HAB'] = habword # print qwords['SUBJ'] if 'MAINV' in set(qwords_list): qwords['MAINV'] = {} mainv_word = None # Select one mainverb element for question. mainv_elements = self.get_elements(question,'MAINV') if mainv_elements: mainv_el = mainv_elements[randint(0, len(mainv_elements)-1)] # If there is only on tag element, then there are no choices for agreement. tag_el_count = mainv_el.tags.count() if tag_el_count == 1: tag_el=mainv_el.tags.all()[0] else: # Subject-verb agreement if qwords.has_key('SUBJ') and qwords['SUBJ'].has_key('number'): subjnumber=qwords['SUBJ']['number'] v_number = self.SVPN[subjnumber] if qtype in self.qtype_verbs or self.gametype=="qa": mainv_tags = mainv_el.tags.filter(Q(personnumber=v_number)) else: mainv_tags = mainv_el.tags.filter(Q(personnumber=v_number) & \ Q(tense=self.tense) & \ Q(mood=self.mood)) # If there is no subject element # then select random tag from all tags. else: mainv_tag_count = mainv_el.tags.count() mainv_tags = mainv_el.tags.all() if not mainv_tags: if self.test: raise Http404("not mainv_tags " + " ".join(qwords_list) + " " + question.qid) return None tag_el = mainv_tags[randint(0, mainv_tags.count()-1)] # Select random mainverb info = self.get_qword(mainv_el, tag_el) mainv_word = info if not mainv_word: if self.test: raise Http404("not mainv_word " + " ".join(qwords_list) + " " + question.qid) return None else: mainv_word['number'] = tag_el.personnumber qwords['MAINV'] = mainv_word if not mainv_word: if self.test: raise Http404("not mainv" + " " + " ".join(qwords_list)) return None # 2. Other grammatical elements # At the moment, agreement is not taken into account for s in qwords_list: if s in set(self.syntax): continue tag_el=None word = {} anumber = "" elements = self.get_elements(question,s) if elements: element = elements[randint(0, len(elements)-1)] copy_id=element.copy_id if copy_id: copy = QElement.objects.filter(id=copy_id)[0] copy_syntax = copy.syntax if qwords.has_key(copy_syntax): word = qwords[copy_syntax] if element.agreement: agr_id = element.agreement_id agr_el = QElement.objects.get(id=agr_id) agr_syntax = agr_el.identifier if qwords.has_key(agr_syntax): qword = qwords[agr_syntax] if qword.has_key('tag'): agr_tag_id = qword['tag'] agr_tag = Tag.objects.get(id=agr_tag_id) if agr_tag.personnumber: anumber = agr_tag.personnumber else: anumber = agr_tag.number _tag_query = Q(personnumber=anumber) | Q(number=anumber) tags = element.tags.filter(_tag_query) if tags.count() > 0: tag_el = choice(tags) if not tag_el: tag_el_count = element.tags.count() if tag_el_count > 0: tag_el = element.tags.order_by('?')[0] if tag_el: # Select random word info = self.get_qword(element, tag_el) word = info else: word = {} info = {'fullform' : [ s ] } word = info if not word: if self.test: raise Http404("not word " + "".join(qwords_list)) return None qwords[s] = word # Return the ready qwords list. return qwords def filter_forms_by_dialect(self, form_set): """ Filters forms by the current session dialect. Commented out for myv ATM. """ #dialect = 'main' #if self.settings.has_key('dialect'): # dialect = self.settings['dialect'] #else: # dialect = DEFAULT_DIALECT #excl = form_set.exclude(dialects__dialect='NG') #if excl.count() > 0: # form_set = excl #dialect_forms = form_set.filter(dialects__dialect=dialect) #if dialect_forms.count() > 0: # form_set = dialect_forms return form_set def select_reciprocative_forms(self, answer, awords, target): """ Follows user selection of reciprocative type and returns the relevant wordform. """ wordform_type = self.settings['wordform_type'] if not wordform_type: wordform_type = 'goabbat' _recipr_qelement = answer.qelement_set.get(identifier=target) _recipr_tag = _recipr_qelement.tags.all().order_by('?')[0] if target == 'P-REC': # P-REC needs to search by word stem, which should be set # to guoibmi or nubb if wordform_type == 'goabbat': stem_type = 'guoibmi' else: stem_type = 'nubbi' _recipr_forms = _recipr_tag.form_set.filter(word__stem=stem_type) else: _recipr_forms = _recipr_tag.form_set.filter(word__lemma=wordform_type) _recipr_word = _recipr_forms[0].word _recipr_fullforms = [a.fullform for a in _recipr_forms] awords[target] = [{ 'tag': _recipr_tag.id, 'word': _recipr_word.id, 'fullform': _recipr_fullforms, }] return awords def generate_answers_reflexive(self, answer, question, awords, qwords): """ Checks reflexive agreement on RPRON with a specified agreement element, returns awords. If agreement isn't specified, default behavior is MAINV. Task element should be specified like this to get RPRON agreement from MAINV. """ # Get corresponding RPRON tag _refl_qelement = answer.qelement_set.get(identifier='RPRON') try: _refl_agreement_head = _refl_qelement.agreement.identifier except AttributeError: _refl_agreement_head = 'MAINV' # Find agreement head's person (MAINV) _head = choice(awords[_refl_agreement_head]) _head_tag = Tag.objects.get(id=_head['tag']) _head_person = _head_tag.personnumber # Get agreeing tag _refl_person = 'Px%s' % _head_person _refl_tag = _refl_qelement.tags.get(possessive=_refl_person) # Get RPRON forms, tags, word element _refl_forms = self.filter_forms_by_dialect(_refl_tag.form_set.all()) _refl_word = _refl_forms.order_by('?')[0].word _refl_fullforms = _refl_forms.values_list('fullform', flat=True) awords['RPRON'] = [{ 'tag': _refl_tag.id, 'word': _refl_word.id, 'fullform': _refl_fullforms, }] return awords def generate_answers_subject(self, answer, question, awords, qwords, element="SUBJ"): """ Can be used to generate answers for habitive, just supply element="HAB" """ words=[] word_id="" a_number="" subj_el = None subjword = None copy_syntax = "" # If there is subject in the question, there is generally agreement. subj_elements = self.get_elements(answer,element) if subj_elements: subj_el = subj_elements[0] copy_id = subj_el.copy_id if subj_el.copy: subj_copy = subj_el.copy copy_syntax = subj_copy.syntax if qwords.has_key(copy_syntax): qword = qwords[copy_syntax] subjtag_id = qword['tag'] subjtag = Tag.objects.get(id=subjtag_id) subjword_id = qword['word'] if subjtag.pos == "Pron": subjnumber = subjtag.personnumber else: subjnumber = subjtag.number # this should only happen if there's subj person a_number = self.QAPN[subjnumber] asubjtag = subjtag.string.replace(subjnumber, a_number) asubjtag_el = Tag.objects.get(string=asubjtag) # If pronoun, get the correct form if self.PronPNBase.has_key(a_number): pronbase = self.PronPNBase[a_number] words = self.get_words(None, asubjtag_el, pronbase) for word in words: word['number'] = a_number if not words and not len(words)>0: words = self.get_words(subj_copy, asubjtag_el, None, subjword_id) words[0]['number'] = a_number # Check if there are elements specified for the answer subject. else: if subj_el: tag_el_count = subj_el.tags.count() word_el_count = subj_el.wordqelement_set.count() if tag_el_count > 0: tag_el = subj_el.tags.all().order_by('?')[0] if tag_el.pos=="Pron": a_number = tag_el.personnumber else: a_number = tag_el.number if not subjword: subjword = subj_el.wordqelement_set\ .filter(word__form__tag=tag_el)\ .order_by('?')[0].word.id info = { 'qelement': subj_el.id, 'word' : subjword, 'tag' : tag_el.id, 'number' : a_number } words.append(info) for word in words: word['number'] = a_number awords[element] = words[:] # If SUBJ is appearing in the output, this means subjword is set to none for some reason. # subjword is set to none because subj_el.copy_id is none return awords def generate_answers_mainv(self, answer, question, awords, qwords, element="MAINV"): mainv_elements = self.get_elements(answer, element) # print '--' # print question.qid # print mainv_elements mainv_word=None mainv_words = [] mainv_tag = None mainv_tags = [] va_number = None copy_syntax = "" # Find content elements. if mainv_elements: mainv_el = mainv_elements[0] if mainv_el.copy_id: copy_id = mainv_el.copy_id copy_element = QElement.objects.get(id=copy_id) copy_syntax = copy_element.identifier # It is assumed that all subjects cause the same inflection # for verb, so it does not matter which subject is selected. if awords.has_key('SUBJ') and len(awords['SUBJ'])>0: # mainverb number depends on the number of the subject. asubj = awords['SUBJ'][0] a_number=asubj['number'] # print 'asubj number: ', a_number va_number=self.SVPN[a_number] # print 'va_number: ', va_number else: # No SUBJ defined, MAINV is a copy of the question MAINV # and needs to have Question-Answer subject change if qwords.has_key(copy_syntax): qmainv = qwords[copy_syntax] q_number = qmainv['number'] if q_number: va_number = self.QAPN[q_number] else: # No SUBJ defined, and MAINV is defined (and not a copy from Q) # but MAINV still needs to have Question-Answer subject change if qwords.has_key(element): qmainv = qwords[element] q_number = qmainv['number'] if q_number: va_number = self.QAPN[q_number] # The element we're looking at is not present in qwords, # but it is present in awords; which means that it's probably NEG if awords.has_key(element) and not qwords.has_key(element): qmainv = qwords.get("MAINV", False) if qmainv: q_number = qmainv['number'] if q_number: va_number = self.QAPN[q_number] # If there is no subject, then the number of the question # mainverb determines the number. mainv_fullform = False mainv_form = False mainv_word_obj = None if qwords.has_key(copy_syntax): qmainv = qwords[copy_syntax] mainv_word = qwords[copy_syntax]['word'] qmainvtag_id = qmainv['tag'] qmainvtag = Tag.objects.get(id=qmainvtag_id) qmainvtag_string = qmainvtag.string v_number = qmainvtag.personnumber if va_number: amainvtag_string = qmainvtag_string.replace(v_number,va_number) else: amainvtag_string = qmainvtag_string #print 'MAINV tag', amainvtag_string mainv_tag = Tag.objects.get(string=amainvtag_string) mainv_tags.append(mainv_tag) mainv_word_obj = Word.objects.get(id=mainv_word) try: mainv_form = mainv_word_obj.form_set.filter(tag__string=mainv_tag).order_by('?')[0] except IndexError: error_vars = ('generate_answers_mainv', mainv_word_obj, mainv_word_obj.pk, mainv_tag.string, mainv_word_obj.form_set.all().count()) error = "%s: Word <%s, id: %d> missing form for Tag <%s> (%d total form(s) available). \r\n" % error_vars # error += '\r\n'.join([form.tag.string for form in mainv_word_obj.form_set.all()]) raise Http404(error) mainv_fullform = mainv_form.fullform # If the main verb is under question, then generate full list. if answer.task in ["MAINV", "NEG"]: mainv_words = [] if mainv_elements: for mainv_el in mainv_elements: if mainv_el.tags.count()>0: if va_number: # print va_number mainv_tags = mainv_el.tags.filter(Q(personnumber=va_number)) else: mainv_tags = mainv_el.tags.all() for t in mainv_tags: info = {'qelement': mainv_el.id, 'tag': t.id} if mainv_fullform and mainv_word and mainv_tag: info['fullform'] = [mainv_fullform] info['word'] = mainv_word info['number'] = mainv_tag.personnumber mainv_words.append(info) else: info = { 'qelement' : mainv_el.id, 'tag' : mainv_tag.id } mainv_words.append(info) else: if mainv_word: mainv_words.extend(self.get_words(mainv_el, mainv_tag, None, mainv_word)) else: if mainv_elements: mainv_element = mainv_elements[0] tag_el_count = mainv_element.tags.count() if tag_el_count > 0: mainv_tags = mainv_el.tags.filter(Q(personnumber=va_number)) for tag in mainv_tags: info = { 'qelement' : mainv_element.id, 'word' : mainv_word, 'tag' : tag.id } mainv_words.append(info) else: for tag in mainv_tags: info = { 'tag' : mainv_tag.id, 'word' : mainv_word } mainv_words.append(info) if not mainv_words and qwords.has_key(element): mainv_words.append(qwords[element]) awords[element] = mainv_words return awords def generate_syntax(self, answer, question, awords, qwords, s): if s in self.generated_syntaxes: return awords if not awords.has_key(s): awords[s] = [] word_id=None tag_elements = [] swords = [] elements = self.get_elements(answer,s) if not elements: info = { 'fullform' : [ s ] } swords.append(info) awords[s] = swords return awords element = elements[0] if element.copy_id: copy_id = element.copy_id copy_element = QElement.objects.get(id=copy_id) copy_syntax = copy_element.identifier if qwords.has_key(copy_syntax): qword = qwords[copy_syntax] if qword.has_key('word'): word_id=qword['word'] if qword.has_key('tag'): tag = Tag.objects.get(id=qword['tag']) tag_elements.append(tag) if element.agreement: agr_id = element.agreement_id agr_el = QElement.objects.get(id=agr_id) agr_syntax = agr_el.identifier if qwords.has_key(agr_syntax): qword = qwords[agr_syntax] if qword.has_key('tag'): agr_tag_id = qword['tag'] agr_tag = Tag.objects.get(id=agr_tag_id) if agr_tag.personnumber: anumber = agr_tag.personnumber else: anumber = agr_tag.number _tag_query = Q(personnumber=anumber) | Q(number=anumber) tags_elements = element.tags.filter(_tag_query) # if no agreement, take all tags. else: tag_count = element.tags.count() if tag_count > 0: tag_elements = element.tags.all() # Take word forms for all tags info=None for tag_el in tag_elements: if not word_id: info = self.get_qword(element, tag_el) else: form_list = Form.objects.filter(Q(tag=tag_el.id) & Q(word=word_id)) if form_list: info = { 'qelement' : element.id, 'word' : word_id, 'tag' : tag_el.id } if not info: if self.test: raise Http404("not info " + question.id) return None swords.append(info) if not swords: if self.test: raise Http404("not swords " + str(question.id) + " " + s + str(element.id)) return None awords[s] = swords return awords ######### Vasta questions def get_question_qa(self,db_info,qtype): qwords = {} # if self.settings.has_key('level'): level=int(self.settings['level']) # else: # default level was set to 'all', but I could not find where level='1' q_count = Question.objects.filter(gametype="qa", level__lte=level).count() question = Question.objects.filter(gametype="qa", level__lte=level)[randint(0,q_count-1)] #question = Question.objects.get(id="107") qtype = question.qtype qwords = None qwords= self.generate_question(question, qtype) db_info['qwords'] = qwords db_info['question_id'] = question.id return db_info ######## Morfa questions def get_question_morfa(self, db_info, qtype): qwords = {} pos = self.settings.get('pos', False) qtype_wordform = False # Get qtype from settings. if not qtype: if pos == "N": qtype = self.settings['case_context'] if pos == "V": qtype = self.settings['vtype_context'] if pos == "Num": qtype = self.settings['num_context'] if pos == "A": qtype = self.settings['adj_context'] if pos == "Pron": qtype = self.settings['pron_context'] if pos == "Der": qtype = self.settings['derivation_type_context'] books = self.settings.get('book', None) question_query = Q(qtype__contains=qtype) & Q(gametype="morfa") if books: question_query = question_query & (Q(source__name__in=books) | Q(source__name="all" )) ### Generate question. If it fails, select another one. i, max_ = 0, 20 while not qwords and i < max_: i += 1 question = Question.objects.filter(question_query) if question.count() > 0: question = question.order_by('?')[0] else: errormsg = 'Database may not be properly loaded. No questions found for query.' errormsg += '\n qtype: %s' % repr(qtype) raise Http404(errormsg) qwords = None qwords = self.generate_question(question, qtype) db_info['qwords'] = qwords db_info['question_id'] = question.id return db_info, question ########### Morfa answers def get_answer_morfa(self,db_info,question): # Select answer using the id from the interface. # Otherwise select answer that is related to the question. awords = {} if db_info.has_key('answer_id'): answer = Question.objects.get(id=db_info['answer_id']) else: try: answer = question.answer_set.all().order_by('?')[0] except IndexError: raise Http404("No answer found for qid %s, check that questions are properly installed." % question.qid) # Generate the set of possible answers if they are not coming from the interface # Or if the gametype is qa. if db_info.has_key('answer_id') and self.settings['gametype'] == 'context': awords=db_info['awords'] else: # Generate the set of possible answers # Here only the text of the first answer is considered!! atext=answer.string words_strings = set(atext.split()) #Initialize each element identifier for w in atext.split(): if w== "": continue info = {} awords[w] = info # Subject and main verb are special cases: # There is subject-verb agreement and correspondence with question elements. if 'SUBJ' in words_strings: awords = self.generate_answers_subject(answer, question, awords, db_info['qwords']) self.generated_syntaxes.append('SUBJ') if 'HAB' in words_strings: awords = self.generate_answers_subject(answer, question, awords, db_info['qwords'], element="HAB") self.generated_syntaxes.append('HAB') # NOTE: seems to be generating correct negative number... if 'NEG' in words_strings: try: awords = self.generate_answers_mainv(answer, question, awords, db_info['qwords'], element="NEG") except AttributeError: if self.test: raise Http404("problem") return "error" self.generated_syntaxes.append('NEG') if 'MAINV' in words_strings: try: awords = self.generate_answers_mainv(answer, question, awords, db_info['qwords']) self.generated_syntaxes.append('MAINV') except AttributeError: if self.test: raise Http404("problem") return "error" # RPRON needs to be processed after MAINV and SUBJ so that person information is available if 'RPRON' in words_strings: awords = self.generate_answers_reflexive(answer, question, awords, db_info['qwords']) self.generated_syntaxes.append('RPRON') # RECPL, RECDU, P-REC processing here? if 'RECPL' in words_strings: awords = self.select_reciprocative_forms(answer, awords, target='RECPL') self.generated_syntaxes.append('RECPL') if 'RECDU' in words_strings: awords = self.select_reciprocative_forms(answer, awords, target='RECDU') self.generated_syntaxes.append('RECDU') if 'P-REC' in words_strings: awords = self.select_reciprocative_forms(answer, awords, target='P-REC') self.generated_syntaxes.append('P-REC') # Rest of the syntax #if self.test: raise Http404(words_strings) for s in words_strings: awords = self.generate_syntax(answer, question, awords, db_info['qwords'], s) if not awords: if self.test: raise Http404("problem" + s) return "error" if not awords.has_key(s): if self.test: raise Http404("problem2" + s) return "error" db_info['answer_id'] = answer.id db_info['awords'] = awords # print db_info # raise Exception(db_info) # print db_info['awords'] # print question.string return db_info def get_db_info(self, db_info,qtype=None,default_qid=None): anslist=[] # If the question id is received from the interface, use that question info # Otherwise select random question if db_info.has_key('question_id'): question = Question.objects.get(id=db_info['question_id']) qwords=db_info['qwords'] else: if default_qid: question = Question.objects.get(qid=default_qid) qwords = None qwords= self.generate_question(question, qtype) db_info['qwords'] = qwords # If no default information select question else: if not self.gametype == "qa": db_info,question = self.get_question_morfa(db_info,qtype) else: db_info = self.get_question_qa(db_info,qtype) # If Vasta, store and return: if not self.gametype == "qa": db_info = self.get_answer_morfa(db_info,question) return db_info def create_form(self, db_info, n, data=None): question = Question.objects.get(Q(id=db_info['question_id'])) # print question.string answer = None if self.settings.has_key('dialect'): dialect = self.settings['dialect'] else: dialect = DEFAULT_DIALECT # TODO: language setting language = "nob" if self.settings.has_key('language'): language = self.settings['language'] if not self.gametype == "qa": answer = Question.objects.get(Q(id=db_info['answer_id'])) # print answer.string form = (ContextMorfaQuestion(question, answer, \ db_info['qwords'], db_info['awords'], dialect, language,\ db_info['userans'], db_info['correct'], data, prefix=n)) else: form = (VastaQuestion(question, \ db_info['qwords'], language, \ db_info['userans'], db_info['correct'], data, prefix=n)) #print "awords:", db_info['awords'] #print "awords ...................." #print "qwords:", db_info['qwords'] #print "qwords ...................." return form, None