6.5 KiB
::: notes
Remercier ceux qui nous hébergent.
HackInScience
Hackinscience
Julien Palard
Paris.Py #16
Julien Palard
- Python core dev / freelance
- CPython documentation translator (french only)
- Python teacher/coach, at
- Makina Corpus
- Center for Research and Interdisciplinarity
- Sup'Internet
- …
julien@python.org, @sizeof, https://mdk.fr
HackInScience
Back in 2015, we started a project with the CRI of Paris Descartes: A one-week intensive Python class.
::: notes
"The Center for Research and Interdisciplinarity" en anglais.
- Ouvert à tous : élèves de l'université, chercheurs, public.
Pedagogy
We were aiming for 50 students per week, so we had to adapt, we needed:
- A short Python introduction (slides and a teacher).
- Lots of exercises, sorted by difficulty.
- A bot to correct exercises, live.
- 2 to 3 highly available teachers in the room.
- Short optional lessons about very specific topics.
- Rules, teaching best practices.
::: notes
Rules like: never touch a student keyboard: they're here to learn.
2015: Focus on content
We started by focusing on exercises (needed to give a course) and the correction bot (needed to scale).
Workflow from a student point of view:
- Clone the exercise repo
- Do exercises
- git push
- Receive a mail with the correction
::: notes
It was crude, but it worked.
We automated exercises corrections (like exercises unit tests) using a Python script.
2016: Focus on confort
Antoine Angot developped a website so students do no longer needed to use git. Emails were no longer needed, which is nice too.
::: notes
Thx bro!
Turns out that teaching git took a lot of time over teaching Python...
And emails were easily marked as spam even with SPF and DKIM configured properly.
2017: Focus on content, again
The year to enhance existing parts, to rely on them, this is also the year of... many repositories:
- One for the website
- One for the exercises (markdown files)
- One for our internal documentation
- One for the correction bot
- One for the ansible playbook
::: notes
Exercises had a check.py and a solution.py
Internal documentation == teaching best practices.
2018: Migrating to Django
Jérôme Schneider started to migrate the website to Django.
(So we could modify it more easily.)
::: notes
Thx bro :) A nice part was templates: the syntax was almost the same.
Show me the code!
So what is it now? 181 lines of Python (first fully working version), it should fit in a few slides ;)
::: notes
Today it's more like 700 lines of code, mainly little tweaks and personalisation.
Django models
class Exercise(models.Model):
title = models.CharField(max_length=255)
check = models.TextField()
solution = models.TextField()
wording = models.TextField()
::: notes
Already know Django? Focus on the content.
Django models
Helps in generating:
- DB migrations;
- Admin pages;
- Forms;
- Views (Using class-based views);
- API (Using DRF);
- Queries ("ORM" as humans say).
::: notes
A Django Model makes the code aware of the database structure.
- Autocompletion
- ...
Django view
class ExerciseListView(LoginRequiredMixin, ListView):
model = Exercise
template_name = "hkis/exercises.html"
::: notes
How to read this Mixin thing?
Read: ExerciseListView inherite first from LoginRequiredMixin, then on ListView. So LoginRequiredMixin can place its method before ListView, like intercepting them.
Django view
Django view
class ExerciseView(LoginRequiredMixin, DetailView):
model = Exercise
template_name = "hkis/exercise.html"
def get_context_data(self, **kwargs):
"""Add student answers.
"""
context = super().get_context_data(**kwargs)
context["answers"] = self.object.answers.filter(
user=self.request.user
).order_by("-id")
return context
Django view
Need an API now
class ExerciseSerializer(serializers.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
Why DRF use a router? Because there's many views in a ViewSet.
Need an API now
::: notes
A nice feature: The API replies with HTML when asked for, so it's browsable using a web browser.
Need an admin interface now
from django.contrib import admin
from website.models import Answer, Exercise
admin.site.register(Answer)
admin.site.register(Exercise)
Admin interface
Admin interface
::: notes
We're using markdown to redact exercises.
Admin interface
::: notes
This is the Python script used to check an exercise.
We need lives updates, now!
So when a student submit an answer, he gets a correction as soon as possible.
We can use Django Channels
for this.
Django Channels
Need first to setup some kind of high level router:
application = ProtocolTypeRouter(
{"websocket": AuthMiddlewareStack(
URLRouter(website.routing.websocket_urlpatterns))}
)
and
websocket_urlpatterns = [
url(
r"^ws/answers/(?P<user_id>[0-9]+)/(?P<exercise_id>[0-9]+)/$",
consumers.AnswerConsumer,
)
]
Django Channels
Note the ws/
prefix, it's usefull once in production:
- nginx → gunicorn, for HTTP
- nginx → daphne, for websockets
Django Channels
We're disambiguating it nginx side:
location /ws {
proxy_pass http://unix:/run/hkis-website/daphne.sock;
proxy_http_version 1.1;
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection "Upgrade";
}
location / {
proxy_pass http://unix:/run/hkis-website/website.sock;
proxy_set_header Host $host;
}
The future
Display exercises as a tree, with subjects like datascience, web, low-level, and so on as group of leafs of the tree.
::: notes
So one could navigate to its preferred subject.
Questions?
- julien@python.org
- Twitter: @sizeof
- IRC: mdk on #python-fr (freenode)
- https://mdk.fr
- https://hackinscience.org