---
jupytext:
  notebook_metadata_filter: rise
  text_representation:
    extension: .md
    format_name: myst
    format_version: 0.13
    jupytext_version: 1.11.5
kernelspec:
  display_name: Python 3 (ipykernel)
  language: python
  name: python3
rise:
  auto_select: first
  autolaunch: true
  centered: false
  enable_chalkboard: true
  height: 100%
  margin: 0
  maxScale: 1
  minScale: 1
  scroll: true
  slideNumber: true
  start_slideshow_at: selected
  transition: none
  width: 90%
---

+++ {"slideshow": {"slide_type": "slide"}}

# Jupyter for teaching

+++

Nicolas M. Thiéry

LRI/LISN: Laboratoire Interdisciplinaire des Sciences du Numériques

Université Paris-Saclay

+++

Erlangen, March 21st of 2022

+++

Browse live on [![Binder](https://mybinder.org/badge_logo.svg)](https://mybinder.org/v2/git/https%3A%2F%2Fgitlab.in2p3.fr%2Fjupyterhub-paris-saclay%2Fprojet-conge-innovation-pedagogique/HEAD?labpath=2022-03-20-JupyterForTeaching%2Findex.md)

+++ {"slideshow": {"slide_type": "slide"}}

## What is Jupyter?

+++ {"slideshow": {"slide_type": "fragment"}}

### Jupyter notebooks

+++ {"slideshow": {"slide_type": "fragment"}}

Documents mixing: **Narration**, **Computation**, **Visualization**, **Interaction** and **Programming**

+++ {"slideshow": {"slide_type": "fragment"}}

This slideshow is actually a Jupyter notebook!

+++ {"slideshow": {"slide_type": "fragment"}}

So far we did **Narration**: telling a story

+++ {"slideshow": {"slide_type": "subslide"}}

Now, here is a little mathematical **Computation**:

```{code-cell} ipython3
---
slideshow:
  slide_type: '-'
---
from sympy import *
x = symbols('x')

integrate(x/(x**2+2*x+1), x)
```

+++ {"slideshow": {"slide_type": "subslide"}}

a bit of data **Visualization**:

```{code-cell} ipython3
---
slideshow:
  slide_type: '-'
---
from ipyleaflet import Map, Marker
center = (48.70180933810075, 362.16683685639214)
m = Map(center=center, zoom=15)
marker = Marker(location=center, draggable=True)
m.add_layer(marker);
m
```

+++ {"slideshow": {"slide_type": "subslide"}}

a bit of **Interaction:**

```{code-cell} ipython3
from wealth_of_nation import application
application
```

(taken from the [bqplot documentation](https://github.com/bqplot/bqplot/blob/master/examples/Applications/Wealth%20Of%20Nations/Bubble%20Chart.ipynb))

+++ {"slideshow": {"slide_type": "fragment"}}

and we have seen a bit of **Programming**.

+++ {"slideshow": {"slide_type": "slide"}}

### What's new really?

+++ {"slideshow": {"slide_type": "fragment"}}

- Notebooks: Maple, Mathematica (90's), Sagenb (late 00's), IPython (10's)

+++ {"slideshow": {"slide_type": "fragment"}}

- Web based
- Modern technology
- Interoperable  
  Python, Julia, R, C++, and dozens of other languages / systems
- Widely adopted (millions of notebooks / users)  
  teaching, research, engineering, data science, ...

+++ {"slideshow": {"slide_type": "fragment"}}

### Jupyter, beyond the notebook: https://jupyter.org

An ecosystem of «Free software, open standards, and web services for
interactive computing across all programming languages»

+++ {"slideshow": {"slide_type": "slide"}}

## Jupyter for teaching

A nice reference: [teaching and learning with Jupyter, Barba et al.](https://jupyter4edu.github.io/jupyter-edu-book/)

+++ {"slideshow": {"slide_type": "fragment"}}

### Examples

+++ {"slideshow": {"slide_type": "slide"}}

#### Learn by experimenting and visualizing

+++ {"slideshow": {"slide_type": "-"}}

Taken from a [computational graph theory course](https://nicolas.thiery.name/Enseignement/M1-ISD-AlgorithmiqueAvancee/ComputerLab/README.html):

+++ {"slideshow": {"slide_type": "-"}}

**Définition:**

Soit $G$ un graphe.
- un *chemin* est une suite de sommets $(v_0, v_1, v_2, ...)$ tel qu'il existe une arête entre chaque paire de sommets $v_i$ et $v_{i+1}$
- la *distance* entre deux sommets `u` et `v` est la longueur du plus court chemin entre `u` et `v` (ou la somme des poids des arêtes).
- On suppose ici que $G$ est non orienté. La *composante connexe* d'un sommet $u$ de $G$ est l'ensemble des sommets atteignables depuis $u$ en suivant un chemin dans $G$.

**Un algorithme:**

```{code-cell} ipython3
def parcours_visualisation(G, u):
    """
    INPUT:
    - 'G' - un graphe
    - 'u' - un sommet du graphe
    
    OUTPUT: la liste des sommets `v` de `G`
            tels qu'il existe un chemin de `u` à `v`
    """
    marked = {u} # L'ensemble des sommets déjà rencontrés
    todo   = {u} # L'ensemble des sommets déjà rencontrés, mais pas encore traités
    
    player.player.reset(copy.deepcopy(locals()))
    
    while todo:
        # Invariants:
        # - Si `v` est dans `marked`, alors il y a un chemin de `u` à `v`
        # - Si `v` est dans `marked` et pas dans `todo`
        #   alors tous les voisins de `v` sont dans dans `marked`
        v = todo.pop()
        # Observation des variables locales
        player.set_value(copy.deepcopy(locals()))
        for w in G.neighbors(v):
            
            if w not in marked:
                marked.add(w)
                todo.add(w)
                # Observation des variables locales
                player.set_value(copy.deepcopy(locals()))
        v = None
        # Observation des variables locales
        player.set_value(copy.deepcopy(locals()))
    return marked
```

**Exploration interactive:**

```{code-cell} ipython3
import copy
import graph_algorithm_player
variables = [{'name': 'G',      'type': 'graph' },
             {'name': 'marked', 'type': 'nodes', 'color': 'green',  'display': True},
             {'name': 'todo',   'type': 'nodes', 'color': 'red',    'display': True},
             {'name': 'v',      'type': 'node',  'color': 'yellow', 'display': True}]
player = graph_algorithm_player.GraphAlgorithmPlayer(variables=variables)
player
```

```{code-cell} ipython3
from graph_networkx import examples
G = examples.parcours_directed()
parcours_visualisation(G, "A")
```

+++ {"slideshow": {"slide_type": "slide"}}

#### Learn by example

Taken from an [Introduction to Data Science class](https://nicolas.thiery.name/Enseignement/IntroScienceDonnees/)

**Définir une fonction en Python :**

```{code-cell} ipython3
def f(x, y, r):
    return x + y - r
```

**Exercice:** Écrire une fonction `aire_rectangle(l,h)` qui renvoie
l'aire d'un rectangle de longueur `l` et de hauteur `h`.

```{code-cell} ipython3
def aire_rectangle(l,h):
   return l * h
```

```{code-cell} ipython3
assert aire_rectangle(3, 7) == 21, "aire_rectangle ne renvoie pas le résultat attendu"
```

+++ {"slideshow": {"slide_type": "slide"}}

#### Serious games

+++

Taken from an [introductory C++/Python programming course](https://nicolas.thiery.name/Enseignement/Info111/):

```{code-cell} ipython3
from laby.global_fr import *
Laby("1b")
```

```{code-cell} ipython3
debut()
avance()
droite()
avance()
avance()
prend()
```

+++ {"slideshow": {"slide_type": "slide"}}

### Jupyter for teaching in Paris-Saclay

- Dozens of computational and programming courses: Math, Biology, Physics, Computer Science, Geophysics
- Several courses with hundreds of students at entry level

+++ {"slideshow": {"slide_type": "slide"}}

### What it can bring

+++ {"slideshow": {"slide_type": "fragment"}}

#### Autonomy

Thanks to the narrative structure:
- a clear linear path to follow
- very localized actions to take
- quick feedback loop
- reduced risks to get lost

+++ {"slideshow": {"slide_type": "fragment"}}

- Each student proceeds at its own pace
- Helps instructors focus on fragile students
- Supports hybrid teaching from full autonomy to fully tutored

+++ {"slideshow": {"slide_type": "fragment"}}

#### Flexibility

+++ {"slideshow": {"slide_type": "fragment"}}

- Students can work in the computer lab, from home, on the road
- On tablet, cell phone, offline on their own laptop
- All in the same environment

+++ {"slideshow": {"slide_type": "fragment"}}

- A continuous spectrum of use cases from using to authoring to developing
- Supports percolation of resources and know-how in communities

+++ {"slideshow": {"slide_type": "slide"}}

## Caveats and Tips

+++ {"slideshow": {"slide_type": "subslide"}}

### Go with the flow: the routine of working through notebooks

- Scroll scroll scroll. Execute, execute, execute  
- Think?

+++ {"slideshow": {"slide_type": "fragment"}}

- Short notebooks: a notebook = a unitary story
- Diversity of actions: read, try, experiment, code, debug,
  take notes, **stop and think**!
- Interactive and visual feedback

+++ {"slideshow": {"slide_type": "fragment"}}

### Jupyter notebooks can get messy

- A sheet of paper or a chalk board is a very flexible device: sketch, scribble, draw, compute, write, ...
- It takes **training** to use it properly

+++ {"slideshow": {"slide_type": "fragment"}}

**Jupyter notebooks are not different!**

+++ {"slideshow": {"slide_type": "fragment"}}

- Structure the notebooks for your students
- Keep in mind to train your students
- Notebooks are about narration!  
  code that is not relevant to the narration belongs to code files
- Notebooks are no replacement for specialized tools!  
  IDE (programming only), word processors (narration only)

+++ {"slideshow": {"slide_type": "slide"}}

## Advanced topics

+++ {"slideshow": {"slide_type": "fragment"}}

### How do I make interactive slides?

[RISE](https://github.com/damianavila/RISE/)

+++ {"slideshow": {"slide_type": "fragment"}}

### How do I make mini interactive applications?

[Jupyter widgets](https://ipywidgets.readthedocs.io/en/stable/examples/Widget%20Basics.html)

```{code-cell} ipython3
from ipywidgets import Button, IntSlider, VBox
slider = IntSlider(value=3, vmin=0, vmax=10)
button = Button(description="Click me!")
button.on_click(lambda event: print(slider.value))
VBox([button, slider])
```

+++ {"slideshow": {"slide_type": "subslide"}}

### How do I publish my course?

[jupyter-book](https://jupyterbook.org/): build a static web site from a collection of notebooks

- [Example](https://nicolas.thiery.name/Enseignement/IntroScienceDonnees/)

- Features:
    - Cross references
    - Search
    - «try it online» (currently: with public repo on github only)
    - ...

+++ {"slideshow": {"slide_type": "subslide"}}

### How do I make it easy for my students to access Jupyter?

+++ {"slideshow": {"slide_type": "fragment"}}

[JupyterHub](https://jupyter.org/hub): Software to deploy online service providing Jupyter virtual environments

Example: [JupyterHub@Paris-Saclay](https://jupyterhub.ijclab.in2p3.fr/)
- for all personnel and students
- typical load of 100-200 simultaneous users

+++ {"slideshow": {"slide_type": "fragment"}}

### Reproducible environments (software, data, ...)

- How do I make sure all the required software is available?
- and consistent across the lab, jupyterhub, my laptop, the student laptops?

+++ {"slideshow": {"slide_type": "-"}}

Example: conda + pip

+++ {"slideshow": {"slide_type": "slide"}}

### Reproducible teaching: How do I enforce the robustness of my assignments?

A challenge with computer assignments: the devil is in the details!
- Is my assignment actually doable today?
- Even after the latest XXX upgrade?
- Are my solutions up to date?

+++ {"slideshow": {"slide_type": "fragment"}}

One piece of the puzzle:

Autogenerate the student version:
```
def max(x,y):
    # TODO: YOUR CODE HERE
	raise NotImplementedError();
```

from the instructor version:
```
def max(x,y):
    ### BEGIN SOLUTION
	if x > y:
	    return x
	else:
		return y
	### END SOLUTION
```

e.g. with [nbgrader](https://nbgrader.readthedocs.io/)

+++ {"slideshow": {"slide_type": "fragment"}}

Another piece: Automated testing through Continuous Integration

+++ {"slideshow": {"slide_type": "subslide"}}

### How do I manage assignments?

- How do I distribute my assignment to my students?
- How do I collect them?
- How do I track their progress?

«Teaching computer science or computational courses is
all about collaboration on code. It is thus unsurprising that,
with a pinch of salt, forges like GitLab can provide helpful
infrastructure to support and enhance that collaboration.»

- GitHub classes
- GitLab classes
- [travo](https://gitlab.info.uqam.ca/travo/travo):  
    - git and GitLab made easy through automation
    - used by hundreds of first year students in math, physics, computer science

+++ {"slideshow": {"slide_type": "subslide"}}

### Notebooks as text files (with [jupytext](https://jupytext.readthedocs.io/))

- Use your favorite text editor / tools
- Don't store outputs
- Plays well with versioning
- Saves space

+++ {"slideshow": {"slide_type": "slide"}}

### How do I grade the assignments?

Automatic and computer aided grading:
- with Continuous Integration
- with [nbgrader](https://nbgrader.readthedocs.io/)

- Students can self-evaluate
- early feedback

+++ {"slideshow": {"slide_type": "slide"}}

### How do I help student collaborate on assignments?

- Real time collaboration with JupyterLab
- Asynchronous collaboration with GitLab  
  Basic support in travo designed but not implemented

+++ {"slideshow": {"slide_type": "slide"}}

## The Candyce project

- Toward a national Jupyter deployment for French (hight) schools and higher education
- 3+2 years, 12M€, proposal submitted
- Lead: INRIA / Paris-Saclay
- Main work packages:
     - Software development
     - Deployment and operation
     - Adoption and coconstruction in higher education
     - Adoption and coconstruction in (high) schools
     - Adoption and coconstruction in the community
     - Learning analytics and research

+++ {"slideshow": {"slide_type": "fragment"}}

### Jupyter for high schools? really?

Building on Capytale: a jupyter deployment for high schools

150000 registered students in two years of existence

+++ {"slideshow": {"slide_type": "subslide"}}

### Beyond Jupyter

«Open Source Scientific Software at the fingertip of every kid,
student and teacher (and researcher)»

Via on demand configurable virtual environment for (lightweight) computation

+++ {"slideshow": {"slide_type": "fragment"}}

The Candyce service, in practice:
- INPUT: a **virtual environment description**
  - a list of software (packaged in conda)
  - resources

- can be named through a URL

+++ {"slideshow": {"slide_type": "fragment"}}

- OUTPUT:
  - a virtual machine (container) just for you
  - hosted by a trusted cloud provider
  - with access to limited physical resources
  - with the software and resources
  - and a persistent home directory for the user
  - running a web-application  
    Jupyter, R-studio, visual studio, ... your own

+++ {"slideshow": {"slide_type": "subslide"}}

### Secondary mission: the toolkit

- Improving the ecosystem supporting the deployment of similar infrastructures
- Beyond France
- Beyond education

+++ {"slideshow": {"slide_type": "subslide"}}

## Discussion / project topics for this week

+++ {"slideshow": {"slide_type": "fragment"}}

### Jupyter for teaching

Happy to discuss and help if I can!

+++ {"slideshow": {"slide_type": "fragment"}}

### Toward a semantic web of (Jupyter) teaching resources?

Use case 1: help teachers find resources to reuse
Use case 2: help student navigate resources (adaptative learning / guided tours)

-   Discussion: why and how to annotate Jupyter courses
-   Coding sprint: start annotating the corpus of Jupyter-based courses in Paris-Saclay

+++ {"slideshow": {"slide_type": "fragment"}}

### Write down an intention letter for the collaboration FAU / Candyce
