Skip to content

Examples

generateNscore edited this page Apr 16, 2023 · 16 revisions
  • Examples here demonstrates personalized and responsive questions.
  • Every information including Scripts and previews all can be found at the provided links.
  • Feel free to use them.
  • I would appreciate if you could present proper acknowledgement where you acquired.

  • A. Script

    graph='''var argsFromMain=null;function init(prms) {argsFromMain=prms;}//init();
    if (argsFromMain == null) {argsFromMain=[200, [1, 1, -2], [-5, 5]];}const height = argsFromMain[0];cnvs.height = height;cnvs.width=height;const N=51;const aj=argsFromMain[1], xlim=argsFromMain[2];const dx=(xlim[1]-xlim[0])/(N-1);yMin=Math.floor(aj[2]-aj[1]*aj[1]/4-1);const ylim=[yMin, yMin+10];const xPole=-aj[1]/2;var x=[], y=[], v;for (j=0; j<N; j++) {  v=xlim[0]+j*dx; w=aj[0]*v**2 + aj[1]*v + aj[2];  if (yMin<w && w<yMin+10) {x.push(v); y.push(w);}}function x2cnvs(x) {return bOrigX+pxl2x*(x-xlim[0]);}function y2cnvs(y) {return bOrigY+bL-pxl2x*(y-ylim[0]);}const bOrigX=0.5, bOrigY=0.5, bL=height, pxl2x=bL/(xlim[1]-xlim[0]);ctx.beginPath();ctx.fillStyle="#eee";ctx.fillRect(bOrigX, bOrigY, bL, bL);ctx.strokeStyle="#ccc";for (let j=xlim[0]; j<=xlim[1]; j++) { px=x2cnvs(j); ctx.moveTo(px, bOrigY); ctx.lineTo(px, bOrigY+bL);ctx.stroke();}for (let j=Math.ceil(ylim[0]); j<=Math.floor(ylim[1]); j++) { py=y2cnvs(j); ctx.moveTo(bOrigX, py); ctx.lineTo(bOrigX+bL, py);ctx.stroke();}ctx.beginPath();ctx.strokeStyle="blue"; py=y2cnvs(0); ctx.moveTo(bOrigX, py); ctx.lineTo(bOrigX+bL, py); ctx.stroke();ctx.beginPath();ctx.strokeStyle="blue"; px=x2cnvs(0); ctx.moveTo(px, bOrigY); ctx.lineTo(px, bOrigY+bL); ctx.stroke();ctx.beginPath();ctx.font="normal 14px Arial";ctx.fillStyle="blue";ctx.fillText("O", x2cnvs(0)-15,y2cnvs(0)+15);ctx.fillText("x", bOrigX+bL-10,y2cnvs(0)-3);ctx.fillText("y", x2cnvs(0)-12, bOrigY+13);for (j=ylim[0]+1; j<ylim[1]; j++) {  if (j%2 == 0) {     if (j<0) {ctx.fillText(j.toString(), x2cnvs(0)-15,y2cnvs(j)+5);}     else if (j>0) {ctx.fillText(j.toString(), x2cnvs(0)-10,y2cnvs(j)+5);}  }}ctx.fillText("-4", x2cnvs(-4)-8,y2cnvs(0)+12);ctx.fillText("-2", x2cnvs(-2)-8,y2cnvs(0)+12);ctx.fillText("2", x2cnvs(2)-4,y2cnvs(0)+12);ctx.fillText("4", x2cnvs(4)-4,y2cnvs(0)+12);ctx.beginPath();ctx.strokeStyle="black";ctx.moveTo(x2cnvs(x[0]), y2cnvs(y[0]));for (j=1; j<N; j++) {ctx.lineTo(x2cnvs(x[j]), y2cnvs(y[j]));}ctx.stroke();ctx.beginPath();for (j=0; j<N; j++) {ctx.beginPath();  ctx.arc(x2cnvs(x[j]),y2cnvs(y[j]),2,0, 2*Math.PI);  ctx.stroke();}'''
    
    figures={'graph': graph}
    
    Q=['What is the correct function shown below?<br>figure(graph)<br>init({%prms%});']
    
    A='''data=[]
    choices=[]
    for _ in range(6):
      b=random.choice([-4, -3,-2,-1, 0, 1, 2, 3, 4])
      c=random.choice([-4, -3,-2,-1, 0, 1, 2, 3, 4])
      choices.append([300, [1, b, c], [-5,5]])
    
    indx=random.choice(range(len(choices)))
    ansValue=choices[indx]
    eqs=[]
    term1=lambda v: '+ x' if v==1 else '- x' if v==-1 else f'+ {v}x' if v>0 else f'- {-v}x' if v<0 else ''
    term2=lambda v: f'+ {v}' if v>0 else f'- {-v}' if v<0 else ''
    eqs = []
    for _, aj, _ in choices: eqs.append(f'EQ% x^2 {term1(aj[1])} {term2(aj[2])} %EQ')
    
    answer=[{'choices':eqs, 'ans':eqs[indx]}]
    prms=choices[indx]'''
    
    QGs.append([Q, A, ('chap3', 'eq_graph1'), 'short'])
  • Unfolded code for the "graph" figure can be found here.

  • A. Script

    addFractions='''var argsFromMain=null;function init(prms) {argsFromMain=prms;}//init();
    if (argsFromMain == null) {argsFromMain=[200, [1, 2, 2, 3]];}
    var height = argsFromMain[0];cnvs.height = height;cnvs.width=2*height; var radius = cnvs.height/4;var cY = cnvs.height/2;var cX = cnvs.width/2;var radius = cY-20;
    ctx.beginPath();ctx.font="normal 60px Arial";ctx.fillStyle="black";ctx.fillText("+", cX-17, cY+20);
    var angle = 2*Math.PI/argsFromMain[1][1];for (let j=0; j<argsFromMain[1][1]; j++) {  ctx.beginPath();  ctx.moveTo(cX-radius-20, cY);  ctx.strokeStyle="black";  if (j<argsFromMain[1][0]) {ctx.fillStyle="#ed7";}  else {ctx.fillStyle="white";}  ctx.arc(cX-radius-20, cY, radius, j*angle, (j+1)*angle);  ctx.lineTo(cX-radius-20, cY);  ctx.fill();  ctx.stroke();}
    angle = 2*Math.PI/argsFromMain[1][3];for (let j=0; j<argsFromMain[1][3]; j++) {  ctx.beginPath();  ctx.moveTo(cX+radius+20, cY);  ctx.strokeStyle="black";  if (j<argsFromMain[1][2]) {ctx.fillStyle="#7ed";}  else {ctx.fillStyle="white";}  ctx.arc(cX+radius+20, cY, radius, j*angle, (j+1)*angle);  ctx.lineTo(cX+radius+20, cY);  ctx.fill();  ctx.stroke();}'''
    
    Q=['What is the sum of the two fill areas of the color drawn below?<br>figure(addFractions)<br>init({%prms%});']
    A='''data=[]
    import userfunctions
    choices, indx, ansValue = userfunctions.func2()
    answer=[{'choices':choices, 'ans':choices[indx]}]
    prms=ansValue'''
    
    QGs.append([Q, A, ('chap10', 'udf_fraction_shapes1'), 'choice'])
  • Unfolded code for the "addFractions" figure can be found here.
  • import random
    
    def func2(choices=None, ans=None):
        from fractions import Fraction
        choicesBefore = []
        for j in range(15):
            fr1=Fraction(random.choice([1,2]), random.choice([4,5,6,7,8]))
            fr2=Fraction(random.choice([1,2]), random.choice([4,5,6,7,8]))
            tmp = (fr1, fr2, (fr1+fr2))
            if tmp[-1] not in [item[-1] for item in choicesBefore]: choicesBefore.append(tmp)
    
        choices=[]
        for _, _, fr in choicesBefore:
            choices.append(r'EQ% \frac {'+f'{fr.numerator}'+'} {'+f'{fr.denominator}'+'} %EQ')
    
        indx=random.choice(range(len(choices)))
        f1, f2, _=choicesBefore[indx]
        return choices, indx, [300, [f1.numerator, f1.denominator, f2.numerator, f2.denominator]]
    
    if __name__ == '__main__':
        print(func2())

    A. Script

    division='''var argsFromMain=null;function init(prms) {argsFromMain=prms;}//init();
    if (argsFromMain == null) {argsFromMain=[[50,1000], ['x', '8', '÷', '3', '=', '6']];}cnvs.height = argsFromMain[0][0];cnvs.width = argsFromMain[0][1];
    function drawRect(xo, yo) { ctx.beginPath(); ctx.strokeStyle="#888"; ctx.rect(xo, yo, rectA, rectA); ctx.stroke(); ctx.closePath();}
    const word=argsFromMain[1], rectA=40, xo=50.5, yo=0.5, digits=['0', '1', '2', '3', '4', '5', '6', '7', '8', '9', 'x'];
    for (let i=0; i<word.length; i++) {
      if (digits.includes(word[i])) { ctx.beginPath(); ctx.strokeStyle="#888"; ctx.rect(xo+i*(rectA+5), yo, rectA, rectA); ctx.stroke();}
      if (word[i] != 'x') { ctx.beginPath(); ctx.fillStyle="red"; ctx.textAlign="center"; ctx.font="normal 40px Palatino Linotype"; ctx.fillText(word[i], xo+i*(rectA+5)+rectA/2, yo+rectA-6); }
    }'''
    
    figures={'division': division}
    
    QGs=[]
    
    Q=['Find the integer in the blank that completes the division expression below.figure(division)init({%prms%});',
       'Find the integer in the blank that completes the division expression below.figure(division)init({%prms%});']
    
    A='''data=[]
    vA=random.choice(range(2,20))
    vB=random.choice(range(1,10))
    op='÷'
    vA *= vB
    vAns=int(vA/vB)
    vStr=list(f'{vA}{op}{vB}={vAns}')
    x=random.choice([item for item in enumerate(vStr) if item[1].isnumeric()])
    vStr[x[0]]='x'
    exps=[str(f) for f in range(10)]
    answer=[x[1], {'choices':exps, 'ans':x[1]}]
    prms=[[50, 800], vStr]'''
  • Unfolded code for the "division" figure can be found here
  • The image below shows the result for 2 questions, one as short-answer and the other as multiple-choice, regarding elementary division expression:

    • It would be a good practice if you try to modify the script above for other algebraic expressions, such as addition, subtraction, or multiplication?