Exercise sample: code

Change this sample according to your needs. Run all the cells, and upload resulting .xml file to Moodle.

Auxilary functions


In [1]:
from moodle import *

Reference programme

First we write reference programme.


In [2]:
%%writefile root2.py
###########################################################################
# Write the function root2(x) that calculates square root of x numerically
# with error less than 0.0001
###########################################################################
def root2(x):
    """
    Function root2(x) calculates square root of given x numerically
    with precision 0.0001
    """
# BEGIN_REFERENCE_CODE
    tolerance = 0.0001
    y=x/2;
    for i in range(100):
        yn = (y+x/y)/2
        if abs(yn-y)<tolerance:
            break
        y = yn
    return y
# END_REFERENCE_CODE

# TESTS
import random
if __name__ == '__main__':
    assert(abs(root2(4)-2)<0.0001)
    assert(abs(root2(2)-1.41421356)<0.0001)
    # BEGIN_ANSWER
    random.seed(123)
    ans = root2(random.random()+random.randint(10,20))
    # END_ANSWER
    print("Write this number as answer in Moodle: %1.7f" % ans)


Overwriting root2.py

In [7]:
from root2 import root2
name = "root2.py"
with open(name) as fp:
    s = fp.read()

import re
re_ref_code = re.compile(r'\#\s*BEGIN_REFERENCE_CODE.*\#\s*END_REFERENCE_CODE', re.DOTALL)
template = re_ref_code.sub('# WRITE YOUR CODE HERE\n\n\n# DO NOT CHANGE THE CODE BELOW\n',s)
code = re_ref_code.findall(s)[0]

Question parameters

Generate parameters, that appear in the questions. Since we would like to test Python code, we use random generator with seed to generate test cases.


In [4]:
import random
random.seed(123)
parameters = [random.randint(1000,2000) for i in range(6)]
parameters


Out[4]:
[1053, 1274, 1089, 1787, 1417, 1272]

Question body

Write the function, that generates the text of the question. You can use the following syntax to add different inputs to question string q:

  • value of a variable: q = q + str(x)
  • Python expressions: q = q + str(1+2*x)
  • answer input field: q = q + num_q(correct_answer, precision)

Note on embedding Python files

We use <a name="data.csv" href="data:text/x-python;base64,...> tag to embed arbitrary python file as BASE64 encoded ASCII string.


In [8]:
import io
import base64

def question_text(parameter):
    seed =  parameter # parameter contains seed for random
    s = template.replace('random.seed(123)','random.seed(%d)'%seed)
    random.seed(seed)
    y = root2(random.random()+random.randint(10,20))
    python = base64.b64encode(s.encode('ascii')).decode()
    q = """<p>Write Python function that calculates square root of given number. Use </p>
    <a name="%s" href="data:text/x-python;base64,%s">%s</a> as a template.
    <p>What is the number the program returns?: %s</p>
    """ % (name,python,name,num_q(y,0.00005))
    return q

In [9]:
# display the first question
from IPython.display import HTML
HTML(question_text(parameters[0]))


Out[9]:

Write Python function that calculates square root of given number. Use

root2.py as a template.

What is the number the program returns?: {1:NUMERICAL:=3.968977:0.000050#Pravilno~3.968977:0.000500#Premalo pravilnih decimalk}

Write to file


In [14]:
# Write the questions to a file
category  = 'python/root/'
questions = []
for param in parameters:
    b = question_text(param)
    questions.append(b)
file = open(name + ".xml","w",encoding="utf8")
feedback = "<![CDATA[Reference code:\n<pre>\ndef root2(x):\n%s\n</pre>]]>" % code

# Write to Moodle xml file
cloze_with_feedback = lambda text, name: cloze_question(text, name, feedback)
moodle_xml(name,questions, cloze_with_feedback, category = category, iostream = file)
file.close()
print("Questions were saved in " + name + ".xml, that can be imported into Moodle")


Questions were saved in root2.py.xml, that can be imported into Moodle

In [ ]: