# -*- coding: utf-8 # Copyright 2005 by Vahur Rebas from Products.Archetypes.public import BaseSchema, Schema from Products.Archetypes.public import LinesField, TextField, StringField from Products.Archetypes.public import SelectionWidget, RichWidget, StringWidget from AccessControl import ClassSecurityInfo from Products.Archetypes.public import registerType, BaseContent from Products.CMFCore.utils import getToolByName from Products.Krihvel.Permissions import * from Products.Krihvel.BaseTask import BaseTask, BaseAnswer from Products.Krihvel.config import PROJECT_NAME schema =BaseSchema + BaseTask.schema + Schema(( TextField('Exercise', accessor='getExercise', isMetadata=0, required=True, validators = ('isTidyHtmlWithCleanup',), default_output_type = 'text/x-html-safe', allowable_content_types = ('text/html',), widget = RichWidget( label="Exercise", description="Write or copy here exercises body text, all words you want to be caps that student can fill, must be in bold (B button), for example 'i have big apple' will be structured as 'i have ___ apple in exercise'", label_msgid='label_exercise', description_msgid='desc_exercise_fillin', visible={'view':'visible','edit':'visible'}, i18n_domain="krihvel", rows = 25) ), StringField('CapType', required=1, accessor="getCapType", isMetadata=1, default='Textbox', vocabulary=['Textbox','Dropdown'], widget=SelectionWidget( format="radio", label="Cap type", label_msgid='label_captype', description="How caps will be generated?", description_msgid='desc_captype', i18n_domain="krihvel"), ), StringField('CapSize', required=1, accessor="getCapSize", isMetadata=1, default='10', widget=StringWidget( size="10", label="Cap size", label_msgid='label_capsize', description="Important only if you used textbox as cap, describe here width of the cap, default is 10 but normally it can be 1-20 or longer if needed. For example textbox below is sized 10", description_msgid='desc_capsize', i18n_domain="krihvel"), ), StringField('ShowOriginal', required=1, accessor="getShowOriginal", isMetadata=1, default='Yes', vocabulary=['Yes','No'], widget=SelectionWidget( format="radio", label="Show original text", label_msgid='label_showoriginal', description="Show original text in answer?", description_msgid='desc_showoriginal', i18n_domain="krihvel"), ), )) class BaseFillIn(BaseTask): """ BaseFillIn module. """ security.declareProtected('View', 'getReplacedExercise') def getReplacedExercise(self): """ gets caps from text """ text = self.getExercise().replace("","") text = text.replace("","") return text security.declareProtected('View', 'getCaps') def getCaps(self): """ gets caps from text """ caps = [] text = self.getReplacedExercise() for cap in text.split(''): caps.append(cap.split('')[0]) caps.pop(0) return caps security.declareProtected('View', 'getCapsForExercise') def getCapsForExercise(self, type=None): """ gets caps from text """ caps = [] for cap in self.getCaps(): if cap not in caps: caps.append(cap) if type=='sort': caps.sort() elif type=='mix': c=0 import random while c'): text.append(t.split('')[0]) return text security.declareProtected('View', 'saveFilledCaps') def saveFilledCaps(self, REQUEST): """ gets filled caps """ nr = 0 filledCaps = [] checkOuts = [] for cap in self.getCaps(): filled_cap = REQUEST.get('cap_'+str(nr)) filledCaps.append(filled_cap) if str(cap).lower() == str(filled_cap).lower(): checkOuts.append(True) else: checkOuts.append(False) nr = nr + 1 self.answers = filledCaps self.correct = checkOuts self._p_changed = 1 return filledCaps security.declareProtected('View', 'getFilledCaps') def getFilledCaps(self): """ gets filled caps """ return self.answers class FillIn(BaseTask, BaseFillIn): """ FillIn module. """ meta_type = "FillIn" archetype_name = "FillIn" allowed_content_types = () global_allow = 0 security = ClassSecurityInfo() schema = schema actions = ( { 'id':'view', 'name':'View', 'action':'string:${object_url}/fillin_answer', 'permissions': ('View',), }, ) security.declareProtected('View', 'saveAnswer') def saveAnswer(self, REQUEST): """ Saves Answer """ user = str(REQUEST.AUTHENTICATED_USER) homefolder = self.portal_membership.getHomeFolder(user) number = 1 typestool = getToolByName(self, 'portal_types') puf_type = getattr(typestool, 'FillInAnswer', None) if not puf_type: return 0 puf_type.global_allow = 1 while hasattr(homefolder, 'FillInAnswer-'+str(number)): number = number+1 newid = 'FillInAnswer-'+str(number) id = homefolder.invokeFactory("FillInAnswer", id=newid, title=self.title, Exercise=self.Exercise, Instruction=self.Instruction, Target=self.id, ShowOriginal=self.ShowOriginal) copiedObj = getattr(homefolder,id) copiedObj.answers = self.saveFilledCaps(REQUEST) copiedObj.correct = self.correct puf_type.global_allow = 0 self.addRefsToWhat('refsToThisTask', copiedObj) copiedObj.addRefsToWhat('refsToThisTask', self) return copiedObj registerType(FillIn, PROJECT_NAME) class FillInAnswer(BaseAnswer, BaseFillIn): """ Paper module. """ meta_type = "FillInAnswer" archetype_name = "FillInAnswer" allowed_content_types = [] global_allow = 0 security = ClassSecurityInfo() content_icon='vastus.gif' schema = schema actions = ( { 'id':'view', 'name':'View', 'action':'string:${object_url}/fillin_answer', 'permissions': ('View',), }, ) def __init__(self, id): self.id = id self.answers = [] self.correct = [] security.declareProtected('View', 'getAnswer') def getAnswer(self): """ get answer """ nr = 0 answer = '' for text in self.getText(): answer = answer + text if len(self.getFilledCaps())>nr: answer = answer + '' +self.getFilledCaps()[nr] + '' nr = nr + 1 return answer security.declareProtected('View', 'getCheckOut') def getCheckOut(self): """ get checkOut """ nr = 0 checkOut = [] for cap in self.getCaps(): if self.correct != []: correct = self.correct[nr] elif cap.lower()==self.getFilledCaps()[nr].lower(): correct = True else: correct = False checkOut.append({'cap':cap,'filled':self.getFilledCaps()[nr],'correct':correct}) nr = nr + 1 return checkOut security.declareProtected('View', 'rateAnswers') def rateAnswers(self, REQUEST): """ rate answers """ nr = 0 checkOut = [] for cap in self.getCaps(): if REQUEST.get('check_answer_'+str(nr))=='on': checkOut.append(True) else: checkOut.append(False) nr = nr + 1 self.correct = checkOut self._p_changed = 1 security.declareProtected('View', 'getRating') def getRating(self): """ get rating """ nr = 0 correct = 0 for answer in self.correct: if answer: correct = correct + 1 nr = nr + 1 if correct == 0: return 0 percent = correct * 100 / nr return percent security.declareProtected('View', 'getCorrect') def getCorrect(self): """ get correct answers """ return self.correct registerType(FillInAnswer, PROJECT_NAME)