-
Notifications
You must be signed in to change notification settings - Fork 240
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Add Python code chunks (& other language support) using RMarkdown language engines #310
Conversation
Thank you for looking into this!
Yes. Ideally, it would be great to use So make sure this is passed along, we can make a similar line for Line 190 in 6518724
Then, in exercise.R where you are currently setting the engine, we could read the engine <- knitr::opts_chunk$get("exercise.engine")
if (!is.null(engine)) {
knitr::opts_chunk$set(engine = engine)
} The engine retrieval line could be moved to the top of the function (just above code checking) to be passed into the |
Making notes of things that should be addressed at some point (maybe not this PR)
|
Ah so helpful!! Thank you @schloerke . I thought there may be some knitr intercepting going on... and I neglected to use I'll proceed keeping those features in mind. I noticed that tabs weren't functioning as I expected when writing Python code, so I may have to tackle a bit of the browser UI stuff along the way in the context of input. More soon! |
Thanks! Feel free to push a "broken" PR and ask questions. |
Hi @schloerke - had time to return to this today & a little more progress! We can now use
evaluates to
evaluates to Re: disabling pre/post checking and last line evaluation**I couldn't easily move the engine assignment lines (219-221) as the restoring knitr options lines overwrote them. As I work-around, I set a When I attempted to start disabling code checking or the last line evaluation specific code, e.g. by wrapping the segment you called out earlier in a giant is.null() statement, I wasn't successful. Any advice for specifically which aspects of the checking to disable? I can continue poking around, but wanted to see if you had any quick guidance. Thank you! |
I am so happy to see these things happening! Thanks, @zoews and @schloerke ! |
Yes. Actually looking at this bug right now. Can you pull in my branch so that we have a consistent tutorial to look at? It'll also be easier to collaborate too. # pull in rstudio branch
git pull https://github.com/rstudio/learnr.git exercise_language Allows us to run |
One of the larger issues here is that the Ace editor instances assume that the inner code is always R code, and so the code is always diagnosed as though it were R code. See: learnr/inst/lib/tutorial/tutorial.js Lines 4 to 16 in 6518724
I think there needs to be some way of declaring the completion + diagnostics engines used for different programming languages (or just disabling them for now with Python code). See also: https://github.com/rstudio/learnr/blob/master/inst/lib/tutorial/tutorial-diagnostics.js |
@kevinushey Yes! Absolutely. Was also thinking of just disabling it for now. For me, the blocker comes at evaluating/checking the code. If that can be solved, then we can update the UI. |
* master: Only return the message of the failed evaluation (rstudio#311)
@zoews Fixed. Please pull again. I should have some direction for you to look at here soon. Thank you for the help! |
@zoews I've added some more fixed. Please pull again. Notes
|
I'm following progress here with great interest. We have
I'm pretty sure I could enable code checking of outcomes rather than of the code's text, but I like that people check their own work. It means they can see correct answers multiple times rather than just reviewing their errors and moving on right away when they get it right, without re-reading the correct code. I should mention that most of our learners are highly self motivated. They are taking our classes because they really want to learn. There is no reason to have them "earn" anything other than knowledge. We gauge our success by how much learners think they have advanced towards meeting their own goals (have successfully completed an analysis on their own data sets, etc.). In short, I'm fine with moving forward with multiple languages even if it means I can't check people's code. Try http://www.a-mess.org/list/ for a list of our lessons. You're welcome to try them out and refer them to others, but WARNING: They will move to a new server as soon as we can make that happen. The link puts you on a a behind-the-scenes list that isn't meant as a landing page for the world, but you can tool around if you like to see the project @zoews and I are working on. The lessons include updates for swirl lessons and some statistics lessons based on the Biostatistics Handbook by John H. McDonald and the R Companion for it by Salvatore Mangiafico. |
oh fantastic, thank you @schloerke! (and @kevinushey & @braunsb too!) I've pulled in changes from your branch and pushed them here as you can see. FYI, if I try my two examples from earlier, I continue to see similar errors, but the wording is slightly different: Was this your expectation that these chunks would still produce errors at this point? Or is this something strange continuing to happen? In the meantime, as per your notes, I can look into the step where the chunks are created as an .Rmd for evaluation. I can see how that would be a helpful pattern to implement. Thanks for your good communication around this and please feel free to direct me to how I can be helpful! |
Np! This is a really useful/highly requested feature!! Being able to pull each other's branches solves a lot of issues. Thank you! A more explicit example of the goal of how
|
@schloerke back working on this today FYI! I'll keep an eye on the |
update: with @braunsb's contributions, we were able to circumvent the Yay! Next on the list:
I'll spend some time on these today. @schloerke Thank you! |
Hmm yes I can definitely see the idea of circumventing that pre-rendering layer to pass along However, I'm finding that I can't access I also tried passing along a Is |
Oops! My fault. I meant the Line 118 in 3b230e1
I am looking at them using # other preserved_options ~ line 195
preserved_options$engine <- "R"
str(options)
browser()
|
Yes. This is the sneaky part that learnr hides from its users... shiny-prerendered documents write everything to a file, which is then re-read at run time. The connection object is a s4 object, not an a basic value (atomics, vectors, and list). Learnr is not able to serialize parameters freely. Ex: dput(options$connection)
#> new("SQLiteConnection", ptr = <pointer: 0x7f8eee4ae4d0>, dbname = "./inst/tutorials/python/data_raw/portal_mammals.sqlite",
#> loadable.extensions = TRUE, flags = 70L, vfs = "", ref = <environment>,
#> bigint = "integer64") The pointer above can not be recreated at runtime. So the connection object can not be recreated. Hopefully what we'll be able to do is to capture the original parameters supplied and use them to create the exercise rmd file such as
```{r setup, include=FALSE}
library(learnr)
tutorial_options(
exercise.checker = function(...) {
cat("REGULAR!!")
vals <- list(...)
cat("dots...\n")
str(vals)
cat("envir_result...\n")
str(as.list(vals$envir_result))
cat("envir_prep...\n")
str(as.list(vals$envir_prep))
}
)
# altered from https://datacarpentry.org/R-ecology-lesson/05-r-and-databases.html
if (!dir.exists("data_raw")) {
dir.create("data_raw")
}
if (!file.exists("data_raw/portal_mammals.sqlite")) {
download.file(url = "https://ndownloader.figshare.com/files/2292171",
destfile = "data_raw/portal_mammals.sqlite", mode = "wb")
}
mammals <- DBI::dbConnect(RSQLite::SQLite(), "data_raw/portal_mammals.sqlite")
```
```{sql sql-not-r, connection=mammals, output.var='surveys'}
SELECT *
FROM `surveys`
LIMIT 10
```
The code above would just be a direct copy of the |
@yihui Is it possible to capture the unevaluated parameters of an rmarkdown chunk? I'm trying to pass through the parameters without the user having to do anything custom. Thank you!! |
hi @schloerke I'm with you on using the pattern: pass along serielized/unevaluated parameters -> (bypass shiny pre-rendering) -> combine with code + setup to output chunks serially into .rmd file -> execute as we're already doing. I'm also not sure how to achieve that while e.g. resolving that sql connection pointer issue, so I'll pause here to see if @yihui is able to weigh in. @schloerke in case this pattern is a showstopper/takes more upstream changes to implement/etc before SQL is supported: would you consider accepting the PR at current scope and moving this set of changes to a new PR? I'm working on the project that @braunsb mentioned and we would love to start using Python chunks in our lessons in the short term. if that's acceptable I can keep checking into that other PR as well. thank you! |
@schloerke Sorry this thread is too long and I'm not sure if I get what you need, but |
Sounds good! |
Hey @schloerke -- happy 2020! I tested out supporting This of course kicks the can down the road re: implementing a no-evaluation pattern for the chunks, but given that it works now with all three languages, wanted to present it as one possible option. |
@zoews this is remarkable! At the risk of sounding greedy—any chance of adding Bash? |
@zoews This is all great work. Unfortunately, I do not want to give it the full green light yet. I'm happy to merge this PR into a standing "multiple engine" branch that you (and others) can make more PRs/improvements. Does this work for you? Current thoughts:
|
This comment has been minimized.
This comment has been minimized.
@schloerke that makes a lot of sense! I think merging into a "multiple engine" branch, and giving more thought to the concerns you listed, is a great next step. Count me in. In the meantime, our team will be building from my forked repo in order to deploy Python + other lessons in our modular learning environment in the next few weeks. I imagine this will provoke some further ideas/tweaks that I can propagate back to the multiple engine branch. Thank you! |
Notes for me to look at... |
Having learnr work with R, SQL, and Python would be amazing! @zoews Do you now have this working in your fork? Could you share some examples perhaps? |
Found it: https://github.com/zoews/learnr/blob/master/inst/tutorials/python/python.Rmd Related question: Is it possible to change the mode to "python" for syntax highlighting and even the ace theme? Something like, the below would be great.
Would also love vim keybindings and keyboard short-cuts to run code, etc. as is available in https://github.com/trestletech/shinyAce |
@vnijs ... baby steps. There are still a lot of rough edges to fix. But, there is no reason to not generalize language support. We will need to ship multiple Ace languages, but will be achievable. For For learnr/inst/rmarkdown/templates/tutorial/resources/tutorial-format.htm Lines 232 to 240 in e72c1f9
We're very aware of getting multi-language support working. Our push right now is to make sure it can execute in a safe/reproducible environment. Ex: See #345 |
Thanks for the quick response @schloerke. I expect there is a lot of interest in tools like leanr as most school in the US have already determined that summer classes will be "virtual" and there will be a lot of international students with issues getting visas on time to be on campus in fall. To get the extra components for python, sql, and vim I expect you would just need to add the below to update-ace.R (see also newly created issues as you suggested). Not sure where you store these files in the github repo. Do you graft them together into ace.js? If there is anything (non-JS) I can do to help out please let me now. I'm planning to use some form of learnr (R-python-sql) + gradethis + submitr, hopefully in the form of a website of tutorials, for summer and fall classes so I have some motivation :)
|
Dear all, |
@dputhier Yes, this feature is exciting! @vnijs Good catch on the ace editor! I very am happy to showcase tutorials/vignettes of how to organize packages for teaching. A "real life" tutorial with all three packages would be amazing! @nischalshrestha (and I) is currently working on a new approach (and also allowing for chained setup chunks; another big request!), learning from @zoews's branch. (We will be copying over a lot of the UI improvements already solved in this branch.) When @nischalshrestha's branch is ready, I'll be sure to tag everyone interested! 😃😃 |
hey @schloerke just seeing this -- absolutely! so thrilled to see the new PRs -- long live polyglot learnr! |
(This is an early PR as a place to discuss these changes, but please let me know if another format for discussing/troubleshooting a PR is better @schloerke !)
As per #213 I am working on a PR to enable Python (and eventually more language) support in learnr. As proof of concept, I was able to modify exercise.R to manually set
knitr::opts_chunk$set(engine='python')
and test with code permissible in syntax in R and Python, but with different evaluation:As a code chunk in a learnr lesson now returns:
False
8
Indicating that this chunk runs with the Python engine. However, I was unable to set this on a chunk-by-chunk basis. I would like to use the language tag specified in the knitr code chunk (e.g. the
python
in{python exercise=TRUE...}
) OR a new knitr hook ({r exercise=TRUE, exercise.engine='python'...}
.I ran into issues modifying
knitr-hooks.R
to pass along this information. I tried to pass along the engine name to preserved_options in order to accesspython
viaoptions$engine
in exercise.R, but this failed. This may be my lack of understanding of how knitr-hooks work (OR they might be inappropriate for this task and another method would be preferable).Question: is there another strategy for passing along and accessing the engine option for a code chunk within exercise.R? I feel like I'm missing an aspect of the interaction between code chunks -> knitr -> exercise.R. Note that we definitely will want to use this variable to e.g. introduce conditional syntax/last line checking as per #213 for implementing multi-language support robustly in learnr.
I'll be able to move on to working with code checking/etc. issues once I can access the engine parameter from within exercise.R. Thank you!