# HackInScience

<!-- .slide: data-background="static/background.jpg" -->

<br/>

<b>Julien Palard</b>

<tt>CPython core dev</tt>


# Demo time !

Parce que vous êtes là pour ça.

::: notes

Qui à dit « C'est moche ! » ? Je ne suis pas dev front !

Ne pas oublier la démo C et Rust !

Ceux pour qui la démo suffit, vous pouvez sortir ♥

## Enseigner le Python

J'ai l'habitude.

Mais à des groupes de ~6 pendant ~3 jours.

## C'est green

![Ruby Rhod](static/ruby-rhod.jpg)

## Enseigner le Python

Un jour on nous a proposé un groupe de 50 pendant 7 jours.

::: notes

En fait il sont arrivés à 80.

## C'est pas green

![Ruby Rhod étranglé](static/pas-green.jpg)

## Mais on est devs

Alors on a automatisé tout ce qui pouvait l'être.

::: notes

Pour passer du temps avec ceux qui en ont besoin.


# HackInScience.org

C'est un petit Django, avec un peu de celery.

::: notes

Pour répartir les corrections sur des machines qui ne font que ça.


## 181 lignes de Python

Ça devrait loger dans quelques slides ;)

::: notes

Aujourd'hui c'est 2700 lignes de code…


## Django models

```python
class Exercise(models.Model):
    title = models.CharField(max_length=255)
    wording = models.TextField()
    check = models.TextField()
```

## Django view

```python
class ExerciseListView(LoginRequiredMixin, ListView):
    model = Exercise
    template_name = "hkis/exercises.html"

class ExerciseView(LoginRequiredMixin, DetailView):
    model = Exercise
    template_name = "hkis/exercise.html"
```

::: notes

Vous saviez que la MRO de Python garanti un héritage de gauche à droite ?

Ici il est garanti que les méthodes surchargées par `LoginRequiredMixin`
sont exécutées avant celles de `ListView`.


## Une petite API

```python
class ExerciseSerializer(HyperlinkedModelSerializer):
    class Meta:
        model = Exercise
        fields = '__all__'

class ExerciseViewSet(viewsets.ModelViewSet):
    queryset = Exercise.objects.all()
    serializer_class = ExerciseSerializer

router = routers.DefaultRouter()
router.register('exercises', ExerciseViewSet)
```

::: notes

Pourquoi un "Router" ? Parce que derrière cette ViewSet il y a plein
de vues !

Démo time !

## Une interface d'admin

```python
from django.contrib import admin
from website.models import Answer, Exercise

admin.site.register(Answer)
admin.site.register(Exercise)
```

::: notes

Comme ça on a pu se concentrer sur les exercices et les moulinettes de correction.

# C'est utilisé ?

Je n'ai pas de « pisteur », mais j'ai une DB.

En octobre 2022 : 730 personnes ont résolu 10_780 exercices

La moulinette a corrigé près de 50k rendus.

::: notes

Google Analytics c'est illégal. Mais je sais écrire du SQL.

Aucun tracker, aucune pub, aucun asset externe.

10k c'est peu ou beaucoup, je ne sais pas.

## Ça tient la charge ?

Les exercices sont corrigés en environ 200ms.

Deux serveurs se répartissent le travail.

Les boucles infinies sont interrompues après 20s.

::: notes

Il est très facile d'ajouter un serveur de correction au besoin.


## C'est rentable ?

Ren…quoi ? Pardon ?

J'ai pas de « business model », et non mon projet ne va pas « mourir demain » pour autant #sry.

::: notes

Afficher la page des sponsors, remercier les sponsors et Gandi.

En fait c'était rentable jusqu'à ce que j'achète des billets de train pour venir ici :D


# Côté sécu

Les rendus sont exécutés côté serveur.

C'est un challenge niveau sécurité.

::: notes

Python est réputé pour ne pas être sandboxable, du moins pas depuis l'intérieur de l'interpréteur.


## seccomp

\+ Linux namespaces

\+ rlimit

::: notes

Pourquoi pas Docker ? Pas besoin d'un filesystem complet, juste d'un processus.

# Vu d'un enseignant

::: notes

Vous êtes libres de quitter la salle.

## L'interface d'admin

## Un repo git

Juste pour les exos.

# L'hébergement d'instances locales

Possible, évidement, j'ignore s'il y en a.

# Mot de la fin

Si vous aimez Python, n'oubliez pas la PyConFr !

Du 16 au 19 février 2023 !

# Questions

- Mastodon : [@mdk@mamot.fr](https://mamot.fr/@mdk)
- XMPP : mdk@chapril.org
- HTTP : https://mdk.fr
- SMTP : julien@python.org
- Whatsapp : HAHAHA jamais.
- Insta : Et puis quoi encore ?
- TikTok : SSTTTTOOOOOOOOP !
