From daf51b72bdb2676efc4acdbd69d3352a0a05c1ea Mon Sep 17 00:00:00 2001 From: Andreas Schwenk Date: Mon, 19 Aug 2024 21:40:34 +0200 Subject: [PATCH] v1.2.4 bug fixing --- .vscode/settings.json | 1 + CHANGELOG | 5 + docs/ex1.html | 4 +- sell.py | 527 +++++++++++++++++++++--------------------- web/src/eval.js | 3 +- web/src/math.js | 2 + web/src/question.js | 2 + 7 files changed, 278 insertions(+), 266 deletions(-) diff --git a/.vscode/settings.json b/.vscode/settings.json index 8305a04..871fa63 100644 --- a/.vscode/settings.json +++ b/.vscode/settings.json @@ -26,6 +26,7 @@ "dans", "displaystyle", "dsolve", + "eigenvals", "ejecuta", "elif", "erreurs", diff --git a/CHANGELOG b/CHANGELOG index 8485309..bfc6a41 100644 --- a/CHANGELOG +++ b/CHANGELOG @@ -1,3 +1,8 @@ +# v1.2.4 + +- bug fix: the internal counter for single/multiple choice sections was not reset after retrying a question +- bug fix: context-sensitive boolean variables were not correctly compared. + # v1.2.3 - bug fix: single-choice answers with at least 5 options no longer produce strange progress hints to the student diff --git a/docs/ex1.html b/docs/ex1.html index 1953f25..de2cf4b 100644 --- a/docs/ex1.html +++ b/docs/ex1.html @@ -1,4 +1,4 @@ - pySELL Quiz

DEBUG VERSION

This quiz was created using pySELL, the Python-based Simple E-Learning Language, written by Andreas Schwenk, GPLv3
last update on

DEBUG VERSION

This quiz was created using pySELL, the Python-based Simple E-Learning Language, written by Andreas Schwenk, GPLv3
last update on

\ No newline at end of file + `.includes(s)==!1&&(this.token+=s),this.pos++}}isNum(e){return e.charCodeAt(0)>=48&&e.charCodeAt(0)<=57}isAlpha(e){return e.charCodeAt(0)>=65&&e.charCodeAt(0)<=90||e.charCodeAt(0)>=97&&e.charCodeAt(0)<=122||e==="_"}toString(){return this.root==null?"":this.root.toString()}toTexString(){return this.root==null?"":this.root.toTexString()}},f=class r{constructor(e,t,i=0,s=0){this.op=e,this.c=t,this.re=i,this.im=s,this.explicitParentheses=!1}clone(){let e=new r(this.op,this.c.map(t=>t.clone()),this.re,this.im);return e.explicitParentheses=this.explicitParentheses,e}static const(e=0,t=0){return new r("const",[],e,t)}compare(e,t=0,i=1e-9){let s=this.re-e,l=this.im-t;return Math.sqrt(s*s+l*l)1e-14,i=Math.abs(this.im)>1e-14;t&&i&&this.im>=0?e="("+this.re+"+"+this.im+"i)":t&&i&&this.im<0?e="("+this.re+"-"+-this.im+"i)":t&&this.re>0?e=""+this.re:t&&this.re<0?e="("+this.re+")":i?e="("+this.im+"i)":e="0"}else this.op.startsWith("var")?e=this.op.split(":")[1]:this.c.length==1?e=(this.op===".-"?"-":this.op)+"("+this.c.toString()+")":e="("+this.c.map(t=>t.toString()).join(this.op)+")";return e}toTexString(e=!1){let i="";switch(this.op){case"const":{let s=Math.abs(this.re)>1e-9,l=Math.abs(this.im)>1e-9,a=s?""+this.re:"",h=l?""+this.im+"i":"";h==="1i"?h="i":h==="-1i"&&(h="-i"),!s&&!l?i="0":(l&&this.im>=0&&s&&(h="+"+h),i=a+h);break}case".-":i="-"+this.c[0].toTexString();break;case"+":case"-":case"*":case"^":{let s=this.c[0].toTexString(),l=this.c[1].toTexString(),a=this.op==="*"?"\\cdot ":this.op;i="{"+s+"}"+a+"{"+l+"}";break}case"/":{let s=this.c[0].toTexString(!0),l=this.c[1].toTexString(!0);i="\\frac{"+s+"}{"+l+"}";break}case"sin":case"sinc":case"cos":case"tan":case"cot":case"exp":case"ln":{let s=this.c[0].toTexString(!0);i+="\\"+this.op+"\\left("+s+"\\right)";break}case"sqrt":{let s=this.c[0].toTexString(!0);i+="\\"+this.op+"{"+s+"}";break}case"abs":{let s=this.c[0].toTexString(!0);i+="\\left|"+s+"\\right|";break}default:if(this.op.startsWith("var:")){let s=this.op.substring(4);switch(s){case"pi":s="\\pi";break}i=" "+s+" "}else{let s="warning: Node.toString(..):";s+=" unimplemented operator '"+this.op+"'",console.log(s),i=this.op,this.c.length>0&&(i+="\\left({"+this.c.map(l=>l.toTexString(!0)).join(",")+"}\\right)")}}return!e&&this.explicitParentheses&&(i="\\left({"+i+"}\\right)"),i}};function ie(r,e){let t=1e-9;if(k.compare(r,e))return!0;r=r.clone(),e=e.clone(),N(r.root),N(e.root);let i=new Set;r.getVars(i),e.getVars(i);let s=[],l=[];for(let n of i.keys())n.startsWith("C")?s.push(n):l.push(n);let a=s.length;for(let n=0;n{r.feedbackPopupDiv.style.display="none"},500),r.state===b.passed?r.src.instances.length>0?r.checkAndRepeatBtn.innerHTML=te:r.checkAndRepeatBtn.style.display="none":r.checkAndRepeatBtn.innerHTML=I}var A=class{constructor(e,t,i,s){this.question=t,this.inputId=i,i.length==0&&(this.inputId=i="gap-"+t.gapIdx,t.types[this.inputId]="string",t.expected[this.inputId]=s,t.gapIdx++),i in t.student||(t.student[i]="");let l=s.split("|"),a=0;for(let c=0;ca&&(a=u.length)}let h=v("");e.appendChild(h);let n=Math.max(a*15,24),o=R(n);if(t.gapInputs[this.inputId]=o,o.addEventListener("keyup",()=>{this.question.editedQuestion(),o.value=o.value.toUpperCase(),this.question.student[this.inputId]=o.value.trim()}),h.appendChild(o),this.question.showSolution&&(this.question.student[this.inputId]=o.value=l[0],l.length>1)){let c=v("["+l.join("|")+"]");c.style.fontSize="small",c.style.textDecoration="underline",h.appendChild(c)}}},D=class{constructor(e,t,i,s,l,a,h=!1){i in t.student||(t.student[i]=""),this.question=t,this.inputId=i,this.outerSpan=v(""),this.outerSpan.style.position="relative",e.appendChild(this.outerSpan),this.inputElement=R(Math.max(s*12,48)),this.outerSpan.appendChild(this.inputElement),this.equationPreviewDiv=x(),this.equationPreviewDiv.classList.add("equationPreview"),this.equationPreviewDiv.style.display="none",this.outerSpan.appendChild(this.equationPreviewDiv),this.inputElement.addEventListener("click",()=>{this.question.editedQuestion(),this.edited()}),this.inputElement.addEventListener("keyup",()=>{this.question.editedQuestion(),this.edited()}),this.inputElement.addEventListener("focusout",()=>{this.equationPreviewDiv.innerHTML="",this.equationPreviewDiv.style.display="none"}),this.inputElement.addEventListener("keydown",n=>{let o="abcdefghijklmnopqrstuvwxyz";o+="ABCDEFGHIJKLMNOPQRSTUVWXYZ",o+="0123456789",o+="+-*/^(). <>=|",a&&(o="-0123456789"),n.key.length<3&&o.includes(n.key)==!1&&n.preventDefault();let c=this.inputElement.value.length*12;this.inputElement.offsetWidth0&&!i?"block":"none",this.question.student[this.inputId]=e}},V=class{constructor(e,t,i,s){this.parent=e,this.question=t,this.inputId=i,this.matExpected=new E(0,0),this.matExpected.fromString(s),this.matStudent=new E(this.matExpected.m==1?1:3,this.matExpected.n==1?1:3),t.showSolution&&this.matStudent.fromMatrix(this.matExpected),this.genMatrixDom(!0)}genMatrixDom(e){let t=x();this.parent.innerHTML="",this.parent.appendChild(t),t.style.position="relative",t.style.display="inline-block";let i=document.createElement("table");t.appendChild(i);let s=this.matExpected.getMaxCellStrlen();for(let p=0;p=10,this.matStudent.n<=1,this.matStudent.m>=10,this.matStudent.m<=1];for(let p=0;p<4;p++){if(u[p]==!1)continue;let m=v(l[p]);n[p]!=888&&(m.style.top=""+n[p]+"px"),o[p]!=888&&(m.style.bottom=""+o[p]+"px"),c[p]!=888&&(m.style.right=""+c[p]+"px"),m.classList.add("matrixResizeButton"),t.appendChild(m),d[p]?m.style.opacity="0.5":m.addEventListener("click",()=>{for(let g=0;g=5&&(this.feedbackSpan.innerHTML=""+this.numCorrect+" / "+this.numChecked);break}this.questionDiv.style.color=this.feedbackSpan.style.color=this.titleDiv.style.color=this.checkAndRepeatBtn.style.backgroundColor=this.questionDiv.style.borderColor=e,this.questionDiv.style.backgroundColor=t}populateDom(){if(this.parentDiv.innerHTML="",this.questionDiv=x(),this.parentDiv.appendChild(this.questionDiv),this.questionDiv.classList.add("question"),this.feedbackPopupDiv=x(),this.feedbackPopupDiv.classList.add("questionFeedback"),this.questionDiv.appendChild(this.feedbackPopupDiv),this.feedbackPopupDiv.innerHTML="awesome",this.debug&&"src_line"in this.src){let s=x();s.classList.add("debugInfo"),s.innerHTML="Source code: lines "+this.src.src_line+"..",this.questionDiv.appendChild(s)}if(this.titleDiv=x(),this.questionDiv.appendChild(this.titleDiv),this.titleDiv.classList.add("questionTitle"),this.titleDiv.innerHTML=this.src.title,this.src.error.length>0){let s=v(this.src.error);this.questionDiv.appendChild(s),s.style.color="red";return}let e=this.getCurrentInstance();if(e!=null&&"__svg_image"in e){let s=e.__svg_image.v,l=x();this.questionDiv.appendChild(l);let a=document.createElement("img");l.appendChild(a),a.classList.add("img"),a.src="data:image/svg+xml;base64,"+s}for(let s of this.src.text.c)this.questionDiv.appendChild(this.generateText(s));let t=x();this.questionDiv.appendChild(t),t.classList.add("buttonRow"),this.hasCheckButton=Object.keys(this.expected).length>0,this.hasCheckButton&&(this.checkAndRepeatBtn=j(),t.appendChild(this.checkAndRepeatBtn),this.checkAndRepeatBtn.innerHTML=I,this.checkAndRepeatBtn.style.backgroundColor="black");let i=v("   ");if(t.appendChild(i),this.feedbackSpan=v(""),t.appendChild(this.feedbackSpan),this.debug){if(this.src.variables.length>0){let a=x();a.classList.add("debugInfo"),a.innerHTML="Variables generated by Python Code",this.questionDiv.appendChild(a);let h=x();h.classList.add("debugCode"),this.questionDiv.appendChild(h);let n=this.getCurrentInstance(),o="",c=[...this.src.variables];c.sort();for(let u of c){let d=n[u].t,p=n[u].v;switch(d){case"vector":p="["+p+"]";break;case"set":p="{"+p+"}";break}o+=d+" "+u+" = "+p+"
"}h.innerHTML=o}let s=["python_src_html","text_src_html"],l=["Python Source Code","Text Source Code"];for(let a=0;a0){let n=x();n.classList.add("debugInfo"),n.innerHTML=l[a],this.questionDiv.appendChild(n);let o=x();o.classList.add("debugCode"),this.questionDiv.append(o),o.innerHTML=this.src[h]}}}this.hasCheckButton&&this.checkAndRepeatBtn.addEventListener("click",()=>{this.state==b.passed?(this.state=b.init,this.reset(),this.populateDom()):se(this)})}generateMathString(e){let t="";switch(e.t){case"math":case"display-math":for(let i of e.c){let s=this.generateMathString(i);i.t==="var"&&t.includes("!PM")&&(s.startsWith("{-")?(s="{"+s.substring(2),t=t.replaceAll("!PM","-")):t=t.replaceAll("!PM","+")),t+=s}break;case"text":return e.d;case"plus_minus":{t+=" !PM ";break}case"var":{let i=this.getCurrentInstance(),s=i[e.d].t,l=i[e.d].v;switch(s){case"vector":return"\\left["+l+"\\right]";case"set":return"\\left\\{"+l+"\\right\\}";case"complex":{let a=l.split(","),h=parseFloat(a[0]),n=parseFloat(a[1]);return f.const(h,n).toTexString()}case"matrix":{let a=new E(0,0);return a.fromString(l),t=a.toTeXString(e.d.includes("augmented"),this.language!="de"),t}case"term":{try{t=k.parse(l).toTexString()}catch{}break}default:t=l}}}return e.t==="plus_minus"?t:"{"+t+"}"}generateText(e,t=!1){switch(e.t){case"paragraph":case"span":{let i=document.createElement(e.t=="span"||t?"span":"p");for(let s of e.c)i.appendChild(this.generateText(s));return i}case"text":return v(e.d);case"code":{let i=v(e.d);return i.classList.add("code"),i}case"italic":case"bold":{let i=v("");return i.append(...e.c.map(s=>this.generateText(s))),e.t==="bold"?i.style.fontWeight="bold":i.style.fontStyle="italic",i}case"math":case"display-math":{let i=this.generateMathString(e);return T(i,e.t==="display-math")}case"string_var":{let i=v(""),s=this.getCurrentInstance(),l=s[e.d].t,a=s[e.d].v;return l==="string"?i.innerHTML=a:(i.innerHTML="EXPECTED VARIABLE OF TYPE STRING",i.style.color="red"),i}case"gap":{let i=v("");return new A(i,this,"",e.d),i}case"input":case"input2":{let i=e.t==="input2",s=v("");s.style.verticalAlign="text-bottom";let l=e.d,a=this.getCurrentInstance()[l];if(this.expected[l]=a.v,this.types[l]=a.t,!i)switch(a.t){case"set":s.append(T("\\{"),v(" "));break;case"vector":s.append(T("["),v(" "));break}if(a.t==="string")new A(s,this,l,this.expected[l]);else if(a.t==="vector"||a.t==="set"){let h=a.v.split(","),n=h.length;for(let o=0;o0&&s.appendChild(v(" , "));let c=l+"-"+o;new D(s,this,c,h[o].length,h[o],!1)}}else if(a.t==="matrix"){let h=x();s.appendChild(h),new V(h,this,l,a.v)}else if(a.t==="complex"){let h=a.v.split(",");new D(s,this,l+"-0",h[0].length,h[0],!1),s.append(v(" "),T("+"),v(" ")),new D(s,this,l+"-1",h[1].length,h[1],!1),s.append(v(" "),T("i"))}else{let h=a.t==="int";new D(s,this,l,a.v.length,a.v,h)}if(!i)switch(a.t){case"set":s.append(v(" "),T("\\}"));break;case"vector":s.append(v(" "),T("]"));break}return s}case"itemize":return z(e.c.map(i=>U(this.generateText(i))));case"single-choice":case"multi-choice":{let i=e.t=="multi-choice";i||(this.includesSingleChoice=!0);let s=document.createElement("table"),l=e.c.length,a=this.debug==!1,h=P(l,a),n=i?J:ee,o=i?G:$,c=[],u=[];for(let d=0;d{this.editedQuestion(),this.student[g]=this.student[g]==="true"?"false":"true",this.student[g]==="true"?S.innerHTML=n:S.innerHTML=o}):C.addEventListener("click",()=>{this.editedQuestion();for(let L of u)this.student[L]="false";this.student[g]="true";for(let L=0;L";document.getElementById("courseInfo2").innerHTML=F[r.lang].replace("*",t);let i=[],s=document.getElementById("questions"),l=1;for(let a of r.questions){a.title=""+l+". "+a.title;let h=x();s.appendChild(h);let n=new H(h,a,r.lang,e);n.showSolution=e,i.push(n),n.populateDom(),e&&a.error.length==0&&n.hasCheckButton&&n.checkAndRepeatBtn.click(),l++}}return he(de);})();sell.init(quizSrc,debug); \ No newline at end of file diff --git a/sell.py b/sell.py index 2a01d50..faf4698 100755 --- a/sell.py +++ b/sell.py @@ -994,7 +994,7 @@ def compile_input_file(input_dirname: str, src: str) -> dict: HTML += b' e=="function")for(let s of ne(e))!ae.call(r,s)&&s!==t&&B(r,' HTML += b's,{get:()=>e[s],enumerable:!(i=re(e,s))||i.enumerable});retu' HTML += b'rn r};var he=r=>oe(B({},"__esModule",{value:!0}),r);var de={' -HTML += b'};le(de,{init:()=>pe});function b(r=[]){let e=document.creat' +HTML += b'};le(de,{init:()=>pe});function x(r=[]){let e=document.creat' HTML += b'eElement("div");return e.append(...r),e}function z(r=[]){let' HTML += b' e=document.createElement("ul");return e.append(...r),e}func' HTML += b'tion U(r){let e=document.createElement("li");return e.append' @@ -1269,268 +1269,269 @@ def compile_input_file(input_dirname: str, src: str) -> dict: HTML += b'HTML="",r.numChecked=0,r.numCorrect=0;let e=!0;for(let s in ' HTML += b'r.expected){let l=r.types[s],a=r.student[s],h=r.expected[s];' HTML += b'switch(a!=null&&a.length==0&&(e=!1),l){case"bool":r.numCheck' -HTML += b'ed++,a===h&&r.numCorrect++;break;case"string":{r.numChecked+' -HTML += b'+;let n=r.gapInputs[s],o=a.trim().toUpperCase(),c=h.trim().t' -HTML += b'oUpperCase().split("|"),u=!1;for(let d of c)if(Y(o,d)<=1){u=' -HTML += b'!0,r.numCorrect++,r.gapInputs[s].value=d,r.student[s]=d;brea' -HTML += b'k}n.style.color=u?"black":"white",n.style.backgroundColor=u?' -HTML += b'"transparent":"maroon";break}case"int":r.numChecked++,Math.a' -HTML += b'bs(parseFloat(a)-parseFloat(h))<1e-9&&r.numCorrect++;break;c' -HTML += b'ase"float":case"term":{r.numChecked++;try{let n=k.parse(h),o' -HTML += b'=k.parse(a),c=!1;r.src.is_ode?c=ie(n,o):c=k.compare(n,o),c&&' -HTML += b'r.numCorrect++}catch(n){r.debug&&(console.log("term invalid"' -HTML += b'),console.log(n))}break}case"vector":case"complex":case"set"' -HTML += b':{let n=h.split(",");r.numChecked+=n.length;let o=[];for(let' -HTML += b' c=0;c{r.feedbackPopupDiv.style.display="none"},500),r' -HTML += b'.state===x.passed?r.src.instances.length>0?r.checkAndRepeatB' -HTML += b'tn.innerHTML=te:r.checkAndRepeatBtn.style.display="none":r.c' -HTML += b'heckAndRepeatBtn.innerHTML=I}var A=class{constructor(e,t,i,s' -HTML += b'){this.question=t,this.inputId=i,i.length==0&&(this.inputId=' -HTML += b'i="gap-"+t.gapIdx,t.types[this.inputId]="string",t.expected[' -HTML += b'this.inputId]=s,t.gapIdx++),i in t.student||(t.student[i]=""' -HTML += b');let l=s.split("|"),a=0;for(let c=0;ca&&(a=u.length)}let h=v("");e.appendChild(h);le' -HTML += b't n=Math.max(a*15,24),o=R(n);if(t.gapInputs[this.inputId]=o,' -HTML += b'o.addEventListener("keyup",()=>{this.question.editedQuestion' -HTML += b'(),o.value=o.value.toUpperCase(),this.question.student[this.' -HTML += b'inputId]=o.value.trim()}),h.appendChild(o),this.question.sho' -HTML += b'wSolution&&(this.question.student[this.inputId]=o.value=l[0]' -HTML += b',l.length>1)){let c=v("["+l.join("|")+"]");c.style.fontSize=' -HTML += b'"small",c.style.textDecoration="underline",h.appendChild(c)}' -HTML += b'}},D=class{constructor(e,t,i,s,l,a,h=!1){i in t.student||(t.' -HTML += b'student[i]=""),this.question=t,this.inputId=i,this.outerSpan' -HTML += b'=v(""),this.outerSpan.style.position="relative",e.appendChil' -HTML += b'd(this.outerSpan),this.inputElement=R(Math.max(s*12,48)),thi' -HTML += b's.outerSpan.appendChild(this.inputElement),this.equationPrev' -HTML += b'iewDiv=b(),this.equationPreviewDiv.classList.add("equationPr' -HTML += b'eview"),this.equationPreviewDiv.style.display="none",this.ou' -HTML += b'terSpan.appendChild(this.equationPreviewDiv),this.inputEleme' -HTML += b'nt.addEventListener("click",()=>{this.question.editedQuestio' -HTML += b'n(),this.edited()}),this.inputElement.addEventListener("keyu' -HTML += b'p",()=>{this.question.editedQuestion(),this.edited()}),this.' -HTML += b'inputElement.addEventListener("focusout",()=>{this.equationP' -HTML += b'reviewDiv.innerHTML="",this.equationPreviewDiv.style.display' -HTML += b'="none"}),this.inputElement.addEventListener("keydown",n=>{l' -HTML += b'et o="abcdefghijklmnopqrstuvwxyz";o+="ABCDEFGHIJKLMNOPQRSTUV' -HTML += b'WXYZ",o+="0123456789",o+="+-*/^(). <>=|",a&&(o="-0123456789"' -HTML += b'),n.key.length<3&&o.includes(n.key)==!1&&n.preventDefault();' -HTML += b'let c=this.inputElement.value.length*12;this.inputElement.of' -HTML += b'fsetWidth0&&!i?"block":"none",this.qu' -HTML += b'estion.student[this.inputId]=e}},V=class{constructor(e,t,i,s' -HTML += b'){this.parent=e,this.question=t,this.inputId=i,this.matExpec' -HTML += b'ted=new E(0,0),this.matExpected.fromString(s),this.matStuden' -HTML += b't=new E(this.matExpected.m==1?1:3,this.matExpected.n==1?1:3)' -HTML += b',t.showSolution&&this.matStudent.fromMatrix(this.matExpected' -HTML += b'),this.genMatrixDom(!0)}genMatrixDom(e){let t=b();this.paren' -HTML += b't.innerHTML="",this.parent.appendChild(t),t.style.position="' -HTML += b'relative",t.style.display="inline-block";let i=document.crea' -HTML += b'teElement("table");t.appendChild(i);let s=this.matExpected.g' -HTML += b'etMaxCellStrlen();for(let p=0;p=10,this.matStudent.n<=1,this.matStudent.m>=10,this.matS' -HTML += b'tudent.m<=1];for(let p=0;p<4;p++){if(u[p]==!1)continue;let m' -HTML += b'=v(l[p]);n[p]!=888&&(m.style.top=""+n[p]+"px"),o[p]!=888&&(m' -HTML += b'.style.bottom=""+o[p]+"px"),c[p]!=888&&(m.style.right=""+c[p' -HTML += b']+"px"),m.classList.add("matrixResizeButton"),t.appendChild(' -HTML += b'm),d[p]?m.style.opacity="0.5":m.addEventListener("click",()=' -HTML += b'>{for(let g=0;g=5&&(this.feedbackSpan.innerHTML' -HTML += b'=""+this.numCorrect+" / "+this.numChecked);break}this.questi' -HTML += b'onDiv.style.color=this.feedbackSpan.style.color=this.titleDi' -HTML += b'v.style.color=this.checkAndRepeatBtn.style.backgroundColor=t' -HTML += b'his.questionDiv.style.borderColor=e,this.questionDiv.style.b' -HTML += b'ackgroundColor=t}populateDom(){if(this.parentDiv.innerHTML="' -HTML += b'",this.questionDiv=b(),this.parentDiv.appendChild(this.quest' -HTML += b'ionDiv),this.questionDiv.classList.add("question"),this.feed' -HTML += b'backPopupDiv=b(),this.feedbackPopupDiv.classList.add("questi' -HTML += b'onFeedback"),this.questionDiv.appendChild(this.feedbackPopup' -HTML += b'Div),this.feedbackPopupDiv.innerHTML="awesome",this.debug&&"' -HTML += b'src_line"in this.src){let s=b();s.classList.add("debugInfo")' -HTML += b',s.innerHTML="Source code: lines "+this.src.src_line+"..",th' -HTML += b'is.questionDiv.appendChild(s)}if(this.titleDiv=b(),this.ques' -HTML += b'tionDiv.appendChild(this.titleDiv),this.titleDiv.classList.a' -HTML += b'dd("questionTitle"),this.titleDiv.innerHTML=this.src.title,t' -HTML += b'his.src.error.length>0){let s=v(this.src.error);this.questio' -HTML += b'nDiv.appendChild(s),s.style.color="red";return}let e=this.ge' -HTML += b'tCurrentInstance();if(e!=null&&"__svg_image"in e){let s=e.__' -HTML += b'svg_image.v,l=b();this.questionDiv.appendChild(l);let a=docu' -HTML += b'ment.createElement("img");l.appendChild(a),a.classList.add("' -HTML += b'img"),a.src="data:image/svg+xml;base64,"+s}for(let s of this' -HTML += b'.src.text.c)this.questionDiv.appendChild(this.generateText(s' -HTML += b'));let t=b();this.questionDiv.appendChild(t),t.classList.add' -HTML += b'("buttonRow"),this.hasCheckButton=Object.keys(this.expected)' -HTML += b'.length>0,this.hasCheckButton&&(this.checkAndRepeatBtn=j(),t' -HTML += b'.appendChild(this.checkAndRepeatBtn),this.checkAndRepeatBtn.' -HTML += b'innerHTML=I,this.checkAndRepeatBtn.style.backgroundColor="bl' -HTML += b'ack");let i=v("   ");if(t.appendChild(i),this' -HTML += b'.feedbackSpan=v(""),t.appendChild(this.feedbackSpan),this.de' -HTML += b'bug){if(this.src.variables.length>0){let a=b();a.classList.a' -HTML += b'dd("debugInfo"),a.innerHTML="Variables generated by Python C' -HTML += b'ode",this.questionDiv.appendChild(a);let h=b();h.classList.a' -HTML += b'dd("debugCode"),this.questionDiv.appendChild(h);let n=this.g' -HTML += b'etCurrentInstance(),o="",c=[...this.src.variables];c.sort();' -HTML += b'for(let u of c){let d=n[u].t,p=n[u].v;switch(d){case"vector"' -HTML += b':p="["+p+"]";break;case"set":p="{"+p+"}";break}o+=d+" "+u+" ' -HTML += b'= "+p+"
"}h.innerHTML=o}let s=["python_src_html","text_s' -HTML += b'rc_html"],l=["Python Source Code","Text Source Code"];for(le' -HTML += b't a=0;a0){let n=b();n.classList.add("debugInfo"),n.innerH' -HTML += b'TML=l[a],this.questionDiv.appendChild(n);let o=b();o.classLi' -HTML += b'st.add("debugCode"),this.questionDiv.append(o),o.innerHTML=t' -HTML += b'his.src[h]}}}this.hasCheckButton&&this.checkAndRepeatBtn.add' -HTML += b'EventListener("click",()=>{this.state==x.passed?(this.state=' -HTML += b'x.init,this.reset(),this.populateDom()):se(this)})}generateM' -HTML += b'athString(e){let t="";switch(e.t){case"math":case"display-ma' -HTML += b'th":for(let i of e.c){let s=this.generateMathString(i);i.t==' -HTML += b'="var"&&t.includes("!PM")&&(s.startsWith("{-")?(s="{"+s.subs' -HTML += b'tring(2),t=t.replaceAll("!PM","-")):t=t.replaceAll("!PM","+"' -HTML += b')),t+=s}break;case"text":return e.d;case"plus_minus":{t+=" !' -HTML += b'PM ";break}case"var":{let i=this.getCurrentInstance(),s=i[e.' -HTML += b'd].t,l=i[e.d].v;switch(s){case"vector":return"\\\\left["+l+"\\\\' -HTML += b'right]";case"set":return"\\\\left\\\\{"+l+"\\\\right\\\\}";case"comp' -HTML += b'lex":{let a=l.split(","),h=parseFloat(a[0]),n=parseFloat(a[1' -HTML += b']);return f.const(h,n).toTexString()}case"matrix":{let a=new' -HTML += b' E(0,0);return a.fromString(l),t=a.toTeXString(e.d.includes(' -HTML += b'"augmented"),this.language!="de"),t}case"term":{try{t=k.pars' -HTML += b'e(l).toTexString()}catch{}break}default:t=l}}}return e.t==="' -HTML += b'plus_minus"?t:"{"+t+"}"}generateText(e,t=!1){switch(e.t){cas' -HTML += b'e"paragraph":case"span":{let i=document.createElement(e.t=="' -HTML += b'span"||t?"span":"p");for(let s of e.c)i.appendChild(this.gen' -HTML += b'erateText(s));return i}case"text":return v(e.d);case"code":{' -HTML += b'let i=v(e.d);return i.classList.add("code"),i}case"italic":c' -HTML += b'ase"bold":{let i=v("");return i.append(...e.c.map(s=>this.ge' -HTML += b'nerateText(s))),e.t==="bold"?i.style.fontWeight="bold":i.sty' -HTML += b'le.fontStyle="italic",i}case"math":case"display-math":{let i' -HTML += b'=this.generateMathString(e);return T(i,e.t==="display-math")' -HTML += b'}case"string_var":{let i=v(""),s=this.getCurrentInstance(),l' -HTML += b'=s[e.d].t,a=s[e.d].v;return l==="string"?i.innerHTML=a:(i.in' -HTML += b'nerHTML="EXPECTED VARIABLE OF TYPE STRING",i.style.color="re' -HTML += b'd"),i}case"gap":{let i=v("");return new A(i,this,"",e.d),i}c' -HTML += b'ase"input":case"input2":{let i=e.t==="input2",s=v("");s.styl' -HTML += b'e.verticalAlign="text-bottom";let l=e.d,a=this.getCurrentIns' -HTML += b'tance()[l];if(this.expected[l]=a.v,this.types[l]=a.t,!i)swit' -HTML += b'ch(a.t){case"set":s.append(T("\\\\{"),v(" "));break;case"vecto' -HTML += b'r":s.append(T("["),v(" "));break}if(a.t==="string")new A(s,t' -HTML += b'his,l,this.expected[l]);else if(a.t==="vector"||a.t==="set")' -HTML += b'{let h=a.v.split(","),n=h.length;for(let o=0;o0&&s' -HTML += b'.appendChild(v(" , "));let c=l+"-"+o;new D(s,this,c,h[o].len' -HTML += b'gth,h[o],!1)}}else if(a.t==="matrix"){let h=b();s.appendChil' -HTML += b'd(h),new V(h,this,l,a.v)}else if(a.t==="complex"){let h=a.v.' -HTML += b'split(",");new D(s,this,l+"-0",h[0].length,h[0],!1),s.append' -HTML += b'(v(" "),T("+"),v(" ")),new D(s,this,l+"-1",h[1].length,h[1],' -HTML += b'!1),s.append(v(" "),T("i"))}else{let h=a.t==="int";new D(s,t' -HTML += b'his,l,a.v.length,a.v,h)}if(!i)switch(a.t){case"set":s.append' -HTML += b'(v(" "),T("\\\\}"));break;case"vector":s.append(v(" "),T("]"))' -HTML += b';break}return s}case"itemize":return z(e.c.map(i=>U(this.gen' -HTML += b'erateText(i))));case"single-choice":case"multi-choice":{let ' -HTML += b'i=e.t=="multi-choice";i||(this.includesSingleChoice=!0);let ' -HTML += b's=document.createElement("table"),l=e.c.length,a=this.debug=' -HTML += b'=!1,h=P(l,a),n=i?J:ee,o=i?G:$,c=[],u=[];for(let d=0;d{this.editedQu' -HTML += b'estion(),this.student[g]=this.student[g]==="true"?"false":"t' -HTML += b'rue",this.student[g]==="true"?S.innerHTML=n:S.innerHTML=o}):' -HTML += b'C.addEventListener("click",()=>{this.editedQuestion();for(le' -HTML += b't L of u)this.student[L]="false";this.student[g]="true";for(' -HTML += b'let L=0;L\'+K[r.lang]+"";document.getElementById("cou' -HTML += b'rseInfo2").innerHTML=F[r.lang].replace("*",t);let i=[],s=doc' -HTML += b'ument.getElementById("questions"),l=1;for(let a of r.questio' -HTML += b'ns){a.title=""+l+". "+a.title;let h=b();s.appendChild(h);let' -HTML += b' n=new H(h,a,r.lang,e);n.showSolution=e,i.push(n),n.populate' -HTML += b'Dom(),e&&a.error.length==0&&n.hasCheckButton&&n.checkAndRepe' -HTML += b'atBtn.click(),l++}}return he(de);})();sell.init(quizSrc,debu' -HTML += b'g); ' +HTML += b'ed++,a.toLowerCase()===h.toLowerCase()&&r.numCorrect++;break' +HTML += b';case"string":{r.numChecked++;let n=r.gapInputs[s],o=a.trim(' +HTML += b').toUpperCase(),c=h.trim().toUpperCase().split("|"),u=!1;for' +HTML += b'(let d of c)if(Y(o,d)<=1){u=!0,r.numCorrect++,r.gapInputs[s]' +HTML += b'.value=d,r.student[s]=d;break}n.style.color=u?"black":"white' +HTML += b'",n.style.backgroundColor=u?"transparent":"maroon";break}cas' +HTML += b'e"int":r.numChecked++,Math.abs(parseFloat(a)-parseFloat(h))<' +HTML += b'1e-9&&r.numCorrect++;break;case"float":case"term":{r.numChec' +HTML += b'ked++;try{let n=k.parse(h),o=k.parse(a),c=!1;r.src.is_ode?c=' +HTML += b'ie(n,o):c=k.compare(n,o),c&&r.numCorrect++}catch(n){r.debug&' +HTML += b'&(console.log("term invalid"),console.log(n))}break}case"vec' +HTML += b'tor":case"complex":case"set":{let n=h.split(",");r.numChecke' +HTML += b'd+=n.length;let o=[];for(let c=0;c{r.feedbackPopupDiv.' +HTML += b'style.display="none"},500),r.state===b.passed?r.src.instance' +HTML += b's.length>0?r.checkAndRepeatBtn.innerHTML=te:r.checkAndRepeat' +HTML += b'Btn.style.display="none":r.checkAndRepeatBtn.innerHTML=I}var' +HTML += b' A=class{constructor(e,t,i,s){this.question=t,this.inputId=i' +HTML += b',i.length==0&&(this.inputId=i="gap-"+t.gapIdx,t.types[this.i' +HTML += b'nputId]="string",t.expected[this.inputId]=s,t.gapIdx++),i in' +HTML += b' t.student||(t.student[i]="");let l=s.split("|"),a=0;for(let' +HTML += b' c=0;ca&&(a=u.length)}let' +HTML += b' h=v("");e.appendChild(h);let n=Math.max(a*15,24),o=R(n);if(' +HTML += b't.gapInputs[this.inputId]=o,o.addEventListener("keyup",()=>{' +HTML += b'this.question.editedQuestion(),o.value=o.value.toUpperCase()' +HTML += b',this.question.student[this.inputId]=o.value.trim()}),h.appe' +HTML += b'ndChild(o),this.question.showSolution&&(this.question.studen' +HTML += b't[this.inputId]=o.value=l[0],l.length>1)){let c=v("["+l.join' +HTML += b'("|")+"]");c.style.fontSize="small",c.style.textDecoration="' +HTML += b'underline",h.appendChild(c)}}},D=class{constructor(e,t,i,s,l' +HTML += b',a,h=!1){i in t.student||(t.student[i]=""),this.question=t,t' +HTML += b'his.inputId=i,this.outerSpan=v(""),this.outerSpan.style.posi' +HTML += b'tion="relative",e.appendChild(this.outerSpan),this.inputElem' +HTML += b'ent=R(Math.max(s*12,48)),this.outerSpan.appendChild(this.inp' +HTML += b'utElement),this.equationPreviewDiv=x(),this.equationPreviewD' +HTML += b'iv.classList.add("equationPreview"),this.equationPreviewDiv.' +HTML += b'style.display="none",this.outerSpan.appendChild(this.equatio' +HTML += b'nPreviewDiv),this.inputElement.addEventListener("click",()=>' +HTML += b'{this.question.editedQuestion(),this.edited()}),this.inputEl' +HTML += b'ement.addEventListener("keyup",()=>{this.question.editedQues' +HTML += b'tion(),this.edited()}),this.inputElement.addEventListener("f' +HTML += b'ocusout",()=>{this.equationPreviewDiv.innerHTML="",this.equa' +HTML += b'tionPreviewDiv.style.display="none"}),this.inputElement.addE' +HTML += b'ventListener("keydown",n=>{let o="abcdefghijklmnopqrstuvwxyz' +HTML += b'";o+="ABCDEFGHIJKLMNOPQRSTUVWXYZ",o+="0123456789",o+="+-*/^(' +HTML += b'). <>=|",a&&(o="-0123456789"),n.key.length<3&&o.includes(n.k' +HTML += b'ey)==!1&&n.preventDefault();let c=this.inputElement.value.le' +HTML += b'ngth*12;this.inputElement.offsetWidth' +HTML += b'0&&!i?"block":"none",this.question.student[this.inputId]=e}}' +HTML += b',V=class{constructor(e,t,i,s){this.parent=e,this.question=t,' +HTML += b'this.inputId=i,this.matExpected=new E(0,0),this.matExpected.' +HTML += b'fromString(s),this.matStudent=new E(this.matExpected.m==1?1:' +HTML += b'3,this.matExpected.n==1?1:3),t.showSolution&&this.matStudent' +HTML += b'.fromMatrix(this.matExpected),this.genMatrixDom(!0)}genMatri' +HTML += b'xDom(e){let t=x();this.parent.innerHTML="",this.parent.appen' +HTML += b'dChild(t),t.style.position="relative",t.style.display="inlin' +HTML += b'e-block";let i=document.createElement("table");t.appendChild' +HTML += b'(i);let s=this.matExpected.getMaxCellStrlen();for(let p=0;p<' +HTML += b'this.matStudent.m;p++){let m=document.createElement("tr");i.' +HTML += b'appendChild(m),p==0&&m.appendChild(this.generateMatrixParent' +HTML += b'hesis(!0,this.matStudent.m));for(let g=0;g=10,this.matStudent.n<=1,thi' +HTML += b's.matStudent.m>=10,this.matStudent.m<=1];for(let p=0;p<4;p++' +HTML += b'){if(u[p]==!1)continue;let m=v(l[p]);n[p]!=888&&(m.style.top' +HTML += b'=""+n[p]+"px"),o[p]!=888&&(m.style.bottom=""+o[p]+"px"),c[p]' +HTML += b'!=888&&(m.style.right=""+c[p]+"px"),m.classList.add("matrixR' +HTML += b'esizeButton"),t.appendChild(m),d[p]?m.style.opacity="0.5":m.' +HTML += b'addEventListener("click",()=>{for(let g=0;g=5&&(this.feedbackSpan.innerHTML=' +HTML += b'""+this.numCorrect+" / "+this.numChecked);break}this.questio' +HTML += b'nDiv.style.color=this.feedbackSpan.style.color=this.titleDiv' +HTML += b'.style.color=this.checkAndRepeatBtn.style.backgroundColor=th' +HTML += b'is.questionDiv.style.borderColor=e,this.questionDiv.style.ba' +HTML += b'ckgroundColor=t}populateDom(){if(this.parentDiv.innerHTML=""' +HTML += b',this.questionDiv=x(),this.parentDiv.appendChild(this.questi' +HTML += b'onDiv),this.questionDiv.classList.add("question"),this.feedb' +HTML += b'ackPopupDiv=x(),this.feedbackPopupDiv.classList.add("questio' +HTML += b'nFeedback"),this.questionDiv.appendChild(this.feedbackPopupD' +HTML += b'iv),this.feedbackPopupDiv.innerHTML="awesome",this.debug&&"s' +HTML += b'rc_line"in this.src){let s=x();s.classList.add("debugInfo"),' +HTML += b's.innerHTML="Source code: lines "+this.src.src_line+"..",thi' +HTML += b's.questionDiv.appendChild(s)}if(this.titleDiv=x(),this.quest' +HTML += b'ionDiv.appendChild(this.titleDiv),this.titleDiv.classList.ad' +HTML += b'd("questionTitle"),this.titleDiv.innerHTML=this.src.title,th' +HTML += b'is.src.error.length>0){let s=v(this.src.error);this.question' +HTML += b'Div.appendChild(s),s.style.color="red";return}let e=this.get' +HTML += b'CurrentInstance();if(e!=null&&"__svg_image"in e){let s=e.__s' +HTML += b'vg_image.v,l=x();this.questionDiv.appendChild(l);let a=docum' +HTML += b'ent.createElement("img");l.appendChild(a),a.classList.add("i' +HTML += b'mg"),a.src="data:image/svg+xml;base64,"+s}for(let s of this.' +HTML += b'src.text.c)this.questionDiv.appendChild(this.generateText(s)' +HTML += b');let t=x();this.questionDiv.appendChild(t),t.classList.add(' +HTML += b'"buttonRow"),this.hasCheckButton=Object.keys(this.expected).' +HTML += b'length>0,this.hasCheckButton&&(this.checkAndRepeatBtn=j(),t.' +HTML += b'appendChild(this.checkAndRepeatBtn),this.checkAndRepeatBtn.i' +HTML += b'nnerHTML=I,this.checkAndRepeatBtn.style.backgroundColor="bla' +HTML += b'ck");let i=v("   ");if(t.appendChild(i),this.' +HTML += b'feedbackSpan=v(""),t.appendChild(this.feedbackSpan),this.deb' +HTML += b'ug){if(this.src.variables.length>0){let a=x();a.classList.ad' +HTML += b'd("debugInfo"),a.innerHTML="Variables generated by Python Co' +HTML += b'de",this.questionDiv.appendChild(a);let h=x();h.classList.ad' +HTML += b'd("debugCode"),this.questionDiv.appendChild(h);let n=this.ge' +HTML += b'tCurrentInstance(),o="",c=[...this.src.variables];c.sort();f' +HTML += b'or(let u of c){let d=n[u].t,p=n[u].v;switch(d){case"vector":' +HTML += b'p="["+p+"]";break;case"set":p="{"+p+"}";break}o+=d+" "+u+" =' +HTML += b' "+p+"
"}h.innerHTML=o}let s=["python_src_html","text_sr' +HTML += b'c_html"],l=["Python Source Code","Text Source Code"];for(let' +HTML += b' a=0;a0){let n=x();n.classList.add("debugInfo"),n.innerHT' +HTML += b'ML=l[a],this.questionDiv.appendChild(n);let o=x();o.classLis' +HTML += b't.add("debugCode"),this.questionDiv.append(o),o.innerHTML=th' +HTML += b'is.src[h]}}}this.hasCheckButton&&this.checkAndRepeatBtn.addE' +HTML += b'ventListener("click",()=>{this.state==b.passed?(this.state=b' +HTML += b'.init,this.reset(),this.populateDom()):se(this)})}generateMa' +HTML += b'thString(e){let t="";switch(e.t){case"math":case"display-mat' +HTML += b'h":for(let i of e.c){let s=this.generateMathString(i);i.t===' +HTML += b'"var"&&t.includes("!PM")&&(s.startsWith("{-")?(s="{"+s.subst' +HTML += b'ring(2),t=t.replaceAll("!PM","-")):t=t.replaceAll("!PM","+")' +HTML += b'),t+=s}break;case"text":return e.d;case"plus_minus":{t+=" !P' +HTML += b'M ";break}case"var":{let i=this.getCurrentInstance(),s=i[e.d' +HTML += b'].t,l=i[e.d].v;switch(s){case"vector":return"\\\\left["+l+"\\\\r' +HTML += b'ight]";case"set":return"\\\\left\\\\{"+l+"\\\\right\\\\}";case"compl' +HTML += b'ex":{let a=l.split(","),h=parseFloat(a[0]),n=parseFloat(a[1]' +HTML += b');return f.const(h,n).toTexString()}case"matrix":{let a=new ' +HTML += b'E(0,0);return a.fromString(l),t=a.toTeXString(e.d.includes("' +HTML += b'augmented"),this.language!="de"),t}case"term":{try{t=k.parse' +HTML += b'(l).toTexString()}catch{}break}default:t=l}}}return e.t==="p' +HTML += b'lus_minus"?t:"{"+t+"}"}generateText(e,t=!1){switch(e.t){case' +HTML += b'"paragraph":case"span":{let i=document.createElement(e.t=="s' +HTML += b'pan"||t?"span":"p");for(let s of e.c)i.appendChild(this.gene' +HTML += b'rateText(s));return i}case"text":return v(e.d);case"code":{l' +HTML += b'et i=v(e.d);return i.classList.add("code"),i}case"italic":ca' +HTML += b'se"bold":{let i=v("");return i.append(...e.c.map(s=>this.gen' +HTML += b'erateText(s))),e.t==="bold"?i.style.fontWeight="bold":i.styl' +HTML += b'e.fontStyle="italic",i}case"math":case"display-math":{let i=' +HTML += b'this.generateMathString(e);return T(i,e.t==="display-math")}' +HTML += b'case"string_var":{let i=v(""),s=this.getCurrentInstance(),l=' +HTML += b's[e.d].t,a=s[e.d].v;return l==="string"?i.innerHTML=a:(i.inn' +HTML += b'erHTML="EXPECTED VARIABLE OF TYPE STRING",i.style.color="red' +HTML += b'"),i}case"gap":{let i=v("");return new A(i,this,"",e.d),i}ca' +HTML += b'se"input":case"input2":{let i=e.t==="input2",s=v("");s.style' +HTML += b'.verticalAlign="text-bottom";let l=e.d,a=this.getCurrentInst' +HTML += b'ance()[l];if(this.expected[l]=a.v,this.types[l]=a.t,!i)switc' +HTML += b'h(a.t){case"set":s.append(T("\\\\{"),v(" "));break;case"vector' +HTML += b'":s.append(T("["),v(" "));break}if(a.t==="string")new A(s,th' +HTML += b'is,l,this.expected[l]);else if(a.t==="vector"||a.t==="set"){' +HTML += b'let h=a.v.split(","),n=h.length;for(let o=0;o0&&s.' +HTML += b'appendChild(v(" , "));let c=l+"-"+o;new D(s,this,c,h[o].leng' +HTML += b'th,h[o],!1)}}else if(a.t==="matrix"){let h=x();s.appendChild' +HTML += b'(h),new V(h,this,l,a.v)}else if(a.t==="complex"){let h=a.v.s' +HTML += b'plit(",");new D(s,this,l+"-0",h[0].length,h[0],!1),s.append(' +HTML += b'v(" "),T("+"),v(" ")),new D(s,this,l+"-1",h[1].length,h[1],!' +HTML += b'1),s.append(v(" "),T("i"))}else{let h=a.t==="int";new D(s,th' +HTML += b'is,l,a.v.length,a.v,h)}if(!i)switch(a.t){case"set":s.append(' +HTML += b'v(" "),T("\\\\}"));break;case"vector":s.append(v(" "),T("]"));' +HTML += b'break}return s}case"itemize":return z(e.c.map(i=>U(this.gene' +HTML += b'rateText(i))));case"single-choice":case"multi-choice":{let i' +HTML += b'=e.t=="multi-choice";i||(this.includesSingleChoice=!0);let s' +HTML += b'=document.createElement("table"),l=e.c.length,a=this.debug==' +HTML += b'!1,h=P(l,a),n=i?J:ee,o=i?G:$,c=[],u=[];for(let d=0;d{this.editedQue' +HTML += b'stion(),this.student[g]=this.student[g]==="true"?"false":"tr' +HTML += b'ue",this.student[g]==="true"?S.innerHTML=n:S.innerHTML=o}):C' +HTML += b'.addEventListener("click",()=>{this.editedQuestion();for(let' +HTML += b' L of u)this.student[L]="false";this.student[g]="true";for(l' +HTML += b'et L=0;L\'+K[r.lang]+"";document.getElementById("cour' +HTML += b'seInfo2").innerHTML=F[r.lang].replace("*",t);let i=[],s=docu' +HTML += b'ment.getElementById("questions"),l=1;for(let a of r.question' +HTML += b's){a.title=""+l+". "+a.title;let h=x();s.appendChild(h);let ' +HTML += b'n=new H(h,a,r.lang,e);n.showSolution=e,i.push(n),n.populateD' +HTML += b'om(),e&&a.error.length==0&&n.hasCheckButton&&n.checkAndRepea' +HTML += b'tBtn.click(),l++}}return he(de);})();sell.init(quizSrc,debug' +HTML += b'); ' HTML = HTML.decode('utf-8') # @end(html) diff --git a/web/src/eval.js b/web/src/eval.js index 1c6e683..ed057cc 100644 --- a/web/src/eval.js +++ b/web/src/eval.js @@ -42,7 +42,8 @@ export function evalQuestion(question) { // boolean types primarily occur in single/multiple choice questions. // boolean values are stringified as "true" and "false". question.numChecked++; - if (student === expected) question.numCorrect++; + if (student.toLowerCase() === expected.toLowerCase()) + question.numCorrect++; break; case "string": { // gap question diff --git a/web/src/math.js b/web/src/math.js index d0c1d8f..78a6c8c 100644 --- a/web/src/math.js +++ b/web/src/math.js @@ -13,6 +13,8 @@ * Both terms must be treated equivalent. */ +// TODO: boolean + /** * Given n, the list [0,1,...,n-1] (or a permutation in case "shuffled" is true) * is returned. diff --git a/web/src/question.js b/web/src/question.js index db849ac..eeb3851 100644 --- a/web/src/question.js +++ b/web/src/question.js @@ -104,6 +104,8 @@ export class Question { * Gets the next instance. */ reset() { + this.gapIdx = 0; + this.choiceIdx = 0; this.instanceIdx = (this.instanceIdx + 1) % this.src.instances.length; }