GithubHelp home page GithubHelp logo

ines / course-starter-python Goto Github PK

View Code? Open in Web Editor NEW
503.0 17.0 118.0 1.61 MB

πŸ‘©β€πŸ«πŸ Starter repo for building interactive Python courses

Home Page: https://course-starter-python.netlify.com

License: MIT License

Python 0.88% JavaScript 38.33% CSS 60.78%
python online-course gatsby gatsbyjs jupyter binder

course-starter-python's People

Contributors

arokem avatar hfboyce avatar ines avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

course-starter-python's Issues

Reduce connecting time

Hi ines,

First, I want to say thank you. I really love your template.

Second, there is an issue in juniper and I think it will be better for students if you can solve it.
Currently connecting to mybinder.org take time. I mean "Launching Docker container on mybinder.org..." take from 20sec to 60sec then "Loading..." take about 2sec. This is annoying for students and consume time.
For me, it will be much better if "Launching Docker container on mybinder.org..." start when the student clicks inside "input" space then when students click run "Loading..." start.
So when students trying to solve the exercise, connecting to mybinder.org done then the students when click run button it will take only less than 2sec to execute the code.
Also, this feature exists in most of the online code editors because it saves a lot of time.

Thanks.

Using gitlab doesn't work

Hi @ines

It seems that the juniper settings in meta.json is only valid for GitHub repositories?

Looking in src/components/juniper.js I see that you have

const binderUrl = `${url}/build/gh/${repo}/${branch}`

But when I visit the Binder ui then it seems the url are

https://mybinder.org/v2/gl/nixd%2Fpython-starter-course/binder

instead of

https://mybinder.org/v2/gh/nixd/python-starter-course/binder

I get v2 instead of build, gl instead of gh and %2F instead of / (last can be fixed in ${repo})

EDIT

Seeing your answer in this thread I might just have my juniper in a github repo but itself (if that works - still a bit confused about those links).

ipywidgets functionality?

Hi, thank you for this template.
I've been digging into juniper trying to get it to load ipywidgets the way that thebelab does (ex: https://minrk.github.io/thebelab/widgets.html) but haven't been able to make it work by comparing the two projects javascript dependencies. I can tell there's significant overlap so it's likely just a few steps away...

Is there a path to getting interactive widgets embedded? What files need to get added to? (I can get the python-side properly configured, so the objects are created, but they are not displayed).

Docker compose fails

Hi -- I'm trying to adapt a starter Python course that we wrote a few years ago for use with Binder to the template provided here since it provides a lot of really useful features in terms of self-testing of both code and comprehension.

We already make use of Docker so I was quite excited to think that I'd not have to go anywhere near npm since my previous excursions into the package manager have been... challenging. It might just be my poor understanding of node, but having forked the repository as a template and cloned it to my local machine I'm stuck on this:

 β Ώ Container code-camp-rebooted-gatsby-1  Create...                                        27.1s
Attaching to code-camp-rebooted-gatsby-1
code-camp-rebooted-gatsby-1  | /usr/local/lib/node_modules/gatsby-cli/node_modules/gatsby-telemetry/lib/telemetry.js:39
code-camp-rebooted-gatsby-1  |   store = new _eventStorage.EventStorage();
code-camp-rebooted-gatsby-1  |         ^
code-camp-rebooted-gatsby-1  |
code-camp-rebooted-gatsby-1  | SyntaxError: Unexpected token =
code-camp-rebooted-gatsby-1  |     at Module._compile (internal/modules/cjs/loader.js:723:23)
code-camp-rebooted-gatsby-1  |     at Object.Module._extensions..js (internal/modules/cjs/loader.js:789:10)
code-camp-rebooted-gatsby-1  |     at Module.load (internal/modules/cjs/loader.js:653:32)
code-camp-rebooted-gatsby-1  |     at tryModuleLoad (internal/modules/cjs/loader.js:593:12)
code-camp-rebooted-gatsby-1  |     at Function.Module._load (internal/modules/cjs/loader.js:585:3)
code-camp-rebooted-gatsby-1  |     at Module.require (internal/modules/cjs/loader.js:692:17)
code-camp-rebooted-gatsby-1  |     at require (internal/modules/cjs/helpers.js:25:18)
code-camp-rebooted-gatsby-1  |     at Object.<anonymous> (/usr/local/lib/node_modules/gatsby-cli/node_modules/gatsby-telemetry/lib/index.js:21:18)
code-camp-rebooted-gatsby-1  |     at Module._compile (internal/modules/cjs/loader.js:778:30)
code-camp-rebooted-gatsby-1  |     at Object.Module._extensions..js (internal/modules/cjs/loader.js:789:10)
code-camp-rebooted-gatsby-1 exited with code 1

This is using the repo as cloned on Docker 4.4.2 (Intel Mac running Monterey 12.2.1) with no attempts at modification. Tracing this error via Google led me to this:

With what you provided I'd guess you're running an ancient version of Node:

.nvm/versions/node/v10.24.1
You'll need to use at least Node 14.15.0 with Gatsby

So it looks to me like something (in sharp?) is no longer compatible with what's being installed during docker-compose and hasn't had its version pinned to a compatible one (which seems strange given the sheer overwhelming detail of package-lock.json). Trying to manually install sharp as part of the build process hasn't worked for me. This is almost certainly a function of my lack of knowledge about node. Is there a pre-built image somewhere that I can use, or does that not work because the web site is not actually mounted from the local FS but baked into the build? It doesn't look like that's the case but...

Anyway, since then I've tried this tutorial, this tutorial, and this tutorial. The last one has gotten me closest to a running Docker image but installs someone else's package.json plan with various version locks that are only a bit more recent than this starter course. When I try to bring in the bits that seem to be missing (by comparing against your package.json file) I end up in npm ::hell::.

Is there a process/explanation for installing this stuff from scratch so that I'm not doing cargo cult stuff with npm, package.json, and package-lock.json?

If I can get this building I'd be happy to put a Docker image on the Hub so that a backup process exists as and when the build starts failing...

P.S. Do I also infer that each code cell currently launches its own Binder instance?

Deep links to chapter content

Hi @ines, this is awesome, and we're looking into using this to revamp our intro material for allennlp. One issue that would be great to solve is that the content inside of a chapter is not linkable. E.g., if I want to link directly to the "Loading models" exercise in chapter 1 of your spacy course, I can't do it. Is there an easy way to fix this? I tried looking into a few options myself, but I figured you would know better than me.

Similarly (and I think relatedly, which is why I bring it up here), it'd be great if clicking outside of an exercise collapsed it - I believe one way to solve both of these is to make isExpanded part of the react component's state (and set from the slug), which is reset if you click outside of an exercise, though I'm not familiar enough with react to be confident of doing this right.

Interactive exercises for in-class worksheets - grading for completion

Hey there, thank you for this amazing resource, it looks extremely polished and I'm amazed it's all open-source!

I'd like to use the course-starter pack to build in-class worksheets as I go through my lesson. But the one thing I cannot quite figure out, is how to record student progress. At minimum I'd like to know which of my students complete the worksheet so I could give them completion credit (and more importantly, know who isn't doing it). At the moment the current solution is to use jupyter notebooks and get them to submit it, but I really like the idea of using this tool as a lecture-guide and having everything in one place (slides and worksheets). To be clear, I am not suggesting or asking for this to turn into an LMS. I'm aware what I want may require scripts to pull data from different sources and merge it to get it into a useable form.

tl;dr version: Any advice or suggestions on how to use this to capture student progress/performance? I can simply ask a question about their student number or email at the beginning of each worksheet - but does their progress get logged anywhere?

is there a way to display different MIME types already supported by JupyterLab?

Hi!
I'm using this course-starter template for a project and bumped into this issue:
altair

At first, I figured I could just change the way altair renders it's charts like this:
Screen Shot 2019-04-21 at 8 29 32 AM
changed it to alt.renderers.enable('kaggle')

which does add an altair visualization to the page but it doesn't display.
Screen Shot 2019-04-21 at 8 31 43 AM

Looking at the console I find an error that says "requirejs not defined"


Is there anyway to "import" jupyterlab renderers into the course's website as well? This would allow not just altair visualizations to render but other MIMEtypes as well (i.e. plotly, bokeh, etc).

pd: If this is more of a juniper issue I'm happy to close it here and ask there πŸ‘. Thanks again for open-sourcing such an amazing tool. This is going to make tech instruction a lot more accessible across the globe.

Github Action for building course to Github pages

I made a start on trying to build a Github Action to try to build and push a course to Github Pages, but gatsby is completely new to me so I'm not sure where I'm going wrong, getting a GraphQLError: Cannot query field "allMarkdownRemark" on type "Query". error when I try to run it

# .github/workflows/build_and_publish_course.yml
name: "gatsby publisher"
on:
  push:
    branches:
      - master
jobs:
  builder:
    runs-on: ubuntu-latest
    steps:
    - uses: actions/checkout@v2
    - uses: actions/setup-node@v1
      with:
        node-version: '10.x'
    - run: |
        npm install
        npm install --global gatsby-cli
    - name: Use build branch context
      run: |
        sudo chown -R $(whoami):$(whoami) .
        git config --global user.email "[email protected]"
        git config --global user.name "$GITHUB_ACTOR"
        git checkout -b build
        git merge master
    - name: Build docs HTML
      run: |
        if [ ! -f .path_config_set ]; then
          echo "module.exports = { pathPrefix: \"/${GITHUB_REPOSITORY##*/}\"}" >> gatsby-config.js
          touch .path_config_set
        fi
        
        gatsby build --prefix-paths
        git add --all --force public
        git commit -a -m 'Push build branch'
        git push
    - name: Deploy HTML site to gh-pages
      uses: peaceiris/actions-gh-pages@v3
      with:
        github_token: ${{ secrets.GITHUB_TOKEN }}
        publish_dir: ./public

Math support in reveal.js

I changed the slides component code to have:

math: {
                        mathjax: 'https://cdnjs.cloudflare.com/ajax/libs/mathjax/2.7.5/MathJax.js',
                        config: 'TeX-AMS_HTML-full', // See http://docs.mathjax.org/en/latest/config-files.html
                        // pass other options into `MathJax.Hub.Config()`
                        tex2jax: {
                            inlineMath: [ ['$','$'], ["\\(","\\)"] ],
                            displayMath: [ ['$$','$$'], ["\\[","\\]"] ],
                            balanceBraces: true,
                            processEscapes: false,
                            processRefs: true,
                            processEnvironments: true,
                            preview: 'TeX',
                            skipTags: ['script','noscript','style','textarea','pre','code'],
                            ignoreClass: 'tex2jax_ignore',
                            processClass: 'tex2jax_process'
                        }
                    },
                    dependencies: [
                        { src: 'reveal.js/plugin/math/math.js', async: true }
                    ]

But this did not get me math support. A bit flummozed. (math.js is there in the node_modules, but I wonder where this gatsby app is picking it from..)

Slides on last chapter not working

If I have

next: null

in the header of my chapter file, then there are no content in my slides. I am not a frontend guy but here is some error logging from the console.

react-dom.development.js:21258 Download the React DevTools for a better development experience: https://fb.me/react-devtools
react-hot-loader.development.js:2444 React-Hot-Loader: react-πŸ”₯-dom patch is not detected. React 16.6+ features may not work.
patch @ react-hot-loader.development.js:2444
react-dom.development.js:17411 Download the React DevTools for a better development experience: https://fb.me/react-devtools
react-dom.development.js:17411 Download the React DevTools for a better development experience: https://fb.me/react-devtools
client.js?path=/__webpack_hmr&reload=true&overlay=false:92 [HMR] connected
index.js:11 Uncaught RangeError: Maximum call stack size exceeded
    at Function.[Symbol.hasInstance] (<anonymous>)
    at ./node_modules/deep-equal/index.js.module.exports (index.js:11)
    at objEquiv (index.js:91)
    at ./node_modules/deep-equal/index.js.module.exports (index.js:26)
    at objEquiv (index.js:91)
    at ./node_modules/deep-equal/index.js.module.exports (index.js:26)
    at objEquiv (index.js:91)
    at ./node_modules/deep-equal/index.js.module.exports (index.js:26)
    at objEquiv (index.js:91)
    at ./node_modules/deep-equal/index.js.module.exports (index.js:26)
    at objEquiv (index.js:91)
    at ./node_modules/deep-equal/index.js.module.exports (index.js:26)
    at objEquiv (index.js:91)
    at ./node_modules/deep-equal/index.js.module.exports (index.js:26)
    at objEquiv (index.js:91)
    at ./node_modules/deep-equal/index.js.module.exports (index.js:26)
    at objEquiv (index.js:91)
    at ./node_modules/deep-equal/index.js.module.exports (index.js:26)
    at objEquiv (index.js:91)
    at ./node_modules/deep-equal/index.js.module.exports (index.js:26)
    at objEquiv (index.js:91)
    at ./node_modules/deep-equal/index.js.module.exports (index.js:26)
    at objEquiv (index.js:91)
    at ./node_modules/deep-equal/index.js.module.exports (index.js:26)
    at objEquiv (index.js:91)
    at ./node_modules/deep-equal/index.js.module.exports (index.js:26)
    at objEquiv (index.js:91)
    at ./node_modules/deep-equal/index.js.module.exports (index.js:26)
    at objEquiv (index.js:91)
    at ./node_modules/deep-equal/index.js.module.exports (index.js:26)
    at objEquiv (index.js:91)
    at ./node_modules/deep-equal/index.js.module.exports (index.js:26)
    at objEquiv (index.js:91)
    at ./node_modules/deep-equal/index.js.module.exports (index.js:26)
    at objEquiv (index.js:91)
    at ./node_modules/deep-equal/index.js.module.exports (index.js:26)
    at objEquiv (index.js:91)
    at ./node_modules/deep-equal/index.js.module.exports (index.js:26)
    at objEquiv (index.js:91)
    at ./node_modules/deep-equal/index.js.module.exports (index.js:26)
    at objEquiv (index.js:91)
    at ./node_modules/deep-equal/index.js.module.exports (index.js:26)
    at objEquiv (index.js:91)
    at ./node_modules/deep-equal/index.js.module.exports (index.js:26)
    at objEquiv (index.js:91)
    at ./node_modules/deep-equal/index.js.module.exports (index.js:26)
    at objEquiv (index.js:91)
    at ./node_modules/deep-equal/index.js.module.exports (index.js:26)
    at objEquiv (index.js:91)
    at ./node_modules/deep-equal/index.js.module.exports (index.js:26)
./node_modules/deep-equal/index.js.module.exports @ index.js:11
objEquiv @ index.js:91
./node_modules/deep-equal/index.js.module.exports @ index.js:26
objEquiv @ index.js:91
./node_modules/deep-equal/index.js.module.exports @ index.js:26
objEquiv @ index.js:91
./node_modules/deep-equal/index.js.module.exports @ index.js:26
objEquiv @ index.js:91
./node_modules/deep-equal/index.js.module.exports @ index.js:26
objEquiv @ index.js:91
./node_modules/deep-equal/index.js.module.exports @ index.js:26
objEquiv @ index.js:91
./node_modules/deep-equal/index.js.module.exports @ index.js:26
objEquiv @ index.js:91
./node_modules/deep-equal/index.js.module.exports @ index.js:26
objEquiv @ index.js:91
./node_modules/deep-equal/index.js.module.exports @ index.js:26
objEquiv @ index.js:91
./node_modules/deep-equal/index.js.module.exports @ index.js:26
objEquiv @ index.js:91
./node_modules/deep-equal/index.js.module.exports @ index.js:26
objEquiv @ index.js:91
./node_modules/deep-equal/index.js.module.exports @ index.js:26
objEquiv @ index.js:91
./node_modules/deep-equal/index.js.module.exports @ index.js:26
objEquiv @ index.js:91
./node_modules/deep-equal/index.js.module.exports @ index.js:26
objEquiv @ index.js:91
./node_modules/deep-equal/index.js.module.exports @ index.js:26
objEquiv @ index.js:91
./node_modules/deep-equal/index.js.module.exports @ index.js:26
objEquiv @ index.js:91
./node_modules/deep-equal/index.js.module.exports @ index.js:26
objEquiv @ index.js:91
./node_modules/deep-equal/index.js.module.exports @ index.js:26
objEquiv @ index.js:91
./node_modules/deep-equal/index.js.module.exports @ index.js:26
objEquiv @ index.js:91
./node_modules/deep-equal/index.js.module.exports @ index.js:26
objEquiv @ index.js:91
./node_modules/deep-equal/index.js.module.exports @ index.js:26
objEquiv @ index.js:91
./node_modules/deep-equal/index.js.module.exports @ index.js:26
objEquiv @ index.js:91
./node_modules/deep-equal/index.js.module.exports @ index.js:26
objEquiv @ index.js:91
./node_modules/deep-equal/index.js.module.exports @ index.js:26
objEquiv @ index.js:91
./node_modules/deep-equal/index.js.module.exports @ index.js:26
objEquiv @ index.js:91
./node_modules/deep-equal/index.js.module.exports @ index.js:26
objEquiv @ index.js:91
./node_modules/deep-equal/index.js.module.exports @ index.js:26
objEquiv @ index.js:91
./node_modules/deep-equal/index.js.module.exports @ index.js:26
objEquiv @ index.js:91
./node_modules/deep-equal/index.js.module.exports @ index.js:26
objEquiv @ index.js:91
./node_modules/deep-equal/index.js.module.exports @ index.js:26
objEquiv @ index.js:91
./node_modules/deep-equal/index.js.module.exports @ index.js:26
objEquiv @ index.js:91
./node_modules/deep-equal/index.js.module.exports @ index.js:26
objEquiv @ index.js:91
./node_modules/deep-equal/index.js.module.exports @ index.js:26
objEquiv @ index.js:91
./node_modules/deep-equal/index.js.module.exports @ index.js:26
objEquiv @ index.js:91
./node_modules/deep-equal/index.js.module.exports @ index.js:26
objEquiv @ index.js:91
./node_modules/deep-equal/index.js.module.exports @ index.js:26
objEquiv @ index.js:91
./node_modules/deep-equal/index.js.module.exports @ index.js:26
objEquiv @ index.js:91
./node_modules/deep-equal/index.js.module.exports @ index.js:26
objEquiv @ index.js:91
./node_modules/deep-equal/index.js.module.exports @ index.js:26
objEquiv @ index.js:91
./node_modules/deep-equal/index.js.module.exports @ index.js:26
objEquiv @ index.js:91
./node_modules/deep-equal/index.js.module.exports @ index.js:26
objEquiv @ index.js:91
./node_modules/deep-equal/index.js.module.exports @ index.js:26
objEquiv @ index.js:91
./node_modules/deep-equal/index.js.module.exports @ index.js:26
objEquiv @ index.js:91
./node_modules/deep-equal/index.js.module.exports @ index.js:26
objEquiv @ index.js:91
./node_modules/deep-equal/index.js.module.exports @ index.js:26
objEquiv @ index.js:91
./node_modules/deep-equal/index.js.module.exports @ index.js:26
objEquiv @ index.js:91
./node_modules/deep-equal/index.js.module.exports @ index.js:26
objEquiv @ index.js:91
./node_modules/deep-equal/index.js.module.exports @ index.js:26
objEquiv @ index.js:91
./node_modules/deep-equal/index.js.module.exports @ index.js:26
objEquiv @ index.js:91
./node_modules/deep-equal/index.js.module.exports @ index.js:26
objEquiv @ index.js:91
./node_modules/deep-equal/index.js.module.exports @ index.js:26
objEquiv @ index.js:91
./node_modules/deep-equal/index.js.module.exports @ index.js:26
objEquiv @ index.js:91
./node_modules/deep-equal/index.js.module.exports @ index.js:26
objEquiv @ index.js:91
./node_modules/deep-equal/index.js.module.exports @ index.js:26
objEquiv @ index.js:91
./node_modules/deep-equal/index.js.module.exports @ index.js:26
objEquiv @ index.js:91
./node_modules/deep-equal/index.js.module.exports @ index.js:26
objEquiv @ index.js:91
./node_modules/deep-equal/index.js.module.exports @ index.js:26
objEquiv @ index.js:91
./node_modules/deep-equal/index.js.module.exports @ index.js:26
objEquiv @ index.js:91
./node_modules/deep-equal/index.js.module.exports @ index.js:26
objEquiv @ index.js:91
./node_modules/deep-equal/index.js.module.exports @ index.js:26
objEquiv @ index.js:91
./node_modules/deep-equal/index.js.module.exports @ index.js:26
objEquiv @ index.js:91
./node_modules/deep-equal/index.js.module.exports @ index.js:26
objEquiv @ index.js:91
./node_modules/deep-equal/index.js.module.exports @ index.js:26
objEquiv @ index.js:91
./node_modules/deep-equal/index.js.module.exports @ index.js:26
objEquiv @ index.js:91
./node_modules/deep-equal/index.js.module.exports @ index.js:26
objEquiv @ index.js:91
./node_modules/deep-equal/index.js.module.exports @ index.js:26
objEquiv @ index.js:91
./node_modules/deep-equal/index.js.module.exports @ index.js:26
objEquiv @ index.js:91
./node_modules/deep-equal/index.js.module.exports @ index.js:26
objEquiv @ index.js:91
./node_modules/deep-equal/index.js.module.exports @ index.js:26
objEquiv @ index.js:91
./node_modules/deep-equal/index.js.module.exports @ index.js:26
objEquiv @ index.js:91
./node_modules/deep-equal/index.js.module.exports @ index.js:26
objEquiv @ index.js:91
./node_modules/deep-equal/index.js.module.exports @ index.js:26
objEquiv @ index.js:91
./node_modules/deep-equal/index.js.module.exports @ index.js:26
objEquiv @ index.js:91
./node_modules/deep-equal/index.js.module.exports @ index.js:26
objEquiv @ index.js:91
./node_modules/deep-equal/index.js.module.exports @ index.js:26
objEquiv @ index.js:91
./node_modules/deep-equal/index.js.module.exports @ index.js:26
objEquiv @ index.js:91
./node_modules/deep-equal/index.js.module.exports @ index.js:26
objEquiv @ index.js:91
./node_modules/deep-equal/index.js.module.exports @ index.js:26
objEquiv @ index.js:91
./node_modules/deep-equal/index.js.module.exports @ index.js:26
objEquiv @ index.js:91
./node_modules/deep-equal/index.js.module.exports @ index.js:26
objEquiv @ index.js:91
./node_modules/deep-equal/index.js.module.exports @ index.js:26
objEquiv @ index.js:91
./node_modules/deep-equal/index.js.module.exports @ index.js:26
objEquiv @ index.js:91
./node_modules/deep-equal/index.js.module.exports @ index.js:26
objEquiv @ index.js:91
./node_modules/deep-equal/index.js.module.exports @ index.js:26
objEquiv @ index.js:91
./node_modules/deep-equal/index.js.module.exports @ index.js:26
objEquiv @ index.js:91
./node_modules/deep-equal/index.js.module.exports @ index.js:26
objEquiv @ index.js:91
./node_modules/deep-equal/index.js.module.exports @ index.js:26
objEquiv @ index.js:91
./node_modules/deep-equal/index.js.module.exports @ index.js:26
objEquiv @ index.js:91
./node_modules/deep-equal/index.js.module.exports @ index.js:26
objEquiv @ index.js:91
./node_modules/deep-equal/index.js.module.exports @ index.js:26
objEquiv @ index.js:91
./node_modules/deep-equal/index.js.module.exports @ index.js:26
objEquiv @ index.js:91
./node_modules/deep-equal/index.js.module.exports @ index.js:26
objEquiv @ index.js:91
./node_modules/deep-equal/index.js.module.exports @ index.js:26
objEquiv @ index.js:91
./node_modules/deep-equal/index.js.module.exports @ index.js:26
objEquiv @ index.js:91
./node_modules/deep-equal/index.js.module.exports @ index.js:26
objEquiv @ index.js:91
./node_modules/deep-equal/index.js.module.exports @ index.js:26
objEquiv @ index.js:91
./node_modules/deep-equal/index.js.module.exports @ index.js:26
objEquiv @ index.js:91
./node_modules/deep-equal/index.js.module.exports @ index.js:26
objEquiv @ index.js:91
./node_modules/deep-equal/index.js.module.exports @ index.js:26
objEquiv @ index.js:91
./node_modules/deep-equal/index.js.module.exports @ index.js:26
objEquiv @ index.js:91
Show 170 more frames
index.js:2177 The above error occurred in the <HelmetWrapper> component:
    in HelmetWrapper (created by Context.Consumer)
    in StaticQuery (created by SEO)
    in SEO (created by Context.Consumer)
    in StaticQuery (created by Layout)
    in Layout (created by Template)
    in Template (created by HotExportedTemplate)
    in AppContainer (created by HotExportedTemplate)
    in HotExportedTemplate (created by PageRenderer)
    in PageRenderer (created by JSONStore)
    in JSONStore (created by EnsureResources)
    in ScrollContext (created by EnsureResources)
    in RouteUpdates (created by EnsureResources)
    in EnsureResources (created by RouteHandler)
    in RouteHandler (created by Root)
    in div (created by FocusHandlerImpl)
    in FocusHandlerImpl (created by Context.Consumer)
    in FocusHandler (created by RouterImpl)
    in RouterImpl (created by LocationProvider)
    in LocationProvider (created by Context.Consumer)
    in Location (created by Context.Consumer)
    in Router (created by Root)
    in Root
    in _default

React will try to recreate this component tree from scratch using the error boundary you provided, AppContainer.
__stack_frame_overlay_proxy_console__ @ index.js:2177
logCapturedError @ react-dom.development.js:17117
logError @ react-dom.development.js:17153
callback @ react-dom.development.js:18094
callCallback @ react-dom.development.js:16433
commitUpdateEffects @ react-dom.development.js:16472
commitUpdateQueue @ react-dom.development.js:16463
commitLifeCycles @ react-dom.development.js:17364
commitAllLifeCycles @ react-dom.development.js:18736
callCallback @ react-dom.development.js:149
invokeGuardedCallbackDev @ react-dom.development.js:199
invokeGuardedCallback @ react-dom.development.js:256
commitRoot @ react-dom.development.js:18948
(anonymous) @ react-dom.development.js:20418
unstable_runWithPriority @ scheduler.development.js:255
completeRoot @ react-dom.development.js:20417
performWorkOnRoot @ react-dom.development.js:20346
performWork @ react-dom.development.js:20254
performSyncWork @ react-dom.development.js:20228
interactiveUpdates$1 @ react-dom.development.js:20495
interactiveUpdates @ react-dom.development.js:2170
dispatchInteractiveEvent @ react-dom.development.js:4882
index.js:2177 RangeError: Maximum call stack size exceeded
    at Function.[Symbol.hasInstance] (<anonymous>)
    at ./node_modules/deep-equal/index.js.module.exports (index.js:11)
    at objEquiv (index.js:91)
    at ./node_modules/deep-equal/index.js.module.exports (index.js:26)
    at objEquiv (index.js:91)
    at ./node_modules/deep-equal/index.js.module.exports (index.js:26)
    at objEquiv (index.js:91)
    at ./node_modules/deep-equal/index.js.module.exports (index.js:26)
    at objEquiv (index.js:91)
    at ./node_modules/deep-equal/index.js.module.exports (index.js:26)
    at objEquiv (index.js:91)
    at ./node_modules/deep-equal/index.js.module.exports (index.js:26)
    at objEquiv (index.js:91)
    at ./node_modules/deep-equal/index.js.module.exports (index.js:26)
    at objEquiv (index.js:91)
    at ./node_modules/deep-equal/index.js.module.exports (index.js:26)
    at objEquiv (index.js:91)
    at ./node_modules/deep-equal/index.js.module.exports (index.js:26)
    at objEquiv (index.js:91)
    at ./node_modules/deep-equal/index.js.module.exports (index.js:26)
    at objEquiv (index.js:91)
    at ./node_modules/deep-equal/index.js.module.exports (index.js:26)
    at objEquiv (index.js:91)
    at ./node_modules/deep-equal/index.js.module.exports (index.js:26)
    at objEquiv (index.js:91)
    at ./node_modules/deep-equal/index.js.module.exports (index.js:26)
    at objEquiv (index.js:91)
    at ./node_modules/deep-equal/index.js.module.exports (index.js:26)
    at objEquiv (index.js:91)
    at ./node_modules/deep-equal/index.js.module.exports (index.js:26)
    at objEquiv (index.js:91)
    at ./node_modules/deep-equal/index.js.module.exports (index.js:26)
    at objEquiv (index.js:91)
    at ./node_modules/deep-equal/index.js.module.exports (index.js:26)
    at objEquiv (index.js:91)
    at ./node_modules/deep-equal/index.js.module.exports (index.js:26)
    at objEquiv (index.js:91)
    at ./node_modules/deep-equal/index.js.module.exports (index.js:26)
    at objEquiv (index.js:91)
    at ./node_modules/deep-equal/index.js.module.exports (index.js:26)
    at objEquiv (index.js:91)
    at ./node_modules/deep-equal/index.js.module.exports (index.js:26)
    at objEquiv (index.js:91)
    at ./node_modules/deep-equal/index.js.module.exports (index.js:26)
    at objEquiv (index.js:91)
    at ./node_modules/deep-equal/index.js.module.exports (index.js:26)
    at objEquiv (index.js:91)
    at ./node_modules/deep-equal/index.js.module.exports (index.js:26)
    at objEquiv (index.js:91)
    at ./node_modules/deep-equal/index.js.module.exports (index.js:26)
__stack_frame_overlay_proxy_console__ @ index.js:2177
error @ react-hot-loader.development.js:232
componentDidCatch @ react-hot-loader.development.js:2139
callback @ react-dom.development.js:18095
callCallback @ react-dom.development.js:16433
commitUpdateEffects @ react-dom.development.js:16472
commitUpdateQueue @ react-dom.development.js:16463
commitLifeCycles @ react-dom.development.js:17364
commitAllLifeCycles @ react-dom.development.js:18736
callCallback @ react-dom.development.js:149
invokeGuardedCallbackDev @ react-dom.development.js:199
invokeGuardedCallback @ react-dom.development.js:256
commitRoot @ react-dom.development.js:18948
(anonymous) @ react-dom.development.js:20418
unstable_runWithPriority @ scheduler.development.js:255
completeRoot @ react-dom.development.js:20417
performWorkOnRoot @ react-dom.development.js:20346
performWork @ react-dom.development.js:20254
performSyncWork @ react-dom.development.js:20228
interactiveUpdates$1 @ react-dom.development.js:20495
interactiveUpdates @ react-dom.development.js:2170
dispatchInteractiveEvent @ react-dom.development.js:4882
react-hot-loader.development.js:2146 Uncaught RangeError: Maximum call stack size exceeded
    at Function.[Symbol.hasInstance] (<anonymous>)
    at ./node_modules/deep-equal/index.js.module.exports (index.js:11)
    at objEquiv (index.js:91)
    at ./node_modules/deep-equal/index.js.module.exports (index.js:26)
    at objEquiv (index.js:91)
    at ./node_modules/deep-equal/index.js.module.exports (index.js:26)
    at objEquiv (index.js:91)
    at ./node_modules/deep-equal/index.js.module.exports (index.js:26)
    at objEquiv (index.js:91)
    at ./node_modules/deep-equal/index.js.module.exports (index.js:26)
    at objEquiv (index.js:91)
    at ./node_modules/deep-equal/index.js.module.exports (index.js:26)
    at objEquiv (index.js:91)
    at ./node_modules/deep-equal/index.js.module.exports (index.js:26)
    at objEquiv (index.js:91)
    at ./node_modules/deep-equal/index.js.module.exports (index.js:26)
    at objEquiv (index.js:91)
    at ./node_modules/deep-equal/index.js.module.exports (index.js:26)
    at objEquiv (index.js:91)
    at ./node_modules/deep-equal/index.js.module.exports (index.js:26)
    at objEquiv (index.js:91)
    at ./node_modules/deep-equal/index.js.module.exports (index.js:26)
    at objEquiv (index.js:91)
    at ./node_modules/deep-equal/index.js.module.exports (index.js:26)
    at objEquiv (index.js:91)
    at ./node_modules/deep-equal/index.js.module.exports (index.js:26)
    at objEquiv (index.js:91)
    at ./node_modules/deep-equal/index.js.module.exports (index.js:26)
    at objEquiv (index.js:91)
    at ./node_modules/deep-equal/index.js.module.exports (index.js:26)
    at objEquiv (index.js:91)
    at ./node_modules/deep-equal/index.js.module.exports (index.js:26)
    at objEquiv (index.js:91)
    at ./node_modules/deep-equal/index.js.module.exports (index.js:26)
    at objEquiv (index.js:91)
    at ./node_modules/deep-equal/index.js.module.exports (index.js:26)
    at objEquiv (index.js:91)
    at ./node_modules/deep-equal/index.js.module.exports (index.js:26)
    at objEquiv (index.js:91)
    at ./node_modules/deep-equal/index.js.module.exports (index.js:26)
    at objEquiv (index.js:91)
    at ./node_modules/deep-equal/index.js.module.exports (index.js:26)
    at objEquiv (index.js:91)
    at ./node_modules/deep-equal/index.js.module.exports (index.js:26)
    at objEquiv (index.js:91)
    at ./node_modules/deep-equal/index.js.module.exports (index.js:26)
    at objEquiv (index.js:91)
    at ./node_modules/deep-equal/index.js.module.exports (index.js:26)
    at objEquiv (index.js:91)
    at ./node_modules/deep-equal/index.js.module.exports (index.js:26)
componentDidCatch @ react-hot-loader.development.js:2146
callback @ react-dom.development.js:18095
callCallback @ react-dom.development.js:16433
commitUpdateEffects @ react-dom.development.js:16472
commitUpdateQueue @ react-dom.development.js:16463
commitLifeCycles @ react-dom.development.js:17364
commitAllLifeCycles @ react-dom.development.js:18736
callCallback @ react-dom.development.js:149
invokeGuardedCallbackDev @ react-dom.development.js:199
invokeGuardedCallback @ react-dom.development.js:256
commitRoot @ react-dom.development.js:18948
(anonymous) @ react-dom.development.js:20418
unstable_runWithPriority @ scheduler.development.js:255
completeRoot @ react-dom.development.js:20417
performWorkOnRoot @ react-dom.development.js:20346
performWork @ react-dom.development.js:20254
performSyncWork @ react-dom.development.js:20228
interactiveUpdates$1 @ react-dom.development.js:20495
interactiveUpdates @ react-dom.development.js:2170
dispatchInteractiveEvent @ react-dom.development.js:4882
index.js:2177 The above error occurred in the <AppContainer> component:
    in AppContainer (created by HotExportedTemplate)
    in HotExportedTemplate (created by PageRenderer)
    in PageRenderer (created by JSONStore)
    in JSONStore (created by EnsureResources)
    in ScrollContext (created by EnsureResources)
    in RouteUpdates (created by EnsureResources)
    in EnsureResources (created by RouteHandler)
    in RouteHandler (created by Root)
    in div (created by FocusHandlerImpl)
    in FocusHandlerImpl (created by Context.Consumer)
    in FocusHandler (created by RouterImpl)
    in RouterImpl (created by LocationProvider)
    in LocationProvider (created by Context.Consumer)
    in Location (created by Context.Consumer)
    in Router (created by Root)
    in Root
    in _default

React will try to recreate this component tree from scratch using the error boundary you provided, LocationProvider.
__stack_frame_overlay_proxy_console__ @ index.js:2177
logCapturedError @ react-dom.development.js:17117
logError @ react-dom.development.js:17153
callback @ react-dom.development.js:18094
callCallback @ react-dom.development.js:16433
commitUpdateEffects @ react-dom.development.js:16472
commitUpdateQueue @ react-dom.development.js:16460
commitLifeCycles @ react-dom.development.js:17364
commitAllLifeCycles @ react-dom.development.js:18736
callCallback @ react-dom.development.js:149
invokeGuardedCallbackDev @ react-dom.development.js:199
invokeGuardedCallback @ react-dom.development.js:256
commitRoot @ react-dom.development.js:18948
(anonymous) @ react-dom.development.js:20418
unstable_runWithPriority @ scheduler.development.js:255
completeRoot @ react-dom.development.js:20417
performWorkOnRoot @ react-dom.development.js:20346
performWork @ react-dom.development.js:20254
performSyncWork @ react-dom.development.js:20228
interactiveUpdates$1 @ react-dom.development.js:20495
interactiveUpdates @ react-dom.development.js:2170
dispatchInteractiveEvent @ react-dom.development.js:4882
index.js:83 Uncaught RangeError: Maximum call stack size exceeded
    at Function.[Symbol.hasInstance] (<anonymous>)
    at ./node_modules/deep-equal/index.js.module.exports (index.js:11)
    at objEquiv (index.js:91)
    at ./node_modules/deep-equal/index.js.module.exports (index.js:26)
    at objEquiv (index.js:91)
    at ./node_modules/deep-equal/index.js.module.exports (index.js:26)
    at objEquiv (index.js:91)
    at ./node_modules/deep-equal/index.js.module.exports (index.js:26)
    at objEquiv (index.js:91)
    at ./node_modules/deep-equal/index.js.module.exports (index.js:26)
    at objEquiv (index.js:91)
    at ./node_modules/deep-equal/index.js.module.exports (index.js:26)
    at objEquiv (index.js:91)
    at ./node_modules/deep-equal/index.js.module.exports (index.js:26)
    at objEquiv (index.js:91)
    at ./node_modules/deep-equal/index.js.module.exports (index.js:26)
    at objEquiv (index.js:91)
    at ./node_modules/deep-equal/index.js.module.exports (index.js:26)
    at objEquiv (index.js:91)
    at ./node_modules/deep-equal/index.js.module.exports (index.js:26)
    at objEquiv (index.js:91)
    at ./node_modules/deep-equal/index.js.module.exports (index.js:26)
    at objEquiv (index.js:91)
    at ./node_modules/deep-equal/index.js.module.exports (index.js:26)
    at objEquiv (index.js:91)
    at ./node_modules/deep-equal/index.js.module.exports (index.js:26)
    at objEquiv (index.js:91)
    at ./node_modules/deep-equal/index.js.module.exports (index.js:26)
    at objEquiv (index.js:91)
    at ./node_modules/deep-equal/index.js.module.exports (index.js:26)
    at objEquiv (index.js:91)
    at ./node_modules/deep-equal/index.js.module.exports (index.js:26)
    at objEquiv (index.js:91)
    at ./node_modules/deep-equal/index.js.module.exports (index.js:26)
    at objEquiv (index.js:91)
    at ./node_modules/deep-equal/index.js.module.exports (index.js:26)
    at objEquiv (index.js:91)
    at ./node_modules/deep-equal/index.js.module.exports (index.js:26)
    at objEquiv (index.js:91)
    at ./node_modules/deep-equal/index.js.module.exports (index.js:26)
    at objEquiv (index.js:91)
    at ./node_modules/deep-equal/index.js.module.exports (index.js:26)
    at objEquiv (index.js:91)
    at ./node_modules/deep-equal/index.js.module.exports (index.js:26)
    at objEquiv (index.js:91)
    at ./node_modules/deep-equal/index.js.module.exports (index.js:26)
    at objEquiv (index.js:91)
    at ./node_modules/deep-equal/index.js.module.exports (index.js:26)
    at objEquiv (index.js:91)
    at ./node_modules/deep-equal/index.js.module.exports (index.js:26)
componentDidCatch @ index.js:83
callback @ react-dom.development.js:18095
callCallback @ react-dom.development.js:16433
commitUpdateEffects @ react-dom.development.js:16472
commitUpdateQueue @ react-dom.development.js:16460
commitLifeCycles @ react-dom.development.js:17364
commitAllLifeCycles @ react-dom.development.js:18736
callCallback @ react-dom.development.js:149
invokeGuardedCallbackDev @ react-dom.development.js:199
invokeGuardedCallback @ react-dom.development.js:256
commitRoot @ react-dom.development.js:18948
(anonymous) @ react-dom.development.js:20418
unstable_runWithPriority @ scheduler.development.js:255
completeRoot @ react-dom.development.js:20417
performWorkOnRoot @ react-dom.development.js:20346
performWork @ react-dom.development.js:20254
performSyncWork @ react-dom.development.js:20228
interactiveUpdates$1 @ react-dom.development.js:20495
interactiveUpdates @ react-dom.development.js:2170
dispatchInteractiveEvent @ react-dom.development.js:4882
index.js:2177 The above error occurred in the <LocationProvider> component:
    in LocationProvider (created by Context.Consumer)
    in Location (created by Context.Consumer)
    in Router (created by Root)
    in Root
    in _default

Consider adding an error boundary to your tree to customize error handling behavior.
Visit https://fb.me/react-error-boundaries to learn more about error boundaries.
__stack_frame_overlay_proxy_console__ @ index.js:2177
logCapturedError @ react-dom.development.js:17117
logError @ react-dom.development.js:17153
update.callback @ react-dom.development.js:18065
callCallback @ react-dom.development.js:16433
commitUpdateEffects @ react-dom.development.js:16472
commitUpdateQueue @ react-dom.development.js:16460
commitLifeCycles @ react-dom.development.js:17383
commitAllLifeCycles @ react-dom.development.js:18736
callCallback @ react-dom.development.js:149
invokeGuardedCallbackDev @ react-dom.development.js:199
invokeGuardedCallback @ react-dom.development.js:256
commitRoot @ react-dom.development.js:18948
(anonymous) @ react-dom.development.js:20418
unstable_runWithPriority @ scheduler.development.js:255
completeRoot @ react-dom.development.js:20417
performWorkOnRoot @ react-dom.development.js:20346
performWork @ react-dom.development.js:20254
performSyncWork @ react-dom.development.js:20228
interactiveUpdates$1 @ react-dom.development.js:20495
interactiveUpdates @ react-dom.development.js:2170
dispatchInteractiveEvent @ react-dom.development.js:4882
react-dom.development.js:20312 Uncaught RangeError: Maximum call stack size exceeded
    at Function.[Symbol.hasInstance] (<anonymous>)
    at ./node_modules/deep-equal/index.js.module.exports (index.js:11)
    at objEquiv (index.js:91)
    at ./node_modules/deep-equal/index.js.module.exports (index.js:26)
    at objEquiv (index.js:91)
    at ./node_modules/deep-equal/index.js.module.exports (index.js:26)
    at objEquiv (index.js:91)
    at ./node_modules/deep-equal/index.js.module.exports (index.js:26)
    at objEquiv (index.js:91)
    at ./node_modules/deep-equal/index.js.module.exports (index.js:26)
    at objEquiv (index.js:91)
    at ./node_modules/deep-equal/index.js.module.exports (index.js:26)
    at objEquiv (index.js:91)
    at ./node_modules/deep-equal/index.js.module.exports (index.js:26)
    at objEquiv (index.js:91)
    at ./node_modules/deep-equal/index.js.module.exports (index.js:26)
    at objEquiv (index.js:91)
    at ./node_modules/deep-equal/index.js.module.exports (index.js:26)
    at objEquiv (index.js:91)
    at ./node_modules/deep-equal/index.js.module.exports (index.js:26)
    at objEquiv (index.js:91)
    at ./node_modules/deep-equal/index.js.module.exports (index.js:26)
    at objEquiv (index.js:91)
    at ./node_modules/deep-equal/index.js.module.exports (index.js:26)
    at objEquiv (index.js:91)
    at ./node_modules/deep-equal/index.js.module.exports (index.js:26)
    at objEquiv (index.js:91)
    at ./node_modules/deep-equal/index.js.module.exports (index.js:26)
    at objEquiv (index.js:91)
    at ./node_modules/deep-equal/index.js.module.exports (index.js:26)
    at objEquiv (index.js:91)
    at ./node_modules/deep-equal/index.js.module.exports (index.js:26)
    at objEquiv (index.js:91)
    at ./node_modules/deep-equal/index.js.module.exports (index.js:26)
    at objEquiv (index.js:91)
    at ./node_modules/deep-equal/index.js.module.exports (index.js:26)
    at objEquiv (index.js:91)
    at ./node_modules/deep-equal/index.js.module.exports (index.js:26)
    at objEquiv (index.js:91)
    at ./node_modules/deep-equal/index.js.module.exports (index.js:26)
    at objEquiv (index.js:91)
    at ./node_modules/deep-equal/index.js.module.exports (index.js:26)
    at objEquiv (index.js:91)
    at ./node_modules/deep-equal/index.js.module.exports (index.js:26)
    at objEquiv (index.js:91)
    at ./node_modules/deep-equal/index.js.module.exports (index.js:26)
    at objEquiv (index.js:91)
    at ./node_modules/deep-equal/index.js.module.exports (index.js:26)
    at objEquiv (index.js:91)
    at ./node_modules/deep-equal/index.js.module.exports (index.js:26)
finishRendering @ react-dom.development.js:20312
performWork @ react-dom.development.js:20273
performSyncWork @ react-dom.development.js:20228
interactiveUpdates$1 @ react-dom.development.js:20495
interactiveUpdates @ react-dom.development.js:2170
dispatchInteractiveEvent @ react-dom.development.js:4882

Syntax highlighting in code blocks in slides

Suggestion: Would it be possible to add syntax highlighting in code blocks in the slides? Syntax highlighting exists for exercises, but for slides with a lot of code, it would help the reader to have syntax colored the same way. Currently, code in the slides is colored uniformly as var(--syntax-text) in slides.module.sass.

Thank you! This is an awesome starter package.

Course deploy on netlify failed (Error running command: Build script returned non-zero exit code: 1)

I am trying to deploy my course on netlify using yor template (without any change) and I am getting build failed error:

3:32:57 PM: Installing NPM modules using NPM version 6.14.4
3:33:36 PM: > sharp@0.21.3 install /opt/build/repo/node_modules/sharp
3:33:36 PM: > (node install/libvips && node install/dll-copy && prebuild-install) || (node-gyp rebuild && node install/dll-copy)
3:33:36 PM: info sharp Downloading https://github.com/lovell/sharp-libvips/releases/download/v8.7.0/libvips-8.7.0-linux-x64.tar.gz
3:33:38 PM: prebuild-install WARN install No prebuilt binaries found (target=12.18.0 runtime=node arch=x64 libc= platform=linux)
3:33:40 PM: make: Entering directory '/opt/build/repo/node_modules/sharp/build'
3:33:40 PM:   TOUCH Release/obj.target/libvips-cpp.stamp
3:33:40 PM:   CXX(target) Release/obj.target/sharp/src/common.o
3:33:41 PM: In file included from ../src/common.cc:27:0:
3:33:41 PM: ../src/common.h:78:16: error: β€˜Handle’ is not a member of β€˜v8’
3:33:41 PM:    bool HasAttr(v8::Handle<v8::Object> obj, std::string attr);
3:33:41 PM:                 ^
3:33:41 PM: ../src/common.h:78:37: error: expected primary-expression before β€˜>’ token
3:33:41 PM:    bool HasAttr(v8::Handle<v8::Object> obj, std::string attr);
3:33:41 PM:                                      ^
3:33:41 PM: ../src/common.h:78:39: error: β€˜obj’ was not declared in this scope
3:33:41 PM:    bool HasAttr(v8::Handle<v8::Object> obj, std::string attr);
3:33:41 PM:                                        ^
3:33:41 PM: ../src/common.h:78:56: error: expected primary-expression before β€˜attr’
3:33:41 PM:    bool HasAttr(v8::Handle<v8::Object> obj, std::string attr);
3:33:41 PM:                                                         ^
3:33:41 PM: ../src/common.h:78:60: error: expression list treated as compound expression in initializer [-fpermissive]
3:33:41 PM:    bool HasAttr(v8::Handle<v8::Object> obj, std::string attr);
3:33:41 PM:                                                             ^
3:33:41 PM: ../src/common.h:79:25: error: β€˜Handle’ is not a member of β€˜v8’
3:33:41 PM:    std::string AttrAsStr(v8::Handle<v8::Object> obj, std::string attr);
3:33:41 PM:                          ^
3:33:41 PM: ../src/common.h:79:46: error: expected primary-expression before β€˜>’ token
3:33:41 PM:    std::string AttrAsStr(v8::Handle<v8::Object> obj, std::string attr);
3:33:41 PM:                                               ^
3:33:41 PM: ../src/common.h:79:48: error: β€˜obj’ was not declared in this scope
3:33:41 PM:    std::string AttrAsStr(v8::Handle<v8::Object> obj, std::string attr);
3:33:41 PM:                                                 ^
3:33:41 PM: ../src/common.h:79:65: error: expected primary-expression before β€˜attr’
3:33:41 PM:    std::string AttrAsStr(v8::Handle<v8::Object> obj, std::string attr);
3:33:41 PM:                                                                  ^
3:33:41 PM: ../src/common.h:80:34: error: β€˜Handle’ is not a member of β€˜v8’
3:33:41 PM:    std::vector<double> AttrAsRgba(v8::Handle<v8::Object> obj, std::string attr);
3:33:41 PM:                                   ^
3:33:41 PM: ../src/common.h:80:55: error: expected primary-expression before β€˜>’ token
3:33:41 PM:    std::vector<double> AttrAsRgba(v8::Handle<v8::Object> obj, std::string attr);
3:33:41 PM:                                                        ^
3:33:41 PM: ../src/common.h:80:57: error: β€˜obj’ was not declared in this scope
3:33:41 PM:    std::vector<double> AttrAsRgba(v8::Handle<v8::Object> obj, std::string attr);
3:33:41 PM:                                                          ^
3:33:41 PM: ../src/common.h:80:74: error: expected primary-expression before β€˜attr’
3:33:41 PM:    std::vector<double> AttrAsRgba(v8::Handle<v8::Object> obj, std::string attr);
3:33:41 PM:                                                                           ^
3:33:41 PM: ../src/common.h:81:44: error: β€˜Handle’ is not a member of β€˜v8’
3:33:41 PM:    template<typename T> v8::Local<T> AttrAs(v8::Handle<v8::Object> obj, std::string attr) {
3:33:41 PM:                                             ^
3:33:41 PM: ../src/common.h:81:65: error: expected primary-expression before β€˜>’ token
3:33:41 PM:    template<typename T> v8::Local<T> AttrAs(v8::Handle<v8::Object> obj, std::string attr) {
3:33:41 PM:                                                                  ^
3:33:41 PM: ../src/common.h:81:67: error: β€˜obj’ was not declared in this scope
3:33:41 PM:    template<typename T> v8::Local<T> AttrAs(v8::Handle<v8::Object> obj, std::string attr) {
3:33:41 PM:                                                                    ^
3:33:41 PM: ../src/common.h:81:84: error: expected primary-expression before β€˜attr’
3:33:41 PM:    template<typename T> v8::Local<T> AttrAs(v8::Handle<v8::Object> obj, std::string attr) {
3:33:41 PM:                                                                                     ^
3:33:41 PM: ../src/common.h:81:37: warning: variable templates only available with -std=c++14 or -std=gnu++14
3:33:41 PM:    template<typename T> v8::Local<T> AttrAs(v8::Handle<v8::Object> obj, std::string attr) {
3:33:41 PM:                                      ^
3:33:41 PM: ../src/common.h:81:90: error: expected β€˜;’ before β€˜{’ token
3:33:41 PM:    template<typename T> v8::Local<T> AttrAs(v8::Handle<v8::Object> obj, std::string attr) {
3:33:41 PM:                                                                                           ^
3:33:41 PM: ../src/common.h:84:33: error: β€˜Handle’ is not a member of β€˜v8’
3:33:41 PM:    template<typename T> T AttrTo(v8::Handle<v8::Object> obj, std::string attr) {
3:33:41 PM:                                  ^
3:33:41 PM: ../src/common.h:84:54: error: expected primary-expression before β€˜>’ token
3:33:41 PM:    template<typename T> T AttrTo(v8::Handle<v8::Object> obj, std::string attr) {
3:33:41 PM:                                                       ^
3:33:41 PM: ../src/common.h:84:56: error: β€˜obj’ was not declared in this scope
3:33:41 PM:    template<typename T> T AttrTo(v8::Handle<v8::Object> obj, std::string attr) {
3:33:41 PM:                                                         ^
3:33:41 PM: ../src/common.h:84:73: error: expected primary-expression before β€˜attr’
3:33:41 PM:    template<typename T> T AttrTo(v8::Handle<v8::Object> obj, std::string attr) {
3:33:41 PM:                                                                          ^
3:33:41 PM: ../src/common.h:84:26: warning: variable templates only available with -std=c++14 or -std=gnu++14
3:33:41 PM:    template<typename T> T AttrTo(v8::Handle<v8::Object> obj, std::string attr) {
3:33:41 PM:                           ^
3:33:41 PM: ../src/common.h:84:79: error: expected β€˜;’ before β€˜{’ token
3:33:41 PM:    template<typename T> T AttrTo(v8::Handle<v8::Object> obj, std::string attr) {
3:33:41 PM:                                                                                ^
3:33:41 PM: ../src/common.h:87:33: error: β€˜Handle’ is not a member of β€˜v8’
3:33:41 PM:    template<typename T> T AttrTo(v8::Handle<v8::Object> obj, int attr) {
3:33:41 PM:                                  ^
3:33:41 PM: ../src/common.h:87:54: error: expected primary-expression before β€˜>’ token
3:33:41 PM:    template<typename T> T AttrTo(v8::Handle<v8::Object> obj, int attr) {
3:33:41 PM:                                                       ^
3:33:41 PM: ../src/common.h:87:56: error: β€˜obj’ was not declared in this scope
3:33:41 PM:    template<typename T> T AttrTo(v8::Handle<v8::Object> obj, int attr) {
3:33:41 PM:                                                         ^
3:33:41 PM: ../src/common.h:87:61: error: expected primary-expression before β€˜int’
3:33:41 PM:    template<typename T> T AttrTo(v8::Handle<v8::Object> obj, int attr) {
3:33:41 PM:                                                              ^
3:33:41 PM: ../src/common.h:84:26: warning: variable templates only available with -std=c++14 or -std=gnu++14
3:33:41 PM:    template<typename T> T AttrTo(v8::Handle<v8::Object> obj, std::string attr) {
3:33:41 PM:                           ^
3:33:41 PM: ../src/common.h:87:71: error: expected β€˜;’ before β€˜{’ token
3:33:41 PM:    template<typename T> T AttrTo(v8::Handle<v8::Object> obj, int attr) {
3:33:41 PM:                                                                        ^
3:33:41 PM: ../src/common.h:93:5: error: β€˜Handle’ is not a member of β€˜v8’
3:33:41 PM:      v8::Handle<v8::Object> input, std::vector<v8::Local<v8::Object>> &buffersToPersist);
3:33:41 PM:      ^
3:33:41 PM: ../src/common.h:93:26: error: expected primary-expression before β€˜>’ token
3:33:41 PM:      v8::Handle<v8::Object> input, std::vector<v8::Local<v8::Object>> &buffersToPersist);
3:33:41 PM:                           ^
3:33:41 PM: ../src/common.h:93:28: error: β€˜input’ was not declared in this scope
3:33:41 PM:      v8::Handle<v8::Object> input, std::vector<v8::Local<v8::Object>> &buffersToPersist);
3:33:41 PM:                             ^
3:33:41 PM: ../src/common.h:93:70: error: expected primary-expression before β€˜&’ token
3:33:41 PM:      v8::Handle<v8::Object> input, std::vector<v8::Local<v8::Object>> &buffersToPersist);
3:33:41 PM:                                                                       ^
3:33:41 PM: ../src/common.h:93:71: error: β€˜buffersToPersist’ was not declared in this scope
3:33:41 PM:      v8::Handle<v8::Object> input, std::vector<v8::Local<v8::Object>> &buffersToPersist);
3:33:41 PM:                                                                        ^
3:33:41 PM: ../src/common.h:93:87: error: expression list treated as compound expression in initializer [-fpermissive]
3:33:41 PM:      v8::Handle<v8::Object> input, std::vector<v8::Local<v8::Object>> &buffersToPersist);
3:33:41 PM:                                                                                        ^
3:33:41 PM: ../src/common.cc:34:20: error: redefinition of β€˜bool sharp::HasAttr’
3:33:41 PM:    bool HasAttr(v8::Handle<v8::Object> obj, std::string attr) {
3:33:41 PM:                     ^
3:33:41 PM: In file included from ../src/common.cc:27:0:
3:33:41 PM: ../src/common.h:78:8: note: β€˜bool sharp::HasAttr’ previously defined here
3:33:41 PM:    bool HasAttr(v8::Handle<v8::Object> obj, std::string attr);
3:33:41 PM:         ^
3:33:41 PM: ../src/common.cc:34:16: error: β€˜Handle’ is not a member of β€˜v8’
3:33:41 PM:    bool HasAttr(v8::Handle<v8::Object> obj, std::string attr) {
3:33:41 PM:                 ^
3:33:41 PM: ../src/common.cc:34:37: error: expected primary-expression before β€˜>’ token
3:33:41 PM:    bool HasAttr(v8::Handle<v8::Object> obj, std::string attr) {
3:33:41 PM:                                      ^
3:33:41 PM: ../src/common.cc:34:39: error: β€˜obj’ was not declared in this scope
3:33:41 PM:    bool HasAttr(v8::Handle<v8::Object> obj, std::string attr) {
3:33:41 PM:                                        ^
3:33:41 PM: ../src/common.cc:34:56: error: expected primary-expression before β€˜attr’
3:33:41 PM:    bool HasAttr(v8::Handle<v8::Object> obj, std::string attr) {
3:33:41 PM:                                                         ^
3:33:41 PM: ../src/common.cc:37:29: error: redefinition of β€˜std::string sharp::AttrAsStr’
3:33:41 PM:    std::string AttrAsStr(v8::Handle<v8::Object> obj, std::string attr) {
3:33:41 PM:                              ^
3:33:41 PM: In file included from ../src/common.cc:27:0:
3:33:41 PM: ../src/common.h:79:15: note: β€˜std::string sharp::AttrAsStr’ previously declared here
3:33:41 PM:    std::string AttrAsStr(v8::Handle<v8::Object> obj, std::string attr);
3:33:41 PM:                ^
3:33:41 PM: ../src/common.cc:37:25: error: β€˜Handle’ is not a member of β€˜v8’
3:33:41 PM:    std::string AttrAsStr(v8::Handle<v8::Object> obj, std::string attr) {
3:33:41 PM:                          ^
3:33:41 PM: ../src/common.cc:37:46: error: expected primary-expression before β€˜>’ token
3:33:41 PM:    std::string AttrAsStr(v8::Handle<v8::Object> obj, std::string attr) {
3:33:41 PM:                                               ^
3:33:41 PM: ../src/common.cc:37:48: error: β€˜obj’ was not declared in this scope
3:33:41 PM:    std::string AttrAsStr(v8::Handle<v8::Object> obj, std::string attr) {
3:33:41 PM:                                                 ^
3:33:41 PM: ../src/common.cc:37:65: error: expected primary-expression before β€˜attr’
3:33:41 PM:    std::string AttrAsStr(v8::Handle<v8::Object> obj, std::string attr) {
3:33:41 PM:                                                                  ^
3:33:41 PM: ../src/common.cc:40:38: error: redefinition of β€˜std::vector<double> sharp::AttrAsRgba’
3:33:41 PM:    std::vector<double> AttrAsRgba(v8::Handle<v8::Object> obj, std::string attr) {
3:33:41 PM:                                       ^
3:33:41 PM: In file included from ../src/common.cc:27:0:
3:33:41 PM: ../src/common.h:80:23: note: β€˜std::vector<double> sharp::AttrAsRgba’ previously declared here
3:33:41 PM:    std::vector<double> AttrAsRgba(v8::Handle<v8::Object> obj, std::string attr);
3:33:41 PM:                        ^
3:33:41 PM: ../src/common.cc:40:34: error: β€˜Handle’ is not a member of β€˜v8’
3:33:41 PM:    std::vector<double> AttrAsRgba(v8::Handle<v8::Object> obj, std::string attr) {
3:33:41 PM:                                   ^
3:33:41 PM: ../src/common.cc:40:55: error: expected primary-expression before β€˜>’ token
3:33:41 PM:    std::vector<double> AttrAsRgba(v8::Handle<v8::Object> obj, std::string attr) {
3:33:41 PM:                                                        ^
3:33:41 PM: ../src/common.cc:40:57: error: β€˜obj’ was not declared in this scope
3:33:41 PM:    std::vector<double> AttrAsRgba(v8::Handle<v8::Object> obj, std::string attr) {
3:33:41 PM:                                                          ^
3:33:41 PM: ../src/common.cc:40:74: error: expected primary-expression before β€˜attr’
3:33:41 PM:    std::vector<double> AttrAsRgba(v8::Handle<v8::Object> obj, std::string attr) {
3:33:41 PM:                                                                           ^
3:33:41 PM: ../src/common.cc:654:1: error: expected β€˜}’ at end of input
3:33:41 PM:  }  // namespace sharp
3:33:41 PM:  ^
3:33:41 PM: cc1plus: warning: unrecognized command line option β€˜-Wno-cast-function-type’
3:33:41 PM: sharp.target.mk:138: recipe for target 'Release/obj.target/sharp/src/common.o' failed
3:33:41 PM: make: *** [Release/obj.target/sharp/src/common.o] Error 1
3:33:41 PM: make: Leaving directory '/opt/build/repo/node_modules/sharp/build'
3:33:41 PM: gyp ERR! build error
3:33:41 PM: gyp ERR! stack Error: `make` failed with exit code: 2
3:33:41 PM: gyp ERR! stack     at ChildProcess.onExit (/opt/buildhome/.nvm/versions/node/v12.18.0/lib/node_modules/npm/node_modules/node-gyp/lib/build.js:194:23)
3:33:41 PM: gyp ERR! stack     at ChildProcess.emit (events.js:315:20)
3:33:41 PM: gyp ERR! stack     at Process.ChildProcess._handle.onexit (internal/child_process.js:275:12)
3:33:41 PM: gyp ERR! System Linux 4.14.138+
3:33:41 PM: gyp ERR! command "/opt/buildhome/.nvm/versions/node/v12.18.0/bin/node" "/opt/buildhome/.nvm/versions/node/v12.18.0/lib/node_modules/npm/node_modules/node-gyp/bin/node-gyp.js" "rebuild"
3:33:41 PM: gyp ERR! cwd /opt/build/repo/node_modules/sharp
3:33:41 PM: gyp ERR! node -v v12.18.0
3:33:41 PM: gyp ERR! node-gyp -v v5.1.0
3:33:41 PM: gyp ERR! not ok
3:33:44 PM: npm WARN optional SKIPPING OPTIONAL DEPENDENCY: fsevents@1.2.7 (node_modules/fsevents):
3:33:44 PM: npm WARN notsup SKIPPING OPTIONAL DEPENDENCY: Unsupported platform for fsevents@1.2.7: wanted {"os":"darwin","arch":"any"} (current: {"os":"linux","arch":"x64"})
3:33:44 PM: npm ERR! code ELIFECYCLE
3:33:44 PM: npm ERR! errno 1
3:33:44 PM: npm ERR! sharp@0.21.3 install: `(node install/libvips && node install/dll-copy && prebuild-install) || (node-gyp rebuild && node install/dll-copy)`
3:33:44 PM: npm ERR! Exit status 1
3:33:44 PM: npm ERR!
3:33:44 PM: npm ERR! Failed at the sharp@0.21.3 install script.
3:33:44 PM: npm ERR! This is probably not a problem with npm. There is likely additional logging output above.
3:33:44 PM: npm ERR! A complete log of this run can be found in:
3:33:44 PM: npm ERR!     /opt/buildhome/.npm/_logs/2020-08-03T12_33_44_321Z-debug.log
3:33:44 PM: Error during NPM install
3:33:44 PM: Error running command: Build script returned non-zero exit code: 1
3:33:44 PM: Failing build: Failed to build site
3:33:44 PM: Failed during stage 'building site': Build script returned non-zero exit code: 1
3:33:44 PM: Finished processing build request in 53.96840015s

`

Add local testing capability

I was looking to test python code locally. There is a conftest.py in the spacy course which could be used as a start, but the testing in this repo does not have that support. So i created a file which has the following hacky code

from wasabi import Printer
import sys

with(open(sys.argv[1])) as fd:
    thesolution = fd.read()
with(open(sys.argv[2])) as fd:
    thetest = fd.read()

__msg__ = Printer()
__solution__ = """{}""".format(thesolution)

exec(thesolution)

exec(thetest)

print(globals().keys())
try:
    test()
except AssertionError as e:
    __msg__.fail(e)

The advantage of this repo's mechanism is that only wasabi needs to be there on the binder server for testing. But if we want to test with data and then need to put the full repo on binder (rather than just a shadow binder repo/branch with maybe a data folder), then additional stuff for pytest does not seem a large imposition?

Possibility for auth

Hi @ines

You make so awesome tools all the time. I love it! 😍

I have a paying client that wants me to do a one-day course in Python for them and thought it would be very cool to use this tool. Due to data privacy the course has to be private though. Is it possible to use a private gitlab repo and add auth to the course app?

I am quite new in this app space.

binder issue

love the idea.

it seems something is up with binder though.

image

figured it'd mention it so that you're aware of it.

Use with (local) docker container

Very interested to try this out with my students this summer but would like to use a (local) docker container. I tried several versions of "serverSettings" but get the same error in chrome developer tools? Any recommendations on what to try? Thx @ines

image

Section with changes from src/components/juniper.js

// url: 'http://localhost:8989',
url: '',
// url: 'https://mybinder.org',
serverSettings: {
    baseUrl: 'http://localhost:8989',
    token: 'jupyter'
},
kernelType: 'python3',
lang: 'python',
theme: 'default',
isolateCells: true,
// useBinder: true,
useBinder: false

Install a package

Hi,

Thank you for this creative platform. It is amazing.
I just want to ask how to install a python library. I am trying to import numpy library but I got this error ( No module named 'numpy' ).
I tried to solve this problem by adding ( numpy==1.16.5 ) to ( binder/requirements.txt ) but I still get the same error.
Could you tell me please how to add python packages to ( course-starter-python )?

Thanks in advance.

Presenting

Hi @ines

So in chrome you can install the App which seems to work fine. Is it possible to hide notes for an audience if I am presenting (using HDMI) on a Mac?

Link directly to individual section within a chapter

Is it possible to create a link that goes directly to an individual section within a chapter? Say for example that I wanted to link to 2-Getting started in https://course.spacy.io/en/chapter1, how would I go about that? Ideally I would want the section to be opened up in a new tab on its own without the other section, but if the link autoscrolls the chapter page and expands the section that would also be a workable solution.

Edit: I just found these related issues, but it seems like the functionality was never merged into main?

Incompatibility with newer node versions

The installation steps should state the appropriate node version, since some packages in node_modules do not support Node version 12 which is the current LTS version.

Supplementary Documentation?

Hi @ines!
I work for the University of British Columbia and have been working on the the development of Data Science courses using your framework. Your documentation was super helpful, but I’ve accumulated some additional tips through my work, so I’m putting together a step-by-step guide for setup and customization. I currently have your repo forked and I’m wondering if you would welcome a pull request once my guide is ready? The guide would be used as supplement to the existing documentation.
Finally, I just want to thank you so much for making this available and open. It’s been so fun working with your framework and I have been enjoying all of it (even the troubleshooting!)!

Pre Exercise code

Hello Ines,

I really apreciate your efforts to make this project simple and useful for all code lecturer around the world ( big thanks to you )

I have a question could you help me please. My question is how to hide pre exercise code. For example if the exercise consist 2 parts and I want to hide the first part

#Part 1 ( Hide )
import pandas as pd
url = "https://github.com/data.csv"

#Part 2 ( Show )
data = pd.read_csv(url)
data.head()

How to hide part 1 ( I dont want the student see this part ) and show only part 2?

Thanks in advance.

Saving environment across the full course

Sorry @ines for referencing this again,
I tried changing isolateCells: true in src/components/juniper.js and I am still not having follow up cells retaining the variables in the previous cell's environment.
Is there anywhere I should look to debug this? I think this feature could be really useful especially for importing modules and data.

Originally posted by @hfboyce in #13 (comment)

Using only code widget

Hello Ines,

I want to use only the code widget of this template without using netlify.

Exactly like juniper I want to embed my code widget in the browser directly in the HTML but I want to use the style of code widget of this template because I can't create exercises using juniper template because there is no hint, solution, reset buttons in the juniper template.

Could you help me please and tell me what I have to do? I spent many hours trying to edit juniper template and adding hint, solution, reset buttons to create exercises but I failed.

Also, I spent many hours trying to edit this template and embed only exercise widget without chapters and slides but I failed.

I really appreciate your efforts and thank you in advance.

Localhost using ines Binder

So I did the following

  1. Import this repo, install it and make sure app is running locally.
  2. Customize the meta.json and /requirements.txt`](binder/requirements.txt).
  3. Build a Binder from the binder branch of this repo.

All works fine. BUT when I run npm dev run and executes python code then it doesn't use the Binder specified in meta.json. I can't figure out why!?

Options for multiple choice questions

Hello,

I have an issue when I stack multiple choice questions in the same exercise. When I try to select for the second question an option, it's not clickable and it updates the options of the first question, like if they are linked.
Code :

<exercise id="4" title="Wrapping up">
Let's ask some questions about the slides before wrapping up.

<choice>

<opt text="True">

Wrong

</opt>

<opt id=4 text="False" correct="true">

Good job!

</opt>

</choice>


Question 2
<choice>

<opt text="True">

Wrong

</opt>

<opt text="False" correct="true">

Good job!

</opt>

</choice>

</exercise>

In the picture, when I click for the second question on the option False, it selects the second option of the first question.
image

A fix for now is only to put one question per exercise (or maybe it's intended ?)

Overall, everything works like a charm, I only had an issue with Netlify/Binder where you need to properly delete the cache of Netlify or it won't take any updates from Binder.

Thanks!

Question & Suggestion

Hello,

I have 4 questions and 1 suggestion.

My questions:
1- Can I use this template for commercial use? I am selling online courses and I need to use online editor for my courses. I was using DataCamp light, but I don't like to put DataCamp logo and URL everywhere inside my website.

  1. I see the code in the course-starter-python/exercises/test.py is very difficult. Can I use Ex().has_equal_ast(exact=False) ? is there any simple code to match the answer with solution?

3- How to embed an interactive code widget ( with run button ) on a website or a blog ( like yours in the home page of https://spacy.io )?

4- Is there any way to write the title and description of "chapter1.md" RTL?

My suggestion:
I suggest you create a Wordpress plugin and also I suggest you make a video to explain how to use this project on any website or blog to make any website or blog interactive.

Finally, big thanks to you for this brilliant project, I really like it and I think this project better than DataCamp light and it will help many course creator around the world.

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    πŸ–– Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. πŸ“ŠπŸ“ˆπŸŽ‰

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❀️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.