[Rd] Posting Guide - help.request() function?
Dr Heather Turner
Heather.Turner at warwick.ac.uk
Mon Jun 9 16:35:09 CEST 2008
Whilst it is a good idea to improve the posting guide, it seems to me
that it would be useful to have a function along the lines of
bug.report(), to help a potential questioner make sure they have done
their homework and have the relevant information to put into a post to
R-help.
Even those of us who know what ought to go into a post can sometimes
forget to check something obvious - I recently got caught out by not
checking an error was reproducible in the patched version for example.
So I have written a help.request() function (see below), which
- prompts the user to check the relevant resources, stopping and opening
the relevant url where necessary
- checks their R version is up-to-date (in a rather messy way - please
suggest improvements!)
- prompts them to prepare appropriate example code and test it in a
fresh R session
- prompts them to give a meaningful subject line
- automatically adds system info to the post (as in bug.report)
- sends the message for them (ensuring a fresh thread is started)
Is this an idea worth taking further? I would be happy to make
improvements as suggested and write a help file if so.
Heather
------------------------------------------------------------
help.request <- function (subject = "",
ccaddress = Sys.getenv("USER"),
method = getOption("mailer"),
address = "r-help at R-project.org",
file = "R.help.request")
{
no <- function(answer) answer == "n"
yes <- function(answer) answer == "y"
go <- function(url) {
cat("Please do this first - the site has been loaded in your
web browser\n")
browseURL(url)
}
cat("Checklist:\n")
post <- readline("Have you read the posting guide? (y/n) ")
if (no(post)) return(go("http://www.r-project.org/posting-guide.html"))
FAQ <- readline("Have you checked the FAQ? (y/n) ")
if (no(FAQ)) return(go("http://cran.r-project.org/faqs.html"))
intro <- readline("Have you checked An Introduction to R? (y/n) ")
if (no(intro))
return(go("http://cran.r-project.org/doc/manuals/R-intro.html"))
NEWS <- readline("Have you checked the NEWS of the latest
development release? (y/n) ")
if (no(NEWS)) return(go("https://svn.r-project.org/R/trunk/NEWS"))
rsitesearch <- readline("Have you looked on RSiteSearch? (y/n) ")
if (no(rsitesearch)) {
cat("Please do this first - the site has been loaded in your
web browser\n")
return(RSiteSearch(subject))
}
inf <- sessionInfo()
if ("otherPkgs" %in% names(inf)){
other <- readline("You have packages other than the base
packages loaded.",
"\nIf your query relates to one of these,
have you ",
"checked any corresponding books/manuals \nand ",
"considered contacting the package
maintainer? (y/n/NA) ")
if(no(other)) return("Please do this first.")
}
man <- url("http://cran.r-project.org/manuals.html")
ver <- scan(man, what = character(0), sep = "\n", skip = 13, nlines
= 1, quiet = TRUE)
major <- as.numeric(substr(ver, start = 18, stop = 18))
minor <- as.numeric(substr(ver, start = 20, stop = 22))
if (major < as.numeric(R.Version()$major) ||
minor < as.numeric(R.Version()$major)) {
update <- readline("Your R version is out-of-date, would you
like to update now? (y/n) ")
if (yes(update)) {
return(go(getOption("repos")))
}
}
## To get long prompt!
cat("Have you written example code that is\n",
"- minimal\n - reproducible\n - self-contained\n - commented",
"\nusing data that is either\n",
"- constructed by the code\n - loaded by data()\n",
"- reproduced using dump(\"mydata\", file = \"\")\n")
code <- readline(paste("have you checked this code in a fresh R
session",
"\n(invoking R with the --vanilla option if
possible)",
"\nand is this code copied to the clipboard?
(y/n) "))
if (no(code))
return(cat("\nIf your query is not directly related to code",
"(e.g. a general query \nabout R's capabilities),",
"email R-help at r-project.org directly. ",
"\nOtherwise prepare some example code first.\n"))
change <- readline(paste("Would you like to change your subject
line:\n",
subject, "\nto something more meaningful?
(y/n) "))
if (yes(change))
subject <- readline("Enter subject: \n")
methods <- c("mailx", "gnudoit", "none", "ess")
method <- if (is.null(method))
"none"
else methods[pmatch(method, methods)]
body <- paste("\\n<<Write your query here, using your example code
to illustrate>>",
"\\n<<End with your name and affiliation>>\\n\\n\\n\\n",
"--please do not edit the information below--\\n\\n",
"Version:\\n ", paste(names(R.version), R.version,
sep = " = ",
collapse = "\\n "), if
(nzchar(Sys.getenv("R_GUI_APP_VERSION")))
paste("\\n\\nGUI:\\n R-GUI ",
Sys.getenv("R_GUI_APP_VERSION"),
" (", Sys.getenv("R_GUI_APP_REVISION"), ")",
sep = "")
else "", "\\n\\n",
"Locale:\\n", Sys.getlocale(), "\\n\\n",
"Search Path:\\n ", paste(search(), collapse = ", "),
"\\n", sep = "", collapse = "")
if (method == "gnudoit") {
cmd <- paste("gnudoit -q '", "(mail nil \"", address,
"\")", "(insert \"", body, "\")",
"(search-backward \"Subject:\")",
"(end-of-line)'", sep = "")
system(cmd)
}
else if (method == "none") {
disclaimer <- paste("# Your mailer is set to \"none\" (default
on Windows),\n",
"# hence we cannot send the help request directly from R.\n",
"# Please copy the help request (after finishing it) to\n",
"# your favorite email program and send it to\n#\n",
"# ", address, "\n#\n",
"######################################################\n",
"\n\n", sep = "")
cat(disclaimer, file = file)
body <- gsub("\\\\n", "\n", body)
cat(body, file = file, append = TRUE)
cat("Please edit the help request.\n")
system(paste(getOption("editor"), file))
cat("The unsent help request can be found in file", file,
"\n")
}
else if (method == "mailx") {
if (missing(subject))
stop("'subject' missing")
body <- gsub("\\\\n", "\n", body)
cat(body, file = file, append = FALSE)
cat("Please edit the help request.\n")
system(paste(getOption("editor"), file))
if (is.character(ccaddress) && nzchar(ccaddress)) {
cmdargs <- paste("-s '", subject, "' -c", ccaddress,
address, "<", file, "2>/dev/null")
}
else cmdargs <- paste("-s '", subject, "'", address,
"<", file, "2>/dev/null")
status <- 1
cat("Submit the help request? ")
answer <- readline()
answer <- grep("y", answer, ignore.case = TRUE)
if (length(answer) > 0) {
cat("Sending email ...\n")
status <- system(paste("mailx", cmdargs))
if (status > 0)
status <- system(paste("Mail", cmdargs))
if (status > 0)
status <- system(paste("/usr/ucb/mail", cmdargs))
if (status == 0)
unlink(file)
else {
cat("Sending email failed!\n")
cat("The unsent help request can be found in file",
file, "\n")
}
}
else cat("The unsent help request can be found in file",
file, "\n")
}
else if (method == "ess") {
body <- gsub("\\\\n", "\n", body)
cat(body)
}
}
-----------------------------------------------------------------------
Gabor Grothendieck wrote:
> Here is another update. I have added the following:
>
> - info about using a fresh R session. (In that case ls() output is less
> essential; however, the developers of sessionInfo() might consider
> adding that as a default or as an option.)
>
> - questioner should consider use of functions.
>
> - for data use dump(x, file = "") to reproducibly display data or use
> builtin datasets listed by data()
>
> - minimal versions of slow code should be presented in cases where
> questioner is looking for faster code.
>
> - we still need to add links to illustrative sample questions in r-help
>
> The following were not added for the reason cited:
>
> - guide is not just for questioners. Important to distinguish roles
> of questioner, responder and reader.
>
> - what is to be provided ought to be given a name to make it easier
> to refer to. An unlabelled set of points is too vague. Test
> framework seems appropriately descriptive. By giving it a name
> one can request that a questioner "provide a test framework as
> defined in the posting guide summary".
>
> - self contained is not implied by reproducible. Reproducible
> only means that info is available somewhere -- not that its all
> available right in the questioner's post and all in a manner that
> is readily accessible.
>
> - focus should be on making data minimal. Don't like attachments
> since responder must save them and read them in. It encourages
> use of large rather than minimal data sets.
>
> Summary
>
> Surprisingly, the main problem for responders is not to answer the
> question but to quickly figure out what the question is, reproduce it
> in their own R session and test their answer.
>
> Test Framework. To faciliate this provide a test framework of:
>
> (1) minimal reproducible self-contained commented code and data
> that has been run in a fresh R session. That means code and
> data have been cut down as far as possible to the essentials
> needed to illustrate the problem and were run are just after
> starting up R. Also it means that its possible for responders
> to just copy the code and data section from the questioner's
> post to the clipboard and paste it into their session to see
> the same output without having to enter even one R command.
> In some cases there may be an advantage to present the code as
> a function and in the case of needing a speedup be sure to post
> a minimal version of the slow code. Use builtin data sets such
> as those listed by data() to illustrate problem or reduce your
> data to a minimum and present it reproducibly by using:
> dump("mydata", file = "")
>
> (2) comments/explanation of what the code is intended to produce
> -- Don't assume its obvious!
>
> (3) versions of all software used, e.g. sessionInfo(),
> or R.version.string; packageDescription("zoo")$Version
>
> Without self-contained reproducible code the responder must not only
> understand the question but must also create a test framework and that
> typically takes more time than answering the question! Its not fair
> to ask the responder to provide all that on top of answering the
> question. Do NOT assume the problem is so simple that it is not
> necessary.
>
> Effort. The effort taken to reduce the problem to its essentials and
> produce a test framework often solves the problem avoiding the need
> for a post in the first place. It at the least shows that the
> questioner tried to solve it themself.
>
> Subscribers. The questioner should ensure that the thread is complete
> and that it has an appropriate Subject. The purpose of the post is
> not only to help the questioner but also the other list subscribers
> and those later searching the archives.
>
>
>
>
>
> On Sat, Jun 7, 2008 at 9:38 AM, Gabor Grothendieck
> <ggrothendieck at gmail.com> wrote:
>> Here is a second version of the summary. Its been rearranged to
>> place most important info at top. Also shortened it a bit.
>>
>> It still needs links to example posts, as suggested. Anyone?
>>
>> Summary
>>
>> Surprisingly, the main problem for responders is not to answer the
>> posted questions but to quickly figure out what the question is, reproduce
>> it in their own R session and test their answer.
>>
>> Test Framework. To faciliate that provide a test framework of:
>>
>> (1) reproducible self-contained minimal code and data. That means
>> responders can copy it from the questioner's post and paste it
>> into their session to see the same output without having to
>> enter even one R command.
>> NB. dput(mydata) produces mydata in reproducible form.
>> (2) comments/explanations of what the code is intended to produce and
>> (3) versions of all software used, e.g. sessionInfo().
>>
>> Without self-contained reproducible code the responder must not only
>> understand the question but must also create a test framework and that
>> typically takes more time than answering the question! Its not fair
>> to ask the responder to provide all that on top of answering the
>> question. Do NOT assume the problem is so simple that it is not
>> necessary.
>>
>> Effort. The effort taken to reduce the problem to its essentials and
>> produce a test framework often solves the problem avoiding the need
>> for a post in the first place. It at the least shows that the
>> questioner tried to solve it themself.
>>
>> Subscribers. The questioner should ensure that the thread is complete
>> and that it has an appropriate Subject. The purpose of the post is
>> not only to help the questioner but also the other list subscribers
>> and those later searching the archives.
>>
>>
>>
>> On Fri, Jun 6, 2008 at 1:30 PM, Gabor Grothendieck
>> <ggrothendieck at gmail.com> wrote:
>>> People read the posting guide yet they are still unable to create an acceptable
>>> post. e.g.
>>> https://stat.ethz.ch/pipermail/r-help/2008-June/164092.html
>>>
>>> I think the problem is that the guide is not clear or concise enough.
>>> I suggest we add a summary at the beginning which gets to the heart
>>> of what a poster is expected to provide:
>>>
>>> Summary
>>>
>>> To maximize your change of getting a response when posting provide (1)
>>> commented,
>>> (2) minimal, (3) self-contained and (4) reproducible code. (This one
>>> line summary
>>> also appears at the end of each message to r-help.)
>>>
>>> "Self-contained" and "reproducible" mean that a responder can copy the
>>> questioner's code to
>>> the clipboard, paste it into their R session and see the same problem
>>> you as the questioner
>>> see. Note that dput(mydata) will display mydata in a reproducible way.
>>> Self-contained and reproducible are needed because:
>>> (1) Self-Effort. It shows that the questioner tried to solve the
>>> problem by themself first.
>>> (2) Test framework. Often the responder needs to play with the code a
>>> bit in order to respond
>>> or at least to give the best answer. They can't do that without a
>>> test framework that includes
>>> the data and the code to run it and its not fair to ask them to not
>>> only answer the question but
>>> also to come up with test data and to complete incomplete code.
>>> (3) Archives. Questions and answers go into the archives so they are
>>> not only for the benefit of
>>> of the questioner but also for the benefit of all future searchers of
>>> the archive. That means
>>> that its not finished if you have solved the problem for yourself.
>>> You still need to ensure that
>>> the thread has a complete solution. (For that reason its also
>>> important to give a meaningful
>>> subject to each post.)
>>>
>>> "Commented" and "minimal" also reduce the time it takes to understand
>>> the problem.
>>> Don't just dump your code as is into the message since you are just
>>> wasting your own
>>> time. Its not likely anyone will answer a message if the questioner
>>> has not taken the
>>> time to reduce it to its essential elements. Surprisingly, quite
>>> often understanding what
>>> the problem is takes the responder most of the time -- not solving the
>>> problem. Once the
>>> question is actually understood its often quite fast to answer. Thus
>>> in addition to posting
>>> it in a minimal form, comment on it sufficiently so that the responder
>>> knows what the code
>>> does and is intended to produce. It may be obvious to the questioner
>>> who is embroiled in
>>> the problem but that does not mean its obvious to others.
>>>
>>> Introduction
>>>
>>> .... rest of posting guide ...
>>>
>
> ______________________________________________
> R-devel at r-project.org mailing list
> https://stat.ethz.ch/mailman/listinfo/r-devel
--
Dr H Turner
Research Fellow
Dept. of Statistics
The University of Warwick
Coventry
CV4 7AL
Tel: 024 76575870
Fax: 024 76524532
Url: www.warwick.ac.uk/go/heatherturner
More information about the R-devel
mailing list