bhobijn
Community Member

Canvas API: Structure of answer object for numerical answer question

I am using the Canvas API to develop a set of questions the answers to which automatically get updated to reflect the lastest economic data. Some of these questions are numerical_answer type questions. However when I post

answers = [ { 'text': '',  'comments': '',  'comments_html': '', 'weight': 100, 'numerical_answer_type': 'exact_answer', 'exact': 12.3, 'margin': 0.1} ]

then the question does get created with  'numerical_answer_type' as 'exact_answer', but the 'exact' and 'margin' entries are not updated on Canvas to the right answer. Instead, they are set to zero. Does someone know how to structure the post of the answer object in the Canvas API for a numerical_answer question such that these answers get properly posted to the server?

Bart Hobijn

Tags (1)
5 Replies
jack_c_kiefer
Community Novice

I have discovered a work-around!

It seems that, firstly, the API documentation is either wrong or out-of-date. Digging through the Canvas source code a bit, I found that the labels for numerical answers are different from how they're specified in the docs. Here's some sample code for properly structuring the answers object:

exactAnswer = 4
margin = 0.1

start = exactAnswer - margin
end = exactAnswer + margin

answers = [{
'numerical_answer_type' : 'range_answer',
'answer_exact' : exactAnswer,
'answer_error_margin' : margin,
'answer_range_start' : start,
'answer_range_end' : end
}‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍]

It's a little redundant, but the API is a little weird sometimes about missing information. Even trying to construct a range_answer in the manner according to the docs will lead to the same erroneous behavior of answers that are only 0.

You can, of course, put multiple answer objects in the answers list to specify multiple possible answers (like if you're asking about one of the two roots of a quadratic or something).

Hope this helps while the API/docs get a fix!

Thank you, I've been trying to figure this out for hours.

If you are using the python canvasapi this is how I submit a new numeric answer question with exact answers. answer_weight Does not work still, but I got a little further than I was.

canvas = Canvas(API_URL, API_KEY)
course = canvas.get_course(CourseNumber)


test_quiz3 = course.create_quiz(quiz_dict3)


numeric_question_dictionary = {'question[question_name]':"Question 10",
'question[question_text]':"<p>Select the appropriate answer</p>",
'question[question_type]':"numerical_question",
'question[points_possible]':10,
'question[answers][0][numerical_answer_type]':"exact_answer",
'question[answers][0][answer_exact]':42,
'question[answers][0][answer_text]': 42,
'question[answers][0][answer_weight]': 1,
'question[answers][0][answer_error_margin]': 4}




test_quiz3.create_question(**numeric_question_dictionary)




0 Kudos
James
Community Champion

 @davidlamb ,

I don't use the Python library, but here's a good and quick way to tell what to send.

Open up the developer tools in your browser (F12 in Chrome or Firefox). Then go to the network tab. Create a question and look at the XHR request that Canvas makes. In Chrome, it's under the headers tab, then scroll down to Form Data. Then duplicate what Canvas is sending.

330916_pastedImage_6.png

Here's what Canvas sent when I created your question. Note that it had a lot of other crud in there, I isolated just the relevant portions.

question[question_name]: Question 10
question[question_type]: numerical_question
question[points_possible]: 10

question[question_text]: <p>Select the appropriate answer</p>

question[answers][0][answer_exact]: 42
question[answers][0][answer_error_margin]: 4
question[answers][0][answer_weight]: 100
question[answers][0][numerical_answer_type]: exact_answer

When I look at what Canvas sends vs what you send, I see that the answer_text is not used for a numerical answer question. It typically ignores things that aren't relevant, so including it may not hurt anything, but it's not used. Also, you have a weight of 1 instead of 100.

I don't know if those matter, but if you have exactly what Canvas is sending and it still doesn't work, then it might have to do with the structure rather than the data you're sending.

mboldin
Community Member

Following Jack's hints I was able to use the Python API and pass through create_question() an 'answers' dictionary  as below that I think is the minimal input needed for an numerical answer

question['answers'] =  [{ 'numerical_answer_type' : 'exact_answer',  'answer_exact' : exact_answer }]

This gives an exact answer that automatically sets 'margin': 0  

and for a range:

[{ 'numerical_answer_type' : 'range_answer',
'answer_range_start' : exact_answer - 1,
'answer_range_end' : exact_answer + 1,}]

0 Kudos
edwardkung
Community Member

Thanks, this helped me figure out what was going wrong with my code!  Canvas, please update your documentation!