Numerical Answers with R
This page is specific to the R questions (without coding). The objectives are:
Use the necessary R function in the
server.py
to generate the solutions, and grade the questionsSpecify the randomized variables in the
server.py
Specify the specific files (e.g., figure) in the
server.py
Overview
The easiest way to create a R question (without coding) is by copying an existing R question, and change certain files. Then you don’t need to create the UUID by yourself.
Note: Each UUID will be assigned to a question only.
Step 1: Copy a R question
Follow the Step 1 to Step 4 in the Routine work. Then click PrarieLearn logo (next to Admin) in the upper left.
Click a course such as
CEE 202: Engineering Risk & Uncertainty
in theCourses
(notCourse instances
) list.Click the
Questions
(next toIssues
) on the top line.Find a question you want to copy (for example:
AS4_Prob5_2020_AngTang
).Click
Settings
betweenPreview
andStatistics
.Click
Make a copy of this question
Click
Change QID
Step 2: Modify the questions
Before you modifying the question, I strongly suggest creating a spreadsheet to keep track of the questions (including title, topic, tags) and corresponding UUID.
Note: Each question folder contain the following files
Folder/File Name | Usage |
---|---|
info.json | The information of the question such as title, topic, tags, and uuid. |
question.html | The main body of the question |
server.py | The solution to the question, but it also species |
clientFilesQuestion | Save the figures for the question. |
clientFilesQuestion /dist.png |
The figure needes to be added to the question |
info.json
Click
Edit
underSettings
Define the
title
,topic
,tags
, andtype
server.py
Click
Files
(underPrairieLearn
in the upper left) →Edit
theserver.py
, then you need to finish the following tasks:
import rpy2.robjects as robjects
import prairielearn as pl
def generate(data):
# here is the start the R function
values = robjects.r("""
# prob 1
#a_r = 4.0
a_r = sample(seq(3.8,4.3,0.1),1)
ans_a_r = 1 + a_r
# Export
list(
ans = list(a=a_r,
answer_a=ans_a_r)
)
""")
# here is the end of the R function
ans = values[0]
# Convert from R lists to python dictionaries
ans = { key : ans.rx2(key)[0] for key in ans.names }
# Setup output
data['correct_answers'] = ans
# Setup randomized variables
data["params"] = ans
# define the figure name
image_name = "dist.png"
data["params"]["image"] = image_name
Change the randomized variable using
a_r=sample(seq(start,end,interval),1)
Change the answers (
ans_a_r
,ans_b_r
, …), and export (list(...)
)
Note: a
corresponds to ${{params.a}}$
, answer_a
corresponds to answers-name="answer_a"
in the question.html
Change the
image_name
(if you have figures(s))
question.html
Click
Files
(underPrairieLearn
in the upper left) →Edit
thequestion.html
, then you need to finish the following tasks:
<pl-question-panel>
<p>
This is the problem statement.
</p>
<pl-figure file-name={{params.image}} directory="clientFilesQuestion"></pl-figure>
</pl-question-panel>
<pl-question-panel><hr></pl-question-panel>
<pl-question-panel>
<p>
(a) Determine the probability that the settlement will exceed ${{params.a}}$ cm.
</p>
</pl-question-panel>
<div class="card my-2">
<div class="card-body">
<pl-question-panel>
<p>The answer is: (0.XX)</p>
</pl-question-panel>
<pl-number-input answers-name="answer_a" weight = "3" comparison="relabs" rtol="0.01" atol="0.01"></pl-number-input>
</div>
</div>
Replace “This is the problem statement.” with your problem statement
Replace
${{params.a}}$
with your randomized variable fromserver.py
Replace
"answer_a"
with your answer fromserver.py
Define the tolerance. Sotiria suggests that:
for the answer (0.XX),
comparison="relabs" rtol="0.01" atol="0.01"
for the answer (0.XXX),
comparison="relabs" rtol="0.001" atol="0.001"
Alternatives: Integer
Reference: (link)
If the answer is an integer, you need to replace
<pl-number-input answers-name="answer_a" weight = "3" comparison="relabs" rtol="0.01" atol="0.01"></pl-number-input>
with
<pl-integer-input answers-name="answer_a" weight = 3></pl-integer-input>
Where the answer “answer_a” has to be an integer.
Step 3: Test your questions
Click
Preview
to testClick
New variant
to have another test
Step 4: Commit and push the changes
Using Git to commit and push the changes
Note: You may do this after you finish all the questions
Step 5: Sync and test
Log in the website https://prairielearn.engr.illinois.edu/pl/, and select your course
Click
Sync
, thenPull from remote git repository
Find your questions by clicking
Questions
and test them again
Appendix: Answers from R function output
The following server.py
shows the workflow of doing a simple linear regression
import rpy2.robjects as robjects
import prairielearn as pl
def generate(data):
# here is the start the R function
values = robjects.r("""
# Read in the data
my_data = read.csv(paste0('./clientFilesQuestion/mydata.csv'))
# Form a model
lm_model = lm(y ~ x, data = my_data)
beta_hats = coef(lm_model)
# View all the attributes, e.g., adj.r.squared
#attributes(summary(lm_model))
# New predictions
#new_data <- data.frame(x = c(20))
#predicted = predict(lm_model,newdata=new_data,interval="confidence", level=0.95)
# Export
list(
ans = list(beta1 = beta_hats[2],
beta0 = beta_hats[1],
pvalue = summary(lm_model)$coefficients[2,4],
slope_se = summary(lm_model)$coefficients[2,2],
r_mult=summary(lm_model)$r.squared,
lo=confint(lm_model)[2,1],
hi=confint(lm_model)[2,2],
pred_low = predicted[2],
pred_high = predicted[3],
corr = cor(x,y))
)
""")
# Extract parameter and answer lists
ans = values[0]
# Convert from R lists to python dictionaries
ans = { key : ans.rx2(key)[0] for key in ans.names }
# Setup output dictionaries
data['correct_answers'] = ans