# -*- coding: utf-8 # $Id$ # # Copyright 2001, 2002 by IVA Team and contributors # # This file is part of IVA. # # IVA is free software; you can redistribute it and/or modify # it under the terms of the GNU General Public License as published by # the Free Software Foundation; either version 2 of the License, or # (at your option) any later version. # # IVA is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # GNU General Public License for more details. # # You should have received a copy of the GNU General Public License # along with IVA; if not, write to the Free Software # Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA __version__ = "$Revision$"[11:-2] import AccessControl import OFS, Globals from OFS import SimpleItem import types import time from TraversableWrapper import Traversable from Globals import Persistent from AccessControl import ClassSecurityInfo from Cruft import Cruft from common import translate, perm_edit, perm_view, mkTime import YlVahendus from YlVahendus import YlVahendus import YlAlus import YlTyybid from YlMeta import TestiMeta import YlHoidla from input_checks import strip_tags class YlTest( OFS.Folder.Folder, Persistent, AccessControl.Role.RoleManager, Traversable, Cruft ): """ Ülesannetest koosnev test """ meta_type='YlTest' security = ClassSecurityInfo() security.declareObjectPublic() def __init__(self): """ Alustus """ self.koigiLuba=LahendusLuba() self.koigiLuba.id='koigiLuba' self.grupiLoad=LahendusLoad() self.grupiLoad.id='grupiLoad' self.isikuLoad=LahendusLoad() self.isikuLoad.id='isikuLoad' self.vahendus=YlVahendus() self.vahendus.id='vahendus' self.meta=TestiMeta() self.kirjeldus = "" self.pealkiri = "" self.juhuslikJarjekord = 0 self.nr=0 self.avatudTaitmiseks=0 self.juhuslikJarjekord=0 self.lahendusaegTunnid=24 self.lahendusaegMinutid=0 security.declareProtected(perm_edit, 'add_new_quiz') def add_new_quiz(self): """ we're changing quiz - return 0. in QuizManager it returns 1 """ return 0 def isQuizClosed(self): """ not public yet """ gr_load = len(self.grupiLoad.objectValues()) user_load = len(self.isikuLoad.objectValues()) start_time = self.koigiLuba.algusAeg if gr_load == 0 and user_load == 0 and start_time == -1: return 1 return 0 def isQuizTimelimited(self): """ quiz has timelimit """ start_time = self.koigiLuba.algusAeg if start_time != -1: return 1 return 0 def isQuizPublicForGroups(self): """ quiz is public for groups """ gr_load = len(self.grupiLoad.objectValues()) if gr_load: return 1 return 0 def isQuizPublicForUsers(self): """ quiz is available for some users """ user_load = len(self.isikuLoad.objectValues()) if user_load: return 1 return 0 security.declareProtected(perm_edit, 'lisaYlesanne') def lisaYlesanne(self, yl): """ uus ülesanne testis """ if yl is None: return self.nr = self.nr + 1 while hasattr(self, 'yl'+str(self.nr)): self.nr = self.nr + 1 yl.id = "yl" + str(self.nr) tulem = self._setObject(yl.id, yl) return tulem security.declareProtected(perm_edit, 'lisaYlesanded') def lisaYlesanded(self, ylmassiiv): "Lisatakse ülesannete massiiv" for x in ylmassiiv: self.lisaYlesanne(x) security.declareProtected(perm_edit, 'ylesandedTekstina') def ylesandedTekstina(self): "Väljastab ülesanded HotPotatos ekspordina" tulemus="" yl=self.ylesanded() for i in range(len(yl)): tulemus=tulemus+yl[i].kirjutaYlesanneTekstiks(self.pealkiri, i+1) return tulemus def ylesanded(self): "Ülesannete loetelu" return self.objectValues() def annaPealkiri(self): "Testi nimi" if len(self.pealkiri)>0: return self.pealkiri return self.getId() security.declareProtected(perm_view, 'kysiLahendusajaTunnid') def kysiLahendusajaTunnid(self): "Kui kaua tohib test olla õpilasel lahendamiseks lahti" if not hasattr(self, 'lahendusaegTunnid'): return 24 return self.lahendusaegTunnid security.declareProtected(perm_view, 'kysiLahendusajaMinutid') def kysiLahendusajaMinutid(self): "Kui kaua tohib test olla õpilasel lahendamiseks lahti" if not hasattr(self, 'lahendusaegMinutid'): return 0 return self.lahendusaegMinutid security.declareProtected(perm_view, 'kasLahendusaegPiiratud') def kasLahendusaegPiiratud(self): "jah/ei" return getattr(self, 'lahendusaegPiiratud', 0) def pealkiriHTML(self, REQUEST): "Pealkiri HTMLina" return self.annaPealkiri() security.declareProtected(perm_edit, 'seaPealkiri') def seaPealkiri(self, pealkiri): "Pealkirja salvestus" self.pealkiri = strip_tags(pealkiri) def annaKirjeldus(self): """ Testi kirjeldus """ return self.kirjeldus security.declareProtected(perm_edit, 'seaKirjeldus') def seaKirjeldus(self, kirjeldus): "Kirjelduse salvestus" self.kirjeldus=kirjeldus def quiz_settings_handler(self, REQUEST, pealkiri, kirjeldus, tyyp, nahtavus, liikumisURL="", juhujarjestus='', testipass='', lahendusaegPiiratud=0, lahendusaegTunnid=24, lahendusaegMinutid=0): """ Change quiz settings """ if testipass: self.seaPass(testipass, REQUEST) self.seaPealkiri(pealkiri) self.seaKirjeldus(kirjeldus) self.seaTyyp(REQUEST, int(tyyp)) self.seaKysimusteJuhuslikJarjekord(juhujarjestus) self.seaVastusteNahtavus(nahtavus) self.lahendusaegPiiratud=lahendusaegPiiratud if not lahendusaegTunnid: lahendusaegTunnid = 0 if not lahendusaegMinutid: lahendusaegMinutid = 0 self.lahendusaegTunnid=lahendusaegTunnid self.lahendusaegMinutid=lahendusaegMinutid if liikumisURL=='': liikumisURL='ylesandedMuutmisTabelina'; # REQUEST.RESPONSE.redirect('pealkirjaMuutmisVormHTML?liikumisURL='+liikumisURL) # REQUEST.RESPONSE.redirect(liikumisURL) return REQUEST.RESPONSE.redirect('ylTestSettingsForm') security.declareProtected(perm_edit, 'seaPass') def seaPass(self,testipass, REQUEST): # closing test if testipass!='koigile': self.avatudTaitmiseks=0 if testipass!='ajapiirang': self.koigiLuba.algusAeg=-1 if testipass!='sisegr': for x in self.grupiLoad.nimedeLoetelu(): self.grupiLoad._delObject(x) if testipass!='isikuline': for x in self.isikuLoad.nimedeLoetelu(): self.isikuLoad._delObject(x) # seting permissions if testipass=='koigile': self.avatudTaitmiseks=1 pass if testipass=='ajapiirang': self.prooviRegistreeridaTestKodutooks(REQUEST) if self.koigiLuba.algusAeg==-1: self.koigiLuba.algusAeg=time.time() self.koigiLuba.loppAeg=time.time()+3000000 if testipass=='sisegr': if len(self.grupiLoad.objectValues())==0: dummy = LahendusLuba() dummy.id = 'DuMmY67891' self.grupiLoad._setObject(dummy.id, dummy) if testipass=='isikuline': if len(self.isikuLoad.objectValues())==0: dummy = LahendusLuba() dummy.id = 'DuMmY67891' self.isikuLoad._setObject(dummy.id, dummy) return def kysiVastusteNahtavus(self): "Teatatakse kood, millal õppur võib testi lahendusi näha" if hasattr(self, 'vastusteNahtavus'): return self.vastusteNahtavus return 0 def seaVastusteNahtavus(self, kood): "Salvestus" self.vastusteNahtavus=int(kood) def kasLubatudLahendusiVaadata(self, REQUEST): "Kas konkreetsel kasutajal on õigus oma lahenduste tulemusi näha" kood=self.kysiVastusteNahtavus() if kood==2: return 0 if kood==1: return 1 if kood==0: return not self.kasLubatudLahendada(REQUEST) def kasKirjasKodutoona(self, REQUEST): "Kas test asub juba kodutööde loetelus" m=self.aq_parent.kodutood.objectValues() for x in m: if x.tyyp==0: if hasattr(x, 'testiID'): if x.testiID==self.id: return 1 return 0 def prooviRegistreeridaTestKodutooks(self, REQUEST): """ Registreeritakse juhul, kui tüübiks on test ning vastav test pole veel kodutoo """ if self.kasKirjasKodutoona(REQUEST): return 0 too=self.aq_parent.kodutood.lisaKodutoo(0) too.pealkiri=self.annaPealkiri() too.normPunkte = self.normPunktiSumma() too.kirjeldus = self.annaKirjeldus() too.testiID=self.id return 1 def ylesanneteArv(self): """ Ülesannete arv """ return len(self.ylesanded()) def normPunktiSumma(self): """ Väärtused, mis annavad kokku 100% """ summa=0.0 for x in self.ylesanded(): if x.kasPunktiArvutus(): summa=summa+x.annaNormPunktid() return summa def kasKysimusteJuhuslikJarjekord(self): "Kas lahendamisel järjestatakse küsimused juhuslikult" return self.juhuslikJarjekord def seaKysimusteJuhuslikJarjekord(self, jarjekord): """ Muutuja seadmine """ if jarjekord: self.juhuslikJarjekord=1 else: self.juhuslikJarjekord=0 return str(self.juhuslikJarjekord) def muudaKysimusteJuhuslikJarjekord(self): """ Järjekorra muutmine """ if self.kasKysimusteJuhuslikJarjekord(): self.seaKysimusteJuhuslikJarjekord(0) else: self.seaKysimusteJuhuslikJarjekord(1) return str(self.kasKysimusteJuhuslikJarjekord()) def explainWhy(self, REQUEST): """ explain why user can or cannot solve quiz Quiz is currently closed. You can solve this quiz anytime as much as you like. You can solve this quiz n time(s). You can solve this quiz n hour(s) and n minute(s). You can solve it n time(s). You have not solved this quiz. Quiz is open for solving from till You have solved this quiz n times. """ targetLanguage = self.giveLanguage(REQUEST) why = "" solved_times = self.lahendusKordadeArv(REQUEST) if self.kasAvatudTaitmiseks()==1: why += "You can solve this quiz. This should never appear." if self.kasAvatudTaitmiseks()==2: pass if self.isQuizClosed(): why = translate(self, 'Quiz is currently closed.', target = targetLanguage) if self.isQuizTimelimited(): start = time.strftime(translate(self, 'timestamp_format', target=targetLanguage, default="%H:%M %Y-%m-%d"), time.localtime(self.koigiLuba.algusAeg)) end = time.strftime(translate(self, 'timestamp_format', target=targetLanguage, default="%H:%M %Y-%m-%d"), time.localtime(self.koigiLuba.loppAeg)) map = { 'start_time':start, 'end_time':end } why = translate(self, 'Quiz is open for solving from ${start_time} till ${end_time}', target = targetLanguage, mapping = map) num_times = self.koigiLuba.kordadeArv if num_times == -1: num_times = translate(self, 'unlimited', target=targetLanguage) map = { 'num_times':num_times, 'solved_times':solved_times} why += "
"+translate(self, 'You have solved it ${solved_times}/${num_times} time(s)', target=targetLanguage, mapping=map) map = {'curr_time':time.strftime(translate(self, 'timestamp_format', target=targetLanguage),time.localtime(time.time()))} why += "
"+translate(self, 'Current server time: ${curr_time}.', target=targetLanguage, mapping=map) map = {'hours':self.kysiLahendusajaTunnid(), 'minutes':self.kysiLahendusajaMinutid()} why += "
"+translate(self, 'Time for solving: ${hours} hours and ${minutes} minutes.', target=targetLanguage, mapping=map) return why def kasLubatudLahendada(self, REQUEST): """ Arvutus lubade kaudu """ try: if self.kasAvatudTaitmiseks()==1: return 1 if self.kas_opetaja(REQUEST): return 1 n=self.lahendusKordadeArv(REQUEST) if self.koigiLuba.kasLubatudLahendada(REQUEST, n):return 1 if hasattr(self.isikuLoad, str(REQUEST.AUTHENTICATED_USER)): if getattr(self.isikuLoad, str(REQUEST.AUTHENTICATED_USER)).kasLubatudLahendada(REQUEST, n): return 1 for x in self.find_course().subgroups.getSubgroups(): m=x.get_local_roles() leitud=0 for t in m: if t[0]==str(REQUEST.AUTHENTICATED_USER): leitud=1 if leitud: try: if hasattr(self.grupiLoad, x.id): if getattr(self.grupiLoad, x.id).kasLubatudLahendada(REQUEST, n): return 1 except: pass return 0 except: return 1 security.declareProtected(perm_edit, 'lubadeKustutusLeht') def lubadeKustutusLeht(self, REQUEST): "Lubade eemaldamine" isikud = 0 grupid = 0 if hasattr(REQUEST, 'chkavatudtaitmiseks'): self.avatudTaitmiseks=0 if hasattr(REQUEST, 'chkkoigiluba'): self.koigiLuba.algusAeg=-1 for x in self.isikuLoad.nimedeLoetelu(): if hasattr(REQUEST, 'isik'+x): self.isikuLoad._delObject(x) isikud = 1 for x in self.grupiLoad.nimedeLoetelu(): if hasattr(REQUEST, 'grupp'+x): self.grupiLoad._delObject(x) grupid = 1 if isikud: REQUEST.RESPONSE.redirect('isikuLubadeLisamisVorm') if grupid: REQUEST.RESPONSE.redirect('grupiLubadeLisamisVorm') def lubaKoigileTaita(self, REQUEST): """ Õigus pidevalt täita """ self.seaAvatudTaitmiseks(1, REQUEST) self.prooviRegistreeridaTestKodutooks(REQUEST) REQUEST.RESPONSE.redirect('lubadeViited') def kasLeidubLoataIsikuid(self): "jah/ei" return len(self.find_course().get_all_users_id())>len(self.isikuLoad.nimedeLoetelu()) def startTime(self): """ time starting """ if not hasattr(self, 'startingTime'): return time.time() else: return self.startingTime def endTime(self): """ time ending """ if not hasattr(self, 'endingTime'): return time.time()+10000 else: return self.endingTime def repeatValue(self): """ how many times a student can take the test """ return getattr(self, 'repeating', 1) def applyTimeForAll(self, REQUEST): """ apply timelimit for all selected students """ self.repeating = REQUEST.kordadearv self.startingTime=mkTime(REQUEST, "algusAeg") self.endingTime=mkTime(REQUEST, "loppAeg") for luba in self.isikuLoad.objectValues(): luba.muutmisLeht(REQUEST,returnaway=0) return REQUEST.RESPONSE.redirect('isikuLubadeLisamisVorm') def isikuLubadeLisamisVorm(self, REQUEST): """ Valida, kellel lubada """ tulemus="" tmp = "" on_tulemust = 0 isikud=self.find_course().get_all_users_id() loagaIsikud=self.isikuLoad.nimedeLoetelu() tmp += "

"+translate(self,'Set the same timelimit for all:',target=self.giveLanguage(REQUEST))+"

" tmp += "
" tmp += "

"+translate(self,'Starting time:',target=self.giveLanguage(REQUEST))+"

" tmp += self.ajaMuutmisElemendid('algusAeg',float(self.startTime())) tmp += "

"+translate(self,'Ending time:',target=self.giveLanguage(REQUEST))+"

" tmp += self.ajaMuutmisElemendid('loppAeg',float(self.endTime())) tmp += "

"+translate(self, 'Repeated', target=self.giveLanguage(REQUEST))+"

" tmp += "" tmp += "
" tulemus += "
" for luba in self.isikuLoad.objectValues(): if luba.id == 'DuMmY67891': continue tulemus += "
"+self.firstAndLast(luba.id)+""+luba.loaAndmedTekstina(REQUEST) on_tulemust = 1 if on_tulemust: tulemus += "
" tulemus += "
" if on_tulemust: tulemus = tmp + tulemus tulemus += "
" siit_tulemust = 0 for luba in isikud: if luba in loagaIsikud: continue tulemus += "
\n"+self.firstAndLast(luba) on_tulemust = 1 siit_tulemust = 1 if siit_tulemust: tulemus += '
' tulemus += "
" # tulemus += "
"+translate(self,'Testi haldus',target=self.giveLanguage(REQUEST))+"" if on_tulemust: return self.defaultRender(page=tulemus, breadcrumbs='') else: pass def isikuLubadeLisamisLeht(self, REQUEST, nimed=None): "Nimede salvestus" if nimed is not None: if type(nimed) is types.StringType: nimed=(nimed,) for x in nimed: luba=LahendusLuba() luba.id=x self.isikuLoad._setObject(luba.id, luba) REQUEST.RESPONSE.redirect('isikuLubadeLisamisVorm') def kasLeidubLoataGruppe(self): "jah/ei" return len(self.find_course().subgroups.objectValues())>len(self.grupiLoad.nimedeLoetelu()) def grupiLubadeLisamisVorm(self, REQUEST): """ valida, kellel lubada """ targetLanguage = self.giveLanguage(REQUEST) tulemus="" on_tulemust = 0 subgroupManager = self.find_course().subgroups grupid = subgroupManager.objectValues() loagaGrupid = self.grupiLoad.nimedeLoetelu() tulemus += "
" tulemus += "" tulemus += "" tulemus += "" tulemus += "" for luba in self.grupiLoad.objectValues(): if luba.id=='DuMmY67891': continue tulemus += "\n" tulemus += "" tulemus += "" on_tulemust = 1 if on_tulemust: tulemus += "" tulemus += "
"+translate(self, 'Subgroups', target=targetLanguage)+""+translate(self, 'Limits', target=targetLanguage)+"
"+subgroupManager.getSubgroupById(luba.id).get_name()+""+luba.loaAndmedTekstina(REQUEST)+"
" tulemus += "
" tulemus += "" tulemus += "" tulemus += "" tulemus += "" siit_tulemust = 0 for luba in grupid: if luba.id in loagaGrupid: continue tulemus += "\n" tulemus += "" tulemus += "" tulemus += "" on_tulemust = 1 siit_tulemust = 1 if siit_tulemust: tulemus += "" tulemus += "
"+translate(self, 'Subgroups', target=targetLanguage)+""+translate(self, 'Subgroup members', target=targetLanguage)+"
"+str(luba.get_name())+"" for sm in luba.subgroup_members(): tulemus += sm+" " tulemus += "
" # tulemus += "
Testi haldus" if on_tulemust: return self.defaultRender(page=tulemus) else: return self.message_dialog( message='There are no subgroups!', action='ylTestSettingsForm', ) def grupiLubadeLisamisLeht(self, REQUEST, nimed=None): "Lahendusloa lisamine grupile" if nimed is not None: if type(nimed) is types.StringType: nimed=(nimed,) for x in nimed: luba=LahendusLuba() luba.id=x self.grupiLoad._setObject(luba.id, luba) REQUEST.RESPONSE.redirect('grupiLubadeLisamisVorm') def kustutaLahendusload(self): "Kustutatakse lahendusload" self.grupiLoad.kustutaKoikLoad() self.isikuLoad.kustutaKoikLoad() self.koigiLuba.algusAeg=-1 self.koigiLuba.loppAeg=-1 self.koigiLuba.kordadeArv=-1 def kasLeidubLubasid(self): "Lubade olemasolu otsing" if len(self.grupiLoad.objectValues())>0: return 1 if len(self.isikuLoad.objectValues())>0: return 1 if self.koigiLuba.algusAeg!=-1: return 1 return 0 def taitmisAvatusSymbol(self, REQUEST): "Sümbol vastavalt ligipääsuseisundile" if self.kasAvatudTaitmiseks()==1: return 'public' if self.kasAvatudTaitmiseks()==2: return 'between' return 'closed' def kasAvatudTaitmiseks(self): "Teatab, kas opilastele on test nahtav" try: if self.avatudTaitmiseks: return 1 if self.kasLeidubLubasid(): return 2 return 0 except: return 0 def seaAvatudTaitmiseks(self, seisund, REQUEST): "Saab oelda, kas avatud" if int(seisund)==1: self.avatudTaitmiseks=1 else: self.avatudTaitmiseks=0 self.kustutaLahendusload() #return str(self.avatudTaitmiseks) REQUEST.RESPONSE.redirect('index_html') def muudaAvatudTaitmiseks(self, REQUEST): "Vahetab seisundi" if self.avatudTaitmiseks==1: self.seaAvatudTaitmiseks(0, REQUEST) else: self.seaAvatudTaitmiseks(1, REQUEST) def ylesanneteTyypideLoetelu(self, REQUEST): "Väljakutse" return self.defaultRender(page=self.vahendus.ylesanneteTyypideLoetelu(REQUEST)) security.declareProtected(perm_edit, 'lisaUusYlesanne') def lisaUusYlesanne(self, REQUEST, tyyp): "Ülesande lisamine" yl=self.vahendus.lisaUusYlesanne(REQUEST, tyyp) self.lisatudYlesandeTyyp=tyyp self.lisaYlesanne(yl) yl.lisaMeta(REQUEST) self.kopeeriTestiMetaYlesandele(REQUEST, yl) REQUEST.RESPONSE.redirect(self.absolute_url()+"/"+yl.id+"/kupuform") def kysiLisatudYlesandeTyyp(self): "Antakse teada viimati loodud ülesanne. Abikäsklus mitme samatüübilise ülesande loomisel" if hasattr(self, 'lisatudYlesandeTyyp'): return self.lisatudYlesandeTyyp return 'YksikvalikYlesanne' def kopeeriTestiMetaYlesandele(self, REQUEST, yl): "Kopeerib ülesande jaoks vajalikud väljad" for x in self.meta.keywords: yl.meta.keywords.append(x) yl.meta.language=self.meta.language yl.meta.rightsNr=self.meta.rightsNr yl.meta.copyrightandotherrestrictions=self.meta.copyrightandotherrestrictions yl.meta.copyrightdescription=self.meta.copyrightdescription security.declareProtected(perm_edit, 'kustuta_leht') def kustuta_leht(self, REQUEST, kustuta=None): "ülesannete kustutamise leht" if kustuta is None: kustuta=() if type(kustuta) is types.StringType: kustuta=(kustuta,) for x in kustuta: self._delObject(x) REQUEST.RESPONSE.redirect('ylesandedMuutmisTabelina') def ylTyyp(self, REQUEST, ylid): "Küsitud ID-ga ülesande tüüp" if hasattr(self, ylid): return self.ylid.ylesandeNimetus(REQUEST) return None def kysiLahendamiseYlesanded(self): """ Testis leiduvad ülesanded, vajadusel segipaisatuna """ kirjutusyl=[] for x in self.ylesanded(): kirjutusyl.append(x) if self.kasKysimusteJuhuslikJarjekord(): import random random.shuffle(kirjutusyl) return kirjutusyl def getSolvingHTML(self, REQUEST): """ get html for solving """ if not self.kasLubatudLahendada(REQUEST): return "You are not allowed to solve this quiz." qts = self.ylesanded() if self.kasKysimusteJuhuslikJarjekord(): import random random.shuffle(qts) res = '' for q in qts: res += '' res += '' res += q._getQuestionHTML() res += '' res += '' res += q.taitmineHTML(REQUEST, q.getId()) res += '' res += '' return res def kasLahendamistAlustatud(self, REQUEST): """ Teatatakse, kas õpilane on selle testi küsimusi juba näinud. """ k=salvestusAsukoht(REQUEST, self.id) return hasattr(k, 'algusaeg') def kasLahendusaegaVeel(self, REQUEST): "Kas lubatakse õpilasel üldse testi lahendama asuda" try: if not self.kasLahendusaegPiiratud(): return 1 except TypeError: if not getattr(self, 'lahendusaegPiiratud', 0): return 1 return self.kuiPaljuLahendusaegaVeel(REQUEST)>0 def kuiPaljuLahendusaegaVeel(self, REQUEST): "Mitu sekundit lahendamise lõpuni" t=int(self.kysiLahendusajaTunnid()) m=int(self.kysiLahendusajaMinutid()) aeg=t*3600+m*60 k=self.salvestusAsukoht(REQUEST, self.id) if not hasattr(k.aq_base, 'quiz_starting_time'): return 1 if not k.quiz_starting_time.has_key(self.getId()): return 1 return int(aeg-(time.time()-k.quiz_starting_time[self.getId()])) def salvestaAlgusAeg(self, REQUEST, testinimi=''): """ Jäetakse meelde küsimuste nägemisel """ k=self.salvestusAsukoht(REQUEST, testinimi) # XXX: remove me if hasattr(k.aq_base, 'algusAeg'): del k.algusAeg if not hasattr(k, 'quiz_starting_time'): k.quiz_starting_time = {} if not k.quiz_starting_time.has_key(self.getId()): k.quiz_starting_time[self.getId()] = time.time() return 0 def index_html(self, REQUEST): """ Peegel veebi """ if self.kas_opetaja(REQUEST): #return self.ylesandedMuutmisTabelina(REQUEST) REQUEST.RESPONSE.redirect(self.absolute_url()+"/ylesandedMuutmisTabelina") else: return #self.taidaVorm(REQUEST) def loeAndmedLehelt(self, REQUEST): "Veebilt tulevad andmed talde" if not hasattr(REQUEST, 'salvestusnupp'): return self.defaultRender(page=translate(self, 'You must click the button in order to submit your answers. Return to previous page by clicking the Back-button of your browser.', target=self.giveLanguage(REQUEST))) if not self.kasLahendusaegaVeel(REQUEST): return self.message_dialog_error(title='Expired', message='time limit exceeded '+' '+str(self.kuiPaljuLahendusaegaVeel(REQUEST))+' s', action=self.aq_parent.aq_parent.absolute_url()+'/tootubade_leht' ) t=TestiVastused() #variant1 t.testinimi=self.id for x in self.ylesanded(): vastus = REQUEST.get(x.id, None) #tulemus=tulemus+"!"+x.id+" "+str(vastus) t._setObject(x.id, x.salvestaPakutu(vastus)) #yl1 self.paigutaTestiVastus(REQUEST, t) if t.isAllPointsCalculating(): try: assign = None # kysi testi puntidesumma test_punktid = t.punktiSumma() # kysi norm punktide summa test_norm = t.normPunktiSumma() # kysi kodutöunktide summa kt = self.courses kd = getattr(self.courses, self.get_course_id_from_req(REQUEST)).kodutood for y in kd.listAssignments(): if y.quizID() == self.get_id(): assign = y kodu_punktid = y.getPoints() # kodutööpunktide summaga ja norm punktide summaga (koefitsent) # koef = test_norm*1.0/kodu_punktid if test_norm>0: koef = kodu_punktid*1.0/test_norm else: koef=0 # korruta testipunktide summa koefitsendiga. tt = test_punktid*koef # salvesta kodutöabelisse. assign.setUserPoints(assign.get_id(), str(REQUEST.AUTHENTICATED_USER), 'points', tt) except: pass return REQUEST.RESPONSE.redirect('qtAnswersSaved?userLocation='+REQUEST.userLocation) def salvestusAsukoht(self, REQUEST, testinimi='nimetu'): "Koht testi tulemuste salvestamiseks" #kasutajajuur=getattr(self.fle_root().fle_users, str(REQUEST.AUTHENTICATED_USER)) kasutajajuur = self.fle_root().fle_users.get_user_info(str(REQUEST.AUTHENTICATED_USER)) kasutaja = kasutajajuur.get_course_webtop(kasutajajuur.get_jooksev_kursus()) if not kasutaja: raise 'IVA error', 'course webtop not found' if not hasattr(kasutaja.aq_base, 'testivastused'): kasutaja.manage_addProduct['OFSP'].manage_addFolder('testivastused') kasutaja.testivastused.id='testivastused' if not hasattr(kasutaja.testivastused.aq_self, testinimi): kasutaja.testivastused.manage_addProduct['OFSP'].manage_addFolder(testinimi) testikataloog=getattr(kasutaja.testivastused, testinimi) testikataloog.id=testinimi testikataloog=getattr(kasutaja.testivastused, testinimi) #return self.get_url_to_object(testikataloog) return testikataloog def paigutaTestiVastus(self, REQUEST, vastus): """ Paigutab variandi uue id alla """ k=self.salvestusAsukoht(REQUEST, vastus.testinimi) variandinr = 1 while getattr(k.aq_base, 'variant'+str(variandinr), None): variandinr = variandinr + 1 vastus.id="variant"+str(variandinr) k._setObject(vastus.id, vastus) self.updateStat(REQUEST, 'testsSolved') return str(variandinr) def lahendusKordadeArv(self, REQUEST): "Mitu varianti on kasutaja vastavat testi lahendanud" k=self.salvestusAsukoht(REQUEST, self.id) return len(k.objectValues()) def kasutajateTulemused(self, REQUEST, kommentaarid=0): "Testi tulemused" if hasattr(REQUEST, 'kommentaarid'): kommentaarid=REQUEST.kommentaarid tulemus="

"+(translate(self, 'Answers for', target=self.giveLanguage(REQUEST)) +" "+ self.id)+"

\n" kommentaarid=int(kommentaarid) if kommentaarid==0: tulemus=tulemus+"

"+translate(self, 'show comments', target=self.giveLanguage(REQUEST))+"

\n" else: tulemus=tulemus+"

"+translate(self, 'hide comments', target=self.giveLanguage(REQUEST))+"

\n" try: kasutajad=self.get_all_users() except: return tulemus+translate(self,'could not find user(s)',target=self.giveLanguage(REQUEST)) tulemus=tulemus+"\n\n" for x in kasutajad: tulemus=tulemus+"\n\n\n" except Exception, probleem: tulemus=tulemus+"" tulemus+="\n
"+x.firstAndLast(x.get_uname())+"\n" try: k=getattr(x.webtop, 'c'+str(self.find_course().get_id())) #tulemus=tulemus+"j"+k.absolute_url() if hasattr(k, 'testivastused'): #tulemus=tulemus+"k" if hasattr(k.testivastused, self.id): tmp = getattr(k, 'testivastused') t=getattr(tmp, self.id) for y in t.objectValues(): # we if because if we added aq_self to above getattr, we ended up in god knows where if str(y.id)!='webtop': tulemus=tulemus+""+str(y.id)+" " if kommentaarid: tulemus=tulemus+str(y.lyhiKokkuvoteOpetajale(REQUEST)) else: tulemus=tulemus+str(y.punktiArvutusHTML(REQUEST)) tulemus=tulemus+"
\n" tulemus=tulemus+"\n

\n" tulemus+=""+translate(self, 'Statistics', target=self.giveLanguage(REQUEST))+"" return tulemus def jargmiseYlesandeID(self, REQUEST, ylid=""): "Järgmise number" if hasattr(REQUEST, 'ylid'): ylid=REQUEST.ylid ylesanded=self.ylesanded() nr=-1 for x in range(len(ylesanded)): if ylesanded[x].id==ylid: nr=x nr=nr+1 if nr>=len(ylesanded): return 0 return ylesanded[nr].id def seaTyyp(self, REQUEST, tyyp): "Testi tüübi sättimine" self.tyyp=tyyp def kysiTyyp(self, REQUEST=None): "Väljastatakse testi tüüp" if not hasattr(self, 'tyyp'): return 0 return self.tyyp def kysiTyypTekstina(self, REQUEST): "Jooksva testi tüüp" return self.getTypesPretty(REQUEST)[self.kysiTyyp(REQUEST)] def lahendusteArvud(self, REQUEST): "Lahendamise statistika: kohal 0: lahendajate arv, kohal 2 lahenduste arv" try: kasutajad=self.get_all_users() taitjaid=0 lahendusi=0 for x in kasutajad: if hasattr(x.webtop, 'c'+str(self.find_course().get_id())): k=getattr(x.webtop, 'c'+str(self.find_course().get_id())) if hasattr(k, 'testivastused'): if hasattr(k.testivastused, self.id): t=getattr(k.testivastused, self.id) if len(t.objectValues())>0: taitjaid=taitjaid+1 lahendusi=lahendusi+len(t.objectValues()) return (taitjaid, " ", lahendusi) except: return ('x', ' ', 'x') def lahendusteKataloogid(self, REQUEST): "Õppurite lahenduste kataloogid statistika tarbeks" kataloogid=[] kasutajad=self.get_all_users() course_id = str(self.find_course().get_id()) for x in kasutajad: if hasattr(x.webtop, 'c'+course_id): k=getattr(x.webtop, 'c'+course_id) if hasattr(k, 'testivastused'): if hasattr(k.testivastused, self.id): t=getattr(k.testivastused, self.id) if hasattr(t, 'variant1'): kataloogid.append(t.variant1) return kataloogid def lahendusteYlesanded(self, REQUEST, kataloogid, ylesanne): "Ette antakse õppurite vastava testivariandi lahenduskataloogide massiiv.. Väljastatakse kataloogi seest etteantud nimega ülesannete massiiv" tulemus=[] for k in kataloogid: if hasattr(k, ylesanne.id): tulemus.append(getattr(k, ylesanne.id)) return tulemus def lahendusedStatistikaVastavaltTyybile(self, REQUEST, kataloogid, ylesanne): "" ylesanded=self.lahendusteYlesanded(REQUEST, kataloogid, ylesanne) if ylesanne.meta_type=="YksikvalikYlesanne": return self.lahendusedStatistikaMitmikvalik(REQUEST, ylesanded, ylesanne) if ylesanne.meta_type=="MitmikvalikYlesanne": return self.lahendusedStatistikaOigedVariandid(REQUEST, ylesanded, ylesanne) if ylesanne.meta_type=="ValikYlesanne": return self.lahendusedStatistikaJahEi(REQUEST, ylesanded, ylesanne) if ylesanne.meta_type=="OigeTekstivastusegaYlesanne": return self.lahendusedStatistikaLyhivastus(REQUEST, ylesanded, ylesanne) if ylesanne.meta_type=="ArvuvahemikuliseVastusegaYlesanne" or ylesanne.meta_type=="ProtsentYlesanne": return self.lahendusedStatistikaArvuvahemik(REQUEST, ylesanded, ylesanne) if ylesanne.meta_type=="TekstivastusegaYlesanne": return self.lahendusedStatistikaTekstivastus(REQUEST, ylesanded, ylesanne) return translate(self,'No statistics', target=self.giveLanguage(REQUEST)) def lahendusedStatistikaMitmikvalik(self, REQUEST, ylesanded, ylesanne): "Väljundiks HTML-tabel: valik/pakutud kordade arv. sisendiks kõigi lahendajate vastavad ülesanded" v=[] vigu=0 pihtas=0 for i in range(len(ylesanne.valikud)): v.append(0) for x in ylesanded: try: v[int(x.pakutudAndmed)]+=1 if x.kasPihtas():pihtas+=1 except: vigu+=1 t="\n" t+="\n" for i in range(len(ylesanne.valikud)): t+="\n" t+="
"+translate(self, 'Choice', target=self.giveLanguage(REQUEST))+""+translate(self, 'Count', target=self.giveLanguage(REQUEST))+"
"+ylesanne.valikud[i]+""+str(v[i])+"
" t+=translate(self, 'Errors', target=self.giveLanguage(REQUEST))+": "+str(vigu)+"
" if ylesanne.oigeValik!=-1: #Kui leidub õige vastus t+=translate(self, 'Hits',target=self.giveLanguage(REQUEST))+": "+str(pihtas) return t def lahendusedStatistikaOigedVariandid(self, REQUEST, ylesanded, ylesanne): "Väljundiks HTML-tabel: valik/pakutud kordade arv. sisendiks kõigi lahendajate vastavad ülesanded" v=[] p=[] vigu=0 for i in range(len(ylesanne.valikud)): v.append(0) p.append(0) for x in ylesanded: # try: vastused=None if x.pakutudAndmed is None: vastused=() if type(x.pakutudAndmed) == types.StringType: try: vastused=(int(x.pakutudAndmed),) except ValueError: vastused = [0] #XXX: None here?! if vastused is None: # if type(x.pakutudAndmed) == types.TupleType or type(x.pakutudAndmed)==types.DictType: vastused=map(int, x.pakutudAndmed) for vastus in vastused: v[int(vastus)]+=1 for i in range(len(ylesanne.valikud)): if i in ylesanne.oigedValikud and i in vastused: p[i]+=1 if (i not in ylesanne.oigedValikud) and (i not in vastused): p[i]+=1 # except: # vigu+=1 t="\n " t+="" t+="\n" for i in range(len(ylesanne.valikud)): t+="" if len(ylesanne.oigedValikud)>0: t+="" t+="\n" t+="
"+translate(self, 'Choice', target=self.giveLanguage(REQUEST))+""+translate(self, 'Count', target=self.giveLanguage(REQUEST))+""+translate(self, 'Hits', target=self.giveLanguage(REQUEST))+"
"+ylesanne.valikud[i]+""+str(v[i])+""+str(p[i])+"
" t+=translate(self, 'Errors', target=self.giveLanguage(REQUEST))+": "+str(vigu) return t def lahendusedStatistikaJahEi(self, REQUEST, ylesanded, ylesanne): "Väljundiks HTML-tabel: valik/pakutud kordade arv. sisendiks kõigi lahendajate vastavad ülesanded" kokku=0 pihtas=0 for x in ylesanded: if x.pakutudAndmed=="on": kokku+=1 if x.kasPihtas(): pihtas+=1 return translate(self, 'Count', target=self.giveLanguage(REQUEST))+": "+str(kokku)+", "+translate(self, 'Hits', target=self.giveLanguage(REQUEST))+": "+str(pihtas) def lahendusedStatistikaLyhivastus(self, REQUEST, ylesanded, ylesanne): """Väljundiks HTML-tabel: valik/pakutud kordade arv. sisendiks kõigi lahendajate vastavad ülesanded""" kokku=0 pihtas=0 for x in ylesanded: try: if len(x.pakutudAndmed)>0: kokku+=1 except TypeError: pass if x.kasPihtas(): pihtas+=1 return translate(self, 'Count', target=self.giveLanguage(REQUEST))+": "+str(kokku)+", "+translate(self, 'Hits', target=self.giveLanguage(REQUEST))+": "+str(pihtas) security.declareProtected(perm_edit, 'lahendusedStatistikaArvuvahemik') def lahendusedStatistikaArvuvahemik(self, REQUEST, ylesanded, ylesanne): "Väljundiks HTML-tabel: valik/pakutud kordade arv. sisendiks kõigi lahendajate vastavad ülesanded" punkteSaanud=0 punktiSumma=0 for x in ylesanded: if x.automaatPunkte()>0: punkteSaanud+=1 punktiSumma+=x.automaatPunkte() return translate(self, 'Number of students who scored: ', target=self.giveLanguage(REQUEST))+str(punkteSaanud)+translate(self, ', total sum of points: ', target=self.giveLanguage(REQUEST))+str(punktiSumma)+"/"+str(len(ylesanded)*ylesanne.normPunktid) security.declareProtected(perm_edit, 'lahendusedStatistikaTekstivastus') def lahendusedStatistikaTekstivastus(self, REQUEST, ylesanded, ylesanne): """ Väljundiks HTML-tabel: valik/pakutud kordade arv. sisendiks kõigi lahendajate vastavad ülesanded """ vastanud=0 t=translate(self, 'Submitted:', target=self.giveLanguage(REQUEST))+"
" for x in ylesanded: try: if len(x.pakutudAndmed.strip())>0: vastanud+=1 except AttributeError: pass t+="

"+x.pakutudHTML(REQUEST)+"

" return t+translate(self, 'Number of responses: ', target=self.giveLanguage(REQUEST))+str(vastanud) def leivaPuru(self, REQUEST, viimane=0): "Teekond üles" nimi=self.id if not hasattr(self,'tyyp'): self.tyyp=0 nimi=self.getTypesPretty(REQUEST)[self.tyyp] if viimane: tekst=nimi else: tekst=nimi if self.kas_opetaja(self, REQUEST): return " > "+REQUEST["quizzes"]+" > " + tekst return " > "+tekst security.declareProtected(perm_edit, 'lisaYlesandedHoidlasse') def lisaYlesandedHoidlasse(self, REQUEST): "Kõik loodud/täiendatud ülesanded hoidlasse" loendur=0 for x in self.objectValues(): if x.meta.ex_changed: self.fle_root().qtCatalog.lisaYlesanne(REQUEST, x) loendur=loendur+1 return self.message_dialog( self, REQUEST, title="Pool", message=translate(self,"Questions added to the pool: ",target=self.giveLanguage(REQUEST)) + str(loendur), action="ylesandedMuutmisTabelina") Globals.InitializeClass(YlTest) class LahendusLoad(Persistent, OFS.Folder.Folder, Traversable): "Lahenduslubade kogum" def leivaPuru(self, REQUEST, viimane=0): "Teekond üles" nimi=self.id+" " if viimane: tekst=nimi else: tekst=""+nimi+"" return self.aq_parent.leivaPuru(REQUEST)+" > lubade haldus > "+tekst def kustutusLeht(self, REQUEST, kustuta=None): "õiguslubade kustutamine" if kustuta is not None: if type(kustuta)==types.StringType: kustuta=(kustuta,) for x in kustuta: self._delObject(x) REQUEST.RESPONSE.redirect('index_html') def kustutaKoikLoad(self): "Plats puhtaks" for x in self.nimedeLoetelu(): self._delObject(x) def nimedeLoetelu(self): "Elementide nimed tekstina" nimed=[] for x in self.objectValues(): nimed.append(x.id) return nimed def index_html(self, REQUEST): "Lubade loetelu" tulemus="" if len(self.objectValues())>0: tulemus=tulemus+"
    " for x in self.objectValues(): tulemus=tulemus+"\n
  • "+x.id+"
  • " tulemus=tulemus+"
" else: tulemus=tulemus+"Lubasid pole jagatud" return self.defaultRender(page=tulemus) class LahendusLuba(Persistent, OFS.SimpleItem.Item, Traversable): "õigused testi lahendamiseks" kordadeArv=-1 #arvu ei piirata algusAeg=-1 #Pole avatud lahendamiseks loppAeg=-1 #Kestust ei piirata def kasLahendusAeg(self): "jah/ei praeguse hetke kohta" if self.algusAeg==-1: return 0 if self.algusAeg>time.time():return 0 if self.loppAeg==-1:return 1 if self.loppAeg>time.time():return 1 else: return 0 def kasLubatudLahendada(self, REQUEST, tehtudKordadeArv): "Jah/ei" if self.kasLahendusAeg()==0:return 0 if self.kordadeArv==-1: return 1 return int(tehtudKordadeArv)" x=algus while x<=ots: tulemus=tulemus+"\n " x=x+samm tulemus=tulemus+"\n" return tulemus def aegTekstina(self, REQUEST, aeg): "tekstiesitus" if aeg==-1: return "*" return time.strftime(translate(self,'timestamp_format',default="%H:%M %Y-%m-%d",target=self.giveLanguage(REQUEST)), time.localtime(aeg)) def loaAndmedTekstina(self, REQUEST): "Loa kirjeldus ekraanil. Ajavahemik, kordade arv." tulemus="" if self.algusAeg==-1: tulemus += " "+translate(self,'timelimit',target=self.giveLanguage(REQUEST)) return tulemus tulemus=tulemus+self.aegTekstina(REQUEST, self.algusAeg)+"-" if self.loppAeg==-1: tulemus="" else: tulemus=tulemus+self.aegTekstina(REQUEST, self.loppAeg) if self.kordadeArv==-1: tulemus=tulemus+" "+translate(self,'unlimited',target=self.giveLanguage(REQUEST)) else: tulemus=tulemus+" "+str(self.kordadeArv) tulemus=tulemus+" " return tulemus def ajaMuutmisElemendid(self, elemendinimi, aeg=-1): "Valikute kogum" if aeg==-1:aeg=time.time() m=time.localtime(aeg) tulemus=self.looValik(elemendinimi+"Aasta", m[0]-5, m[0]+10, m[0]) tulemus=tulemus+"-"+\ self.looValik(elemendinimi+"Kuu", 1, 12, m[1]) tulemus=tulemus+"-"+\ self.looValik(elemendinimi+"Paev", 1, 31, m[2]) tulemus=tulemus+"   "+\ self.looValik(elemendinimi+"Tund", 0, 23, m[3]) tulemus=tulemus+":"+\ self.looValik(elemendinimi+"Minut", 0, 59, m[4], samm=5) return tulemus def muutmisVorm(self, REQUEST, liikumisURL): "Muutmisvorm ZPT kaudu" return self.qtTimeSettings(REQUEST, liikumisURL) def muutmisLeht(self, REQUEST, liikumisURL='',returnaway=1): "Tulemuste talletus" self.algusAeg=mkTime(REQUEST, "algusAeg") self.loppAeg=mkTime(REQUEST, "loppAeg") try: self.kordadeArv=int(REQUEST['kordadearv']) except: self.kordadeArv=-1 if liikumisURL!='': REQUEST.RESPONSE.redirect(liikumisURL) else: if returnaway: REQUEST.RESPONSE.redirect('muutmisVorm') def index_html(self, REQUEST,liikumisURL=''): "Avaleht" return self.muutmisVorm(REQUEST,liikumisURL) def leivaPuru(self, REQUEST, viimane=0): "Teekond üles" nimi=self.id+" lahendusaeg" if viimane: tekst=nimi else: tekst=""+nimi+"" return self.aq_parent.leivaPuru(REQUEST)+" > "+tekst class TestiVastused( OFS.Folder.Folder, Persistent, AccessControl.Role.RoleManager, Traversable, Cruft ): "Testi vastusvariant" testinimi="" koguKommentaar="" def ylesanded(self): "Ülesannete kogum" return self.objectValues() def kommentaarideSalvestusLeht(self, REQUEST): "Õpetaja kommentaaride salvestus" import re for x in self.ylesanded(): if hasattr(REQUEST, 'opetajapunktid'+x.id) and len(getattr(REQUEST,'opetajapunktid'+x.id))>0: try: x.seaOpetajaPunktid(float(re.sub(",", ".", getattr(REQUEST,'opetajapunktid'+x.id)))) x.seaPunktiArvutus(1) except: x.seaPunktiArvutus(0) else: x.seaOpetajaPunktid(None) x.seaPunktiArvutus(0) if hasattr(REQUEST, 'opetajakommentaar'+x.id): x.seaOpetajaKommentaar(getattr(REQUEST, 'opetajakommentaar'+x.id)) self.seaKoguKommentaar(REQUEST.koguKommentaar) # REQUEST.RESPONSE.redirect('vastusteKommenteeritavTabel') REQUEST.RESPONSE.redirect('qtTestAnswerCommentingTable') def seaKoguKommentaar(self, koguKommentaar): "Salvestatakse õpetaja kommentaar kogu lahendusvariandile" self.koguKommentaar=strip_tags(koguKommentaar) def kysiKommentaar(self,REQUEST=None): return self.annaKoguKommentaar() def annaKoguKommentaar(self): "Kommentaari väljastus" return self.koguKommentaar def koguKommentaarHTML(self, REQUEST): "Kogu kommentaar HTML-ina" return self.annaKoguKommentaar() def lyhiKokkuvoteOpetajale(self, REQUEST): "Kokkuvote" tulemus=self.punktiArvutusHTML(REQUEST) for x in self.ylesanded(): if len(x.annaOpetajaKommentaar())>0: tulemus=tulemus+"
\n"+x.opetajaKommentaarHTML(REQUEST) if len(self.koguKommentaarHTML(REQUEST))>0: tulemus=tulemus+"

"+self.koguKommentaarHTML(REQUEST) return tulemus def pihtasSumma(self): "Tabamusega ylesannete summa" summa=0 for x in self.ylesanded(): if x.kasPihtas(): summa=summa+1 return summa def punktiSumma(self): "Ülesannete punktisumma" summa=0 for x in self.ylesanded(): try: if x.kasPunktiArvutus(): summa=summa+int(x.punkte()) except Exception, probleem: pass return summa def isAllPointsCalculating(self): """ all quizes contain kasPunktiArvutus method """ for x in self.ylesanded(): if not x.kasPunktiArvutus(): return 0 return 1 def normPunktiSumma(self): "Väärtused, mis annavad kokku 100%" summa=0 for x in self.ylesanded(): if x.kasPunktiArvutus(): summa=summa+x.annaNormPunktid() return summa def punktiProtsent(self, REQUEST): "%" if self.normPunktiSumma()==0: return "Protsendiarvutus puudub" return str(round(self.punktiSumma()*100/self.normPunktiSumma(), 2))+" %" def punktiArvutusHTML(self, REQUEST): "Tulemuste väljastus" return str(round(self.punktiSumma(),2))+" / "+str(round(self.normPunktiSumma(), 2))+\ ", "+self.punktiProtsent(REQUEST) def punktiArvutusLyhiHTML(self, REQUEST): "Tulemuste väljastus" return str(round(self.punktiSumma(), 2))+" / "+str(self.normPunktiSumma()) def leivaPuru(self, REQUEST, viimane=0): "Teekond üles" nimi=self.testinimi if viimane: tekst=nimi else: tekst=""+nimi+"" if self.fle_root().kas_opetaja(self, REQUEST): testipuru=""+'L_it_tests'+"" else: testipuru=translate(self, 'L_it_tests', target=self.giveLanguage(REQUEST)) return " > "+testipuru+" > "+tekst+" > "+translate(self, 'L_it_answers', target=self.giveLanguage(REQUEST))+" " def index_html(self, REQUEST): "Peegel veebi" return self.qtTestAnswerTable() Globals.InitializeClass(TestiVastused) Globals.default__class_init__(TestiVastused)