Arduino and CodeRunner

Re: Arduino and CodeRunner

by Richard Lobb -
Number of replies: 14

Yes, it's there now. There's a demo quiz linked off the front page of this site. It's here.

In reply to Richard Lobb

Re: Arduino and CodeRunner

by Michael Backus -

I've finally gotten around to putting together a question that uses Gap-filler. I can get it to work in python, but when I try to get it to work in C, I run into an issue. I believe the problem is that I need to decode the student's answer which is sent to the template as a JSON list of strings. I just don't know how. Is there a built in parser for JSON in the jobe server?

I've attached my experimental questions. The one I'm having trouble with is C Loop 0-4. If there's a better way to do this, I'm all ears.

Also, I'm interested in checking for correct white space on future questions I make. I suspect the practical way to do this would be to create a c_via_python_whitespace question type. Am I mistaken, or is that the way to go. If so, do you have a questions template or prototype you can share? 

Thanks for making this plugin available. I think it will make a big difference for my students.

In reply to Michael Backus

Re: Arduino and CodeRunner

by Richard Lobb -

Yes, writing the template in C is problematic with the gap-filler UI. Twig unfortunately doesn't have a json decode filter. 

In your C Loop 0-4 example, there is a hacky solution. Since the STUDENT_ANSWER variable is a string of the form

["for (int x = 0; x < 5; x++)"]

you can actually get away with just stripping off the first two and last two characters and plugging the result into the code directly. The template for that is

#include <stdio.h>
#include <stdlib.h>
#include <ctype.h>

int main() {
    {{ STUDENT_ANSWER[2:-2] }}
        printf("%d\n", x);
    return 0;
}

If you also reduce the answer box rows to 1, the resulting run looks like:


But this won't work with multiple gaps, and there are probably other gotchas as well.

So I think you'd be better off writing a variant of the C_via_python question type as you suggest.

I don't quite understand your question about checking for whitespace but whatever it is I'm pretty sure my answer will be "Use Python" :)

I attach the C gapfiller prototype and example of its use that I showed in the earlier posting. Be warned I haven't used this question type in practice so you might have to debug it a bit.

In reply to Richard Lobb

Re: Arduino and CodeRunner

by Michael Backus -

Awesome! I got v2 of my question working (see attachment). My next goal is to get things to look like they would in the Arduino IDE. So, instead of:

int main()
{
  {[30]}
    printf("%d\n", x);
}

I'd like it to look like:

void setup()
{
  Serial.begin(9600);
  {[30]}
    Serial.println(x);
}

void loop()
{}

Earlier in this post you show how to do this by altering the template. I understood your response and think I could edit the template if it were C. However, I must confess I have no clue how to alter the c_via_python template that I'm using for this question.

As for the white space, I am referring to how far students indent lines of code depending on whether they are in a loop, an if statement, or a loop within an if statement. I'd like to assess a penalty when students submit code that is improperly indented. Is that something you do with CodeRunner for any of your questions?

In reply to Michael Backus

Re: Arduino and CodeRunner

by Richard Lobb -

The easiest way to get the extra code (the dummy Serial class) into the program is just to put a line like

#include "arduinostuff.cpp"

at the start of the program in globalextra. Then add to the question a support file arduinostuff.cpp that contains all the extra code.

If you want to hide the include from students you can change the line in the template

raw_prog = """{{ QUESTION.globalextra | e('py') }}"""

to

raw_prog = """#include "arduinostuff.cpp"\n{{ QUESTION.globalextra | e('py') }}"""

For more flexibility again you could set up a template parameter that specified the name(s) of extra files to be included. That way the same question type can be used with different support files.

Checking the indentation of the C code is probably not relevant with gap fillers. But when the student is writing whole functions or programs it's certainly nice to check it. Assuming you're running some variant of the c_via_python question type, the submitted code (for non gap-filler questions) is available as as a string e.g. by

student_answer = """ {{ STUDENT_ANSWER | e('py') }}"""

and it's over to you to check it however you like.

Our own horrendously complex C question type runs the astyle program over the student's code and checks if the code has changed as a result. If so, it prints any discrepancies and aborts execution. Student's are told that they are required to lay out the code exactly as astyle does (with a particular style convention) and their code editor has a button to run astyle with a single mouse click or control-key. So they have no excuse for submitting non-astyle-compliant code.

Our checking also includes parsing the submitted C code with the pycparser Python module and checking things like function length and choice of identifiers. However you can't use pycparser with Arduino C as it's really C++. I don't know of any C++ parser written in Python.

To be fair to the student, you need to provide a Precheck button that does all style checking so they don't pay penalties for trivial stylistic defects.

I suggest you start small and just add simple checks to your base question type and built up its capabilities over time (possibly years).

In reply to Richard Lobb

Re: Arduino and CodeRunner

by Michael Backus -

I tried adding the support file MockArduino.cpp (attached). I then created code in the Global extra field that referenced the MockArduino.cpp file (see attached image of my error message). I think the compiler is expecting to see the setup inside the support file with main. Is there a way to get it to look to the global extra field? Is there another solution?

Attachment ErrorMessage.png
In reply to Michael Backus

Re: Arduino and CodeRunner

by Richard Lobb -

The code from MockArduino.cpp is simply being inserted into the code at the point of the "#include". So if it contains the main function and if you want that to call setup then either put the #include at the end of the program (possibly by hiding it in the template) or (probably nicer) put a forward declaration of setup into MockArduino.cpp, before the main function definition, e.g.

void setup();
// And if you want to put the definition of loop in the student code ...
void loop();  
int main() { ... etc }

Both should work.

In reply to Richard Lobb

Re: Arduino and CodeRunner

by Michael Backus -

I put in a forward declaration of setup and everything worked! The next step is to create a mock of the Serial object. I did so in my MockArduino.cpp using struct. Unfortunately, I'm getting an error that I don't understand (see attached image). I've also attached an exported version of the question as well as the latest version of my MockArduino.cpp file.

Attachment MockSerialError.png
In reply to Michael Backus

Re: Arduino and CodeRunner

by Richard Lobb -

Is your base question type C or C++? Arduino C is actually C++ and your Serial class requires C++.

In reply to Richard Lobb

Re: Arduino and CodeRunner

by Michael Backus -

I'm using the PROTOTYPE_c_gapfiller and C gapfiller example that you provided links to above. Do you have a PROTOTYPE_cpp_gapfiller and example I could use?

In reply to Michael Backus

Re: Arduino and CodeRunner

by Richard Lobb -

You should be able to run C++ instead simply by changing the name prog.c to prog.cpp and changing the Python line that compiles the code from

return_code = subprocess.call(['gcc', '-Wall', '--std=c99', '-Werror', '-o', 'prog', 'prog.c'])

to

return_code = subprocess.call(['g++', '-Wall', '-Werror', '-o', 'prog', 'prog.cpp'])

Give that a go.

Sorry, that's all I can offer at present. I'm afraid I can't construct question prototypes for every problem - every author has their own special needs.


In reply to Richard Lobb

Re: Arduino and CodeRunner

by Michael Backus -
It works! Thanks for all your help. I'm going to make a quiz on loops this weekend. One quick question I have about the user interface is whether there is a way to remove the "For example" from above the test cases that I have chosen to show as an example.

Also, I'd like to know how I can contribute. I now have a working cpp question prototype that I'm happy to share, as well as a MockArduino.cpp file I'm willing to share and plan to expand on in the future. Is there a repository that I can submit pull requests to? I'm also willing to share the questions I write with other educators. Let me know how I can contribute.
Attachment Success.png
In reply to Michael Backus

Re: Arduino and CodeRunner

by Michael Backus -

Awhile back you added me to the Python question repository course. I propose you change the course name to Question Repository, and then I'll add the questions I'm developing if you want. I'll put them in a category called Arduino.

In reply to Michael Backus

Re: Arduino and CodeRunner

by Richard Lobb -

Many thanks for the offer to contribute, Michael.

Since the language that the question type offers to students is C++, I'd prefer that Arduino questions went into the C++ repository rather than the Python repository. So I've changed its name to C++ and Arduino and added you as a teacher. Please create a separate question category for Arduino, then contribute away!