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 questions - Specify 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"
- for the answer (0.XX),
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 test - Click
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