{"id":16570621,"url":"https://github.com/apreshill/tidyversebakeoff","last_synced_at":"2026-04-16T16:08:59.592Z","repository":{"id":95350867,"uuid":"182871613","full_name":"apreshill/tidyversebakeoff","owner":"apreshill","description":null,"archived":false,"fork":false,"pushed_at":"2019-04-22T21:34:20.000Z","size":247,"stargazers_count":2,"open_issues_count":0,"forks_count":0,"subscribers_count":2,"default_branch":"master","last_synced_at":"2025-03-05T12:48:21.693Z","etag":null,"topics":[],"latest_commit_sha":null,"homepage":null,"language":"CSS","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"mit","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/apreshill.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null}},"created_at":"2019-04-22T21:34:02.000Z","updated_at":"2019-04-23T14:01:36.000Z","dependencies_parsed_at":"2023-03-06T16:15:33.656Z","dependency_job_id":null,"html_url":"https://github.com/apreshill/tidyversebakeoff","commit_stats":null,"previous_names":[],"tags_count":0,"template":false,"template_full_name":null,"purl":"pkg:github/apreshill/tidyversebakeoff","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/apreshill%2Ftidyversebakeoff","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/apreshill%2Ftidyversebakeoff/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/apreshill%2Ftidyversebakeoff/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/apreshill%2Ftidyversebakeoff/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/apreshill","download_url":"https://codeload.github.com/apreshill/tidyversebakeoff/tar.gz/refs/heads/master","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/apreshill%2Ftidyversebakeoff/sbom","scorecard":null,"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":286080680,"owners_count":31893445,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2026-04-16T11:36:10.202Z","status":"ssl_error","status_checked_at":"2026-04-16T11:36:09.652Z","response_time":69,"last_error":"SSL_connect returned=1 errno=0 peeraddr=140.82.121.5:443 state=error: unexpected eof while reading","robots_txt_status":"success","robots_txt_updated_at":"2025-07-24T06:49:26.215Z","robots_txt_url":"https://github.com/robots.txt","online":false,"can_crawl_api":true,"host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":[],"created_at":"2024-10-11T21:19:11.727Z","updated_at":"2026-04-16T16:08:59.551Z","avatar_url":"https://github.com/apreshill.png","language":"CSS","funding_links":[],"categories":[],"sub_categories":[],"readme":"# Online course starter: R\n\nThis is a starter repo based on the\n[course framework](https://github.com/ines/spacy-course) I developed for my\n[spaCy course](https://course.spacy.io). The front-end is powered by\n[Gatsby](http://gatsbyjs.org/) and [Reveal.js](https://revealjs.com) and the\nback-end code execution uses [Binder](https://mybinder.org) 💖\n\n_This repo could use some better code examples. Also, if you have experience\nwith R, feel free to suggest improvements to the\n[test logic and template](#adding-tests). It all works as expected, but there\nmight be ways to make it more elegant._\n\n[![Deploy to Netlify](https://www.netlify.com/img/deploy/button.svg)](https://app.netlify.com/start/deploy?repository=https://github.com/ines/courser-starter-r)\n\n[![](https://user-images.githubusercontent.com/13643239/56341448-68fe9380-61b5-11e9-816f-5c71ae71b94f.png)](https://course-starter-r.netlify.com)\n\n## ✅ Quickstart\n\n1. [Import](https://github.com/new/import) this repo, install it and make sure\n   the app is running locally.\n2. Customize the [`meta.json`](meta.json) and\n   [`binder/install.R`](binder/install.R).\n3. Build a [Binder](https://mybinder.org) from the `binder` branch of this repo.\n4. Add content (chapters, exercises and slides) and optionally add separate\n   content license.\n5. Customize the UI theme in [`theme.sass`](theme.sass) and update images in\n   [`static`](static) as needed.\n6. Deploy the app, e.g. to [Netlify](https://netlify.com).\n\n### Running the app\n\nTo start the local development server, install [Gatsby](https://gatsbyjs.org)\nand then all other dependencies. This should serve up the app on\n`localhost:8000`.\n\n```bash\nnpm install -g gatsby-cli  # Install Gatsby globally\nnpm install                # Install dependencies\nnpm run dev                # Run the development server\n```\n\n## 🎨 Customization\n\nThe app separates its source and content – so you usually shouldn't have to dig\ninto the JavaScript source to change things. The following points of\ncustomization are available:\n\n| Location             | Description                                                                                                                           |\n| -------------------- | ------------------------------------------------------------------------------------------------------------------------------------- |\n| `meta.json`          | General config settings, title, description etc.                                                                                      |\n| `theme.sass`         | Color theme.                                                                                                                          |\n| `binder/install.R`   | Packages to install.                                                                                                                  |\n| `binder/runtime.txt` | YYYY-MM-DD snapshot at MRAN that will be used for installing libraries. [See here](https://github.com/binder-examples/r) for details. |\n| `chapters`           | The chapters, one Markdown file per chapter.                                                                                          |\n| `slides`             | The slides, one Markdown file per slide deck.                                                                                         |\n| `static`             | Static assets like images, will be copied to the root.                                                                                |\n\n### `meta.json`\n\nThe following meta settings are available. **Note that you have to re-start\nGatsby to see the changes if you're editing it while the server is running.**\n\n| Setting              | Description                                                                                                                                |\n| -------------------- | ------------------------------------------------------------------------------------------------------------------------------------------ |\n| `courseId`           | Unique ID of the course. Will be used when saving completed exercises to the browser's local storage.                                      |\n| `title`              | The title of the course.                                                                                                                   |\n| `slogan`             | Course slogan, displayed in the page title on the front page.                                                                              |\n| `description`        | Course description. Used for site meta and in footer.                                                                                      |\n| `bio`                | Author bio. Used in the footer.                                                                                                            |\n| `siteUrl`            | URL of the deployed site (without trailing slash).                                                                                         |\n| `twitter`            | Author twitter handle, used in Twitter cards meta.                                                                                         |\n| `fonts`              | [Google Fonts](https://fonts.google.com) to load. Should be the font part of the URL in the embed string, e.g. `Lato:400,400i,700,700i`.   |\n| `testTemplate`       | Template used to validate the answers. `${solution}` will be replaced with the user code and `${test}` with the contents of the test file. |\n| `juniper.repo`       | Repo to build on Binder in `user/repo` format. Usually the same as this repo.                                                              |\n| `juniper.branch`     | Branch to build. Ideally not `master`, so the image is not rebuilt every time you push.                                                    |\n| `juniper.lang`       | Code language for syntax highlighting.                                                                                                     |\n| `juniper.kernelType` | The name of the kernel to use.                                                                                                             |\n| `juniper.debug`      | Logs additional debugging info to the console.                                                                                             |\n| `showProfileImage`   | Whether to show the profile image in the footer. If `true`, a file `static/profile.jpg` needs to be available.                             |\n| `footerLinks`        | List of objects with `\"text\"` and `\"url\"` to display as links in the footer.                                                               |\n| `theme`              | Currently only used for the progressive web app, e.g. as the theme color on mobile. For the UI theme, edit `theme.sass`.                   |\n\n### Static assets\n\nAll files added to `/static` will become available at the root of the deployed\nsite. So `/static/image.jpg` can be referenced in your course as `/image.jpg`.\nThe following assets need to be available and can be customized:\n\n| File              | Description                                              |\n| ----------------- | -------------------------------------------------------- |\n| `icon.png`        | Custom [favicon](https://en.wikipedia.org/wiki/Favicon). |\n| `logo.svg`        | The course logo.                                         |\n| `profile.jpg`     | Photo or profile image.                                  |\n| `social.jpg`      | Social image, displayed in Twitter and Facebook cards.   |\n| `icon_check.svg`  | \"Check\" icon displayed on \"Mark as completed\" button.    |\n| `icon_slides.svg` | Icon displayed in the corner of a slides exercise.       |\n\n## ✏️ Content\n\n### File formats\n\n#### Chapters\n\nChapters are placed in [`/chapters`](/chapters) and are Markdown files\nconsisting of `\u003cexercise\u003e` components. They'll be turned into pages, e.g.\n`/chapter1`. In their frontmatter block at the top of the file, they need to\nspecify `type: chapter`, as well as the following meta:\n\n```yaml\n---\ntitle: The chapter title\ndescription: The chapter description\nprev: /chapter1 # exact path to previous chapter or null to not show a link\nnext: /chapter3 # exact path to next chapter or null to not show a link\nid: 2 # unique identifier for chapter\ntype: chapter # important: this creates a standalone page from the chapter\n---\n\n```\n\n#### Slides\n\nSlides are placed in [`/slides`](/slides) and are markdown files consisting of\nslide content, separated by `---`. They need to specify the following\nfrontmatter block at the top of the file:\n\n```yaml\n---\ntype: slides\n---\n\n```\n\nThe **first and last slide** use a special layout and will display the headline\nin the center of the slide. **Speaker notes** (in this case, the script) can be\nadded at the end of a slide, prefixed by `Notes:`. They'll then be shown on the\nright next to the slides. Here's an example slides file:\n\n```markdown\n---\ntype: slides\n---\n\n# Processing pipelines\n\nNotes: This is a slide deck about processing pipelines.\n\n---\n\n# Next slide\n\n- Some bullet points here\n- And another bullet point\n\n\u003cimg src=\"/image.jpg\" alt=\"An image located in /static\" /\u003e\n```\n\n### Custom Elements\n\nWhen using custom elements, make sure to place a newline between the\nopening/closing tags and the children. Otherwise, Markdown content may not\nrender correctly.\n\n#### `\u003cexercise\u003e`\n\nContainer of a single exercise.\n\n| Argument     | Type            | Description                                                    |\n| ------------ | --------------- | -------------------------------------------------------------- |\n| `id`         | number / string | Unique exercise ID within chapter.                             |\n| `title`      | string          | Exercise title.                                                |\n| `type`       | string          | Optional type. `\"slides\"` makes container wider and adds icon. |\n| **children** | -               | The contents of the exercise.                                  |\n\n```markdown\n\u003cexercise id=\"1\" title=\"Introduction to spaCy\"\u003e\n\nContent goes here...\n\n\u003c/exercise\u003e\n```\n\n#### `\u003ccodeblock\u003e`\n\n| Argument     | Type            | Description                                                                                  |\n| ------------ | --------------- | -------------------------------------------------------------------------------------------- |\n| `id`         | number / string | Unique identifier of the code exercise.                                                      |\n| `source`     | string          | Name of the source file (without file extension). Defaults to `exc_${id}` if not set.        |\n| `solution`   | string          | Name of the solution file (without file extension). Defaults to `solution_${id}` if not set. |\n| `test`       | string          | Name of the test file (without file extension). Defaults to `test_${id}` if not set.         |\n| **children** | string          | Optional hints displayed when the user clicks \"Show hints\".                                  |\n\n```markdown\n\u003ccodeblock id=\"02_03\"\u003e\n\nThis is a hint!\n\n\u003c/codeblock\u003e\n```\n\n#### `\u003cslides\u003e`\n\nContainer to display slides interactively using Reveal.js and a Markdown file.\n\n| Argument | Type   | Description                                   |\n| -------- | ------ | --------------------------------------------- |\n| `source` | string | Name of slides file (without file extension). |\n\n```markdown\n\u003cslides source=\"chapter1_01_introduction-to-spacy\"\u003e\n\u003c/slides\u003e\n```\n\n#### `\u003cchoice\u003e`\n\nContainer for multiple-choice question.\n\n| Argument     | Type            | Description                                                                                  |\n| ------------ | --------------- | -------------------------------------------------------------------------------------------- |\n| `id`         | string / number | Optional unique ID. Can be used if more than one choice question is present in one exercise. |\n| **children** | nodes           | Only `\u003copt\u003e` components for the options.                                                     |\n\n```markdown\n\u003cchoice\u003e\n\n\u003copt text=\"Option one\"\u003eYou have selected option one! This is not good.\u003c/opt\u003e\n\u003copt text=\"Option two\" correct=\"true\"\u003eYay! \u003c/opt\u003e\n\n\u003c/choice\u003e\n```\n\n#### `\u003copt\u003e`\n\nA multiple-choice option.\n\n| Argument     | Type   | Description                                                                                    |\n| ------------ | ------ | ---------------------------------------------------------------------------------------------- |\n| `text`       | string | The option text to be displayed. Supports inline HTML.                                         |\n| `correct`    | string | `\"true\"` if the option is the correct answer.                                                  |\n| **children** | string | The text to be displayed if the option is selected (explaining why it's correct or incorrect). |\n\n### Setting up Binder\n\nThe [`requirements.txt`](binder/requirements.txt) in the repository defines the\npackages that are installed when building it with Binder. You can specify the\nbinder settings like repo, branch and kernel type in the `\"juniper\"` section of\nthe `meta.json`. I'd recommend running the very first build via the interface on\nthe [Binder website](https://mybinder.org), as this gives you a detailed build\nlog and feedback on whether everything worked as expected. Enter your repository\nURL, click \"launch\" and wait for it to install the dependencies and build the\nimage.\n\n![Binder](https://user-images.githubusercontent.com/13643239/39412757-a518d416-4c21-11e8-9dad-8b4cc14737bc.png)\n\n### Adding tests\n\nTo validate the code when the user hits \"Submit\", we're currently using a\nslightly hacky trick. Since the R code is sent back to the kernel as a string,\nwe can manipulate it and add tests – for example, exercise `exc_01_02_01.R` will\nbe validated using `test_01_02_01.R` (if available). The user code and test are\ncombined using a string template. At the moment, the `testTemplate` in the\n`meta.json` looks like this:\n\n```r\nsuccess \u003c- function(text) {\n    cat(paste(\"\\033[32m\", text, \"\\033[0m\", sep = \"\"))\n}\n\n.solution \u003c- \"${solutionEscaped}\"\n\n${solution}\n\n${test}\ntryCatch({\n    test()\n}, error = function(e) {\n    cat(paste(\"\\033[31m\", e[1], \"\\033[0m\", sep = \"\"))\n})\n```\n\nIf present, `${solution}` will be replaced with the string value of the\nsubmitted user code, and `${solutionEscaped}` with the code but with all `\"`\nreplaced by `\\\"`, so we can assign it to a variable as a string and check\nwhether the submission includes something. We also insert the regular solution,\nso we can actually run it and check the objects it creates. `${test}` is\nreplaced by the contents of the test file. The template also defines a `success`\nfunction, which prints a formatted green message and can be used in the tests.\nFinally, the `tryCatch` expression checks if the test function raises a `stop`\nand if so, it outputs the formatted error message. This also hides the full\nerror traceback (which can easily leak the correct answers).\n\nA test file could then look like this:\n\n```r\ntest \u003c- function() {\n    if (some_var != length(mtcars)) {\n        stop(\"Are you getting the correct length?\")\n    }\n    if (!grepl(\"print(mtcars$gear)\", .solution, fixed = TRUE)) {\n        stop(\"Are you printing the correct variable?\")\n    }\n    success(\"Well done!\")\n}\n```\n\nThe string answer is available as `.solution`, and the test also has access to\nthe solution code.\n\n---\n\nFor more details on how it all works behind the scenes, see\n[the original course repo](https://github.com/ines/spacy-course).\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fapreshill%2Ftidyversebakeoff","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fapreshill%2Ftidyversebakeoff","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fapreshill%2Ftidyversebakeoff/lists"}