{"id":13476065,"url":"https://github.com/datacamp/datacamp-light","last_synced_at":"2025-05-14T11:12:06.802Z","repository":{"id":3910096,"uuid":"50122513","full_name":"datacamp/datacamp-light","owner":"datacamp","description":"Convert any blog or website to an interactive learning platform for data science","archived":false,"fork":false,"pushed_at":"2025-03-27T16:00:14.000Z","size":1728,"stargazers_count":1333,"open_issues_count":59,"forks_count":362,"subscribers_count":86,"default_branch":"master","last_synced_at":"2025-04-15T03:37:29.581Z","etag":null,"topics":[],"latest_commit_sha":null,"homepage":"","language":"TypeScript","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"agpl-3.0","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/datacamp.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,"zenodo":null}},"created_at":"2016-01-21T17:02:22.000Z","updated_at":"2025-04-01T16:06:18.000Z","dependencies_parsed_at":"2023-07-05T19:32:27.329Z","dependency_job_id":"f6fa6d7b-88c0-4d23-9916-82e7d455799e","html_url":"https://github.com/datacamp/datacamp-light","commit_stats":{"total_commits":169,"total_committers":26,"mean_commits":6.5,"dds":0.7633136094674556,"last_synced_commit":"1bc934af5d5409fe58cbc64149959d5c317bdbd1"},"previous_names":[],"tags_count":23,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/datacamp%2Fdatacamp-light","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/datacamp%2Fdatacamp-light/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/datacamp%2Fdatacamp-light/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/datacamp%2Fdatacamp-light/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/datacamp","download_url":"https://codeload.github.com/datacamp/datacamp-light/tar.gz/refs/heads/master","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":254129524,"owners_count":22019628,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","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-07-31T16:01:26.260Z","updated_at":"2025-05-14T11:12:03.247Z","avatar_url":"https://github.com/datacamp.png","language":"TypeScript","readme":"\u003ch1 align=\"center\"\u003eDataCamp Light\u003c/h1\u003e\n\u003cp align=\"center\"\u003e\n  \u003ca href=\"https://github.com/datacamp/datacamp-light/projects/1\"\u003eRoadmap\u003c/a\u003e |\n  \u003ca href=\"https://cdn.datacamp.com/dcl-react-prod/index.html\"\u003eDocs\u003c/a\u003e\n\u003c/p\u003e\n\u003cp align=\"center\"\u003e\n  \u003ca href=\"https://codecov.io/gh/datacamp/datacamp-light\"\u003e\u003cimg src=\"https://codecov.io/gh/datacamp/datacamp-light/branch/beta/graph/badge.svg\" /\u003e\u003c/a\u003e\n\u003c/p\u003e\n\n[![DataCamp Light banner](https://assets.datacamp.com/img/github/datacamp-light/banner-new.png \"Banner\")](https://cdn.datacamp.com/dcl-react/standalone-example.html)\n\n\u003cdetails\u003e\n\u003csummary\u003e\u003cstrong\u003eTable of Contents\u003c/strong\u003e\u003c/summary\u003e\n\n\u003c!-- TOC is automatically updated on the pre-commit hook --\u003e\n\n\u003c!-- toc --\u003e\n\n- [Features](#features)\n- [How to run the app](#how-to-run-the-app)\n- [Writing the HTML block](#writing-the-html-block)\n  * [Pre-Exercise Code](#pre-exercise-code)\n  * [Sample Code](#sample-code)\n  * [Solution](#solution)\n  * [Submission Correctness Test (SCT)](#submission-correctness-test-sct)\n  * [Hint](#hint)\n  * [Other Options](#other-options)\n- [How does it work?](#how-does-it-work)\n- [Contributing](#contributing)\n  * [Dependencies](#dependencies)\n  * [Testing](#testing)\n    + [Run tests](#run-tests)\n    + [Reducers](#reducers)\n    + [Components](#components)\n    + [Middleware](#middleware)\n  * [DevOps](#devops)\n    + [Formatting with Prettier](#formatting-with-prettier)\n    + [Code Quality: ESLint, TSLint, Stylelint](#code-quality-eslint-tslint-stylelint)\n    + [Commit Messages](#commit-messages)\n    + [Continuous Integration](#continuous-integration)\n    + [Packages used that you might want to know about](#packages-used-that-you-might-want-to-know-about)\n\n\u003c!-- tocstop --\u003e\n\n\u003c/details\u003e\n\n--------------------------------------------------------------------------------\n\n\n\n\n\n\n## Features\n\n* Convert any website or blog to an interactive learning platform.\n* Works for both R and Python. Sessions are maintained on DataCamp's servers.\n* Convert existing markdown documents to an interactive course using [the\n  tutorial package](https://github.com/datacamp/tutorial).\n* Check out a [demo R and Python\n  example](https://cdn.datacamp.com/dcl-react/standalone-example.html).\n* Leverage the same Submission Correctness Tests (SCT) DataCamp uses for all\n  their courses. For R, there's the\n  [testwhat](https://github.com/datacamp/testwhat) ([GitHub\n  wiki](https://github.com/datacamp/testwhat/wiki)); for Python, there's\n  [pythonwhat](https://github.com/datacamp/pythonwhat) ([GitHub\n  wiki](https://github.com/datacamp/pythonwhat/wiki)).\n\n\n\n\n\n\n## How to run the app\nAdd the script to your HTML page (there is an example in\n`examples/standalone-example.html`):\n\n```html\n\u003cscript type=\"text/javascript\" src=\"//cdn.datacamp.com/dcl-react.js.gz\"\u003e\u003c/script\u003e\n```\n\nThat's it! If your app adds DataCamp Light exercises after the initial page load\n(for example, in React apps), call the following function to initialize those\nnew exercises:\n\n```js\ninitAddedDCLightExercises();\n```\n\n**You can also use the JavaScript library in a stackoverflow.com answer by\nincluding the exercise and script tag as a snippet.**\n\n\n\n## Writing the HTML block\n\nAfter including the JavaScript library, you can start writing HTML blocks in the\nformat below. These will be dynamically converted to exercises.\n\n```html\n\u003cdiv data-datacamp-exercise data-lang=\"r\"\u003e\n\t\u003ccode data-type=\"pre-exercise-code\"\u003e\n\t\t# This will get executed each time the exercise gets initialized\n\t\tb = 6\n\t\u003c/code\u003e\n\t\u003ccode data-type=\"sample-code\"\u003e\n\t\t# Create a variable a, equal to 5\n\n\n\t\t# Print out a\n\n\n\t\u003c/code\u003e\n\t\u003ccode data-type=\"solution\"\u003e\n\t\t# Create a variable a, equal to 5\n\t\ta \u003c- 5\n\n\t\t# Print out a\n\t\tprint(a)\n\t\u003c/code\u003e\n\t\u003ccode data-type=\"sct\"\u003e\n\t\ttest_object(\"a\")\n\t\ttest_function(\"print\")\n\t\tsuccess_msg(\"Great job!\")\n\t\u003c/code\u003e\n\t\u003cdiv data-type=\"hint\"\u003eUse the assignment operator (\u003ccode\u003e\u003c-\u003c/code\u003e) to create the variable \u003ccode\u003ea\u003c/code\u003e.\u003c/div\u003e\n\u003c/div\u003e\n```\n\nAs we can see in the example, the whole exercise is contained in a single\n`\u003cdiv\u003e` element with two data attributes `data-datacamp-exercise` and\n`data-lang`. The first attribute `data-datacamp-exercise` indicates that the\n`\u003cdiv\u003e` should be treated as a DataCamp Light exercise, while the other\nattribute `data-lang` specifies which programming language should be used. The\naccepted values for `data-lang` are `r` and `python`. There is also an optional\nattribute `data-height` which can sets the height in `px` of the div (minimum\nheight is `300px`) or set the size according to the amount of sample code lines:\n`data-height=\"auto\"`.\n\n\n### Pre-Exercise Code\n\nPre-exercise code is executed when the R/Python session is initialized. You can\nuse it to pre-load datasets, packages, etc. for students. The way to specify\nthis is by defining a `\u003ccode\u003e` tag containing your initialization code and set\nthe `data-type` attribute to `pre-exercise-code` like this:\n\n```html\n\u003ccode data-type=\"pre-exercise-code\"\u003e\n\t# This will get executed each time the exercise gets initialized\n\tb = 6\n\u003c/code\u003e\n```\n\nIn our example we initialize the (rather useless) variable `b` with value `6`.\n\n\n\n### Sample Code\n\nTo set the sample code that will be present initially in the code editor, a\n`\u003ccode\u003e` tag should be defined containing the sample code and the `data-type`\nattribute should be set to `sample-code` like this:\n\n```html\n\u003ccode data-type=\"sample-code\"\u003e\n\t# Create a variable a, equal to 5\n\n\n\t# Print out a\n\n\n\u003c/code\u003e\n```\n\nOur example simply shows a couple of comments together with some newlines. The\nJavaScript library also takes care of stripping leading indentation so no need\nto worry about that.\n\n\n\n### Solution\n\nTo set the solution code, a `\u003ccode\u003e` tag should be defined containing the\nsolution code and the `data-type` attribute should be set to `solution`\nlike this:\n\n```html\n\u003ccode data-type=\"solution\"\u003e\n\t# Create a variable a, equal to 5\n\ta \u003c- 5\n\n\t# Print out a\n\tprint(a)\n\u003c/code\u003e\n```\n\n\n\n### Submission Correctness Test (SCT)\n\nA Submission Correctness Test is used to check whether the code submitted by the\nuser properly solves the exercise. For detailed information on this you can look\nat [the documentation for R](https://github.com/datacamp/testwhat) and at [the\ndocumentation for Python](https://github.com/datacamp/pythonwhat). The way to\nspecify the SCT is by defining a `\u003ccode\u003e` tag containing your SCT code and set\nthe `data-type` attribute to `sct` like this:\n\n```html\n\u003ccode data-type=\"sct\"\u003e\n\ttest_object(\"a\")\n\ttest_function(\"print\")\n\tsuccess_msg(\"Great job!\")\n\u003c/code\u003e\n```\n\nIn our example the first line checks whether the user declared the variable `a`\nand whether its value matches that of the solution code. The second line checks\nwhether the `print` function is called and lastly a success message is specified\nthat will be shown to the user when the exercise is successfully completed.\n\n\n\n### Hint\n\nTo specify a hint, a tag should be defined containing the hint and the\n`data-type` attribute should be set to `hint` like this:\n\n```html\n\u003cdiv data-type=\"hint\"\u003e\n    Use the assignment operator (\u003ccode\u003e\u003c-\u003c/code\u003e) to create the variable \u003ccode\u003ea\u003c/code\u003e.\n\u003c/div\u003e\n```\n\nIt is possible for the hint to contain for instance `\u003ccode\u003e` tags as is the case in our example.\n\n\n\n### Other Options\n\n- Add a `data-show-run-button` attribute to always show the \"Run\" button, so your visitors can try out the code without submitting it.\n- Add a `data-no-lazy-loading` attribute to load all exercises as soon as the page is loaded, instead of waiting for the user to scroll down to them. This may cause performance issues, but can fix compatibility problems with iFrame-based pages.\n- Add the following css to the styling of your page to hide the configuration code of the exercises until they are loaded:\n```css\n[data-datacamp-exercise] {\n  visibility: hidden;\n}\n```\n\n\n\n## How does it work?\n\n`div`s with the `data-datacamp-exercise` attribute are converted into a minimal\nversion of DataCamp's learning interface (for the real deal, you can visit\n[www.datacamp.com](https://www.datacamp.com/?utm_source=datacamp_light\u0026utm_medium=readme\u0026utm_term=the_real_deal)).\nIt contains a session manager that connects to DataCamp's servers to provide an\nR or Python session as if you're working on your local system. The R and Python\ncomputing environments feature the most popular packages:\n\n- [See list of packages for R](http://documents.datacamp.com/default_r_packages.txt)\n- [See list of packages for Python](http://documents.datacamp.com/default_python_packages.txt)\n\nIf you want to use a package that is not available, create an issue and we can\ninstall it (it's not possible to install packages at runtime).\n\n\n\n\n\n\n## Contributing\n\nIf you'd like to contribute, awesome! You can start by reading this section of\nthe readme to get an idea of the technical details of this project. For the most\npart, it's structured as a standard React/Redux project (written in TypeScript)\nso if you're not familiar with one of those, you might want to read up a bit.\n\nTo develop DataCamp Light, you'll need to run the app locally. This repository\nincludes some example exercises to test it on.\n\nGet started by cloning this repository, installing the dependencies and starting\nthe development server. As you make changes, the page will reload with your new\ncode.\n\n```\ngit clone https://github.com/datacamp/datacamp-light.git\ncd datacamp-light\ngit checkout beta\nnpm i\nnpm start\n```\n\n\n\n### Dependencies\n\nThe `vendor/` folder includes minified code of some internal DataCamp packages\nthat are not hosted publicly right now.\n\n\n\n### Testing\n\nPlease read these two documents before starting to implement any tests:\n- [Writing tests in redux](http://redux.js.org/docs/recipes/WritingTests.html)\n- [Writing tests for side effects](https://redux-observable.js.org/docs/recipes/WritingTests.html)\n\nTest files are named as `{moduleName}.spec.js`.\n\n#### Run tests\n\n```bash\nnpm test\n```\n\n#### Reducers\n\nSince a reducer is a pure function, it's not that complicated to test it. You\nhave to use a seed to create a mock state. Then you can pass it to the reducer\nas argument along with the action you want to test.\n\n#### Components\n\nUse snapshot testing to make sure components don't change by accident (see\n`src/components/Footer.spec.ts` for an example). Other tests can be done for\ncomponents that have logic inside them.\n\n#### Middleware\n\nTesting middleware is a bit more involved since they have side effects. You can\ntest Epics with the `rxjs-marbles` framework since they transform Observable\nstreams. See `src/autocomplete.spec.ts` for an example.\n\n\n\n### DevOps\n\n#### Formatting with Prettier\n\nWe use [Prettier](https://github.com/prettier/prettier) to keep formatting\nconsistent. This will format your files (JS, TS, CSS, JSON) on a pre-commit\nhook. If you want, you can also call `prettier --write filename` to update a\nfile manually.\n\nThere are also plugins for editors, like\n[`prettier-vscode`](https://marketplace.visualstudio.com/items?itemName=esbenp.prettier-vscode)\nthat can auto-format on save.\n\n#### Code Quality: ESLint, TSLint, Stylelint\n\nI recommend installing plugins for these checkers in your editor. TSLint and\nStylelint are also run in the development command, so you'll see their warnings\npop up there as well.\n\n#### Commit Messages\n\nWe've been using [this commit message\nconvention](https://github.com/kazupon/git-commit-message-convention) because it\nhas emoji and emoji are :thumbsup:.\n\n#### Continuous Integration\n\nDevelopment is primarily done on the [`development`\nbranch](https://github.com/datacamp/datacamp-light/tree/development).\n\nCommits to the `development` branch trigger a build on the DataCamp development\nenvironment and produce a build here:\n\n```\nhttps://cdn.datacamp.com/dcl-react-dev.js.gz\n```\n\nNext, commits to the [`beta` branch](https://github.com/datacamp/datacamp-light/tree/beta)\n push a release to the staging environment:\n\n```\nhttps://cdn.datacamp.com/dcl-react-staging.js.gz\n```\n\nFinally, when we create a release, an update is pushed to the production\nenvironment. This should be a stable version of DataCamp Light:\n\n```\nhttps://cdn.datacamp.com/dcl-react.js.gz\n```\n\nCommits to this\nbranch trigger a build that is deployed on the DataCamp Dev environment. Commits\nto the main branch, `beta`, are built and deployed to staging. When a release is\ncreated, that build is deployed to production.\n\n#### Packages used that you might want to know about\n\n- [TypeScript](https://www.typescriptlang.org/), of course. Make sure you\n  install an appropriate plugin for your editor, if it doesn't ship with one.\n\n- [redux-observable](https://github.com/redux-observable/redux-observable/) for observable middleware\n- [typescript-fsa](https://github.com/aikoven/typescript-fsa) for easy, type-safe action creators\n- [typescript-fsa-reducers](https://github.com/dphilipson/typescript-fsa-reducers) for super-clean reducers\n","funding_links":[],"categories":["TypeScript","Miscellaneous"],"sub_categories":[],"project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fdatacamp%2Fdatacamp-light","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fdatacamp%2Fdatacamp-light","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fdatacamp%2Fdatacamp-light/lists"}