Python 3 construct check

Python 3 construct check

by M M -
Number of replies: 1
I am wanting to use CodeRunner for my Moodle course for teaching basic programming. E.g. I want to be able to check if a student has correctly formed a fixed loop. I am feeling a bit thick after reading through the CodeRunner documentation. I managed to set up a question to test for the output "Hello world" 5 times, but obviously a student could just write 5 print statements rather than use a for loop. Could you please advise me?
In reply to M M

Re: Python 3 construct check

by Richard Lobb -

You could either ask a slightly different question that can't be answered without a loop, or you could check the submitted code to see if it uses a loop. You don't say what language you're using, so I'll assume Python3 in what follows.

Here are 3 possible questions:

  1. "Fill in the body of the function print_hello_repeated(n) so that it prints Hello world n times. The function header is given to you in the answer box". You could then have several tests with different values of n.

    That's the easiest solution as it uses the existing python3 question type directly. Students don't necessarily have to know what functions are; they just have to write the code to print the output using n. However, they do have to know to indent the code (if it's Python).

  2. "Assuming the existence of a variable n, write a code fragment that prints the message Hello world n times." You can then have several tests containing code like n = 5, n = 7 etc. To make that approach work, you need to customise the template so that the test code runs before the student code, rather than vice versa. Such a template might be just:

    {{TEST.testcode}}
    {{STUDENT_ANSWER}}
    
    Note that the is combinator checkbox needs to be unchecked for that particular template.

  3. (Your original question) "Write a code fragment that prints Hello world 5 times. Your code is required to use a for loop and a single print function call.

    Your customised template (again, not a combinator template) might then be something like:

    answer = """{{ STUDENT_ANSWER | e('py')}}"""
    lines = answer.split('\n')
    if not any(line.strip().startswith('for') for line in lines):
        print("Your code doesn't use a for loop")
    elif answer.count('print') > 2:  # Allow an extra print in a comment
        print("Your code should contain a single 'print'")
    else:
        exec(answer)
    

I recommend option 1. Option 2 might seem convenient but students make mistakes like pasting in their own code that assigns a value to n or they use a different variable name like m and the output can then be confusing. Option 3 is OK but it's a lot of extra effort to go to for such a simple question.

Richard