C’est quoi Culture Créative ?
Culture Créative est un quiz interactif développé avec Streamlit et Python qui te permet de tester tes connaissances sur les licences Creative Commons et le droit d’auteur. Explore les différentes licences, leurs conditions de partage, et découvre comment contribuer à une culture numérique collaborative.
Tu produis du contenu en ligne et tu aimerais mieux comprendre comment le partager tout en gardant le contrôle de tes droits? J’ai créé un petit outil interactif pour toi.
🌘 Le projet
Culture Créative est un quiz qui te présente des questions sur les licences Creative Commons. Chaque question est associée à une licence spécifique, et tu dois choisir la bonne réponse parmi plusieurs options. À la fin, tu vois une explication détaillée qui te permet d’en apprendre plus sur chaque licence.
Voici comment se comparent les permissions de chaque licence :
graph LR
subgraph "Plus permissif"
PUB[Domaine public / CC0]
end
subgraph "Attribution requise"
BY[CC-BY]
BYSA[CC-BY-SA]
BYNC[CC-BY-NC]
BYND[CC-BY-ND]
BYNCSA[CC-BY-NC-SA]
BYNCND[CC-BY-NC-ND]
end
PUB --> BY
BY --> BYSA
BYSA --> BYNC
BYNC --> BYND
BYND --> BYNCSA
BYNCSA --> BYNCND
BYNCND --> R[Plus restrictif]
Le jeu couvre huit licences :
🌘 Pourquoi les licences Creative Commons ?
Les licences Creative Commons sont un outil légal incontournable pour les créateurs de contenu. Elles te permettent de définir les conditions de partage de tes œuvres tout en préservant certains droits. C’est une façon de contribuer à une culture numérique collaborative sans tout abandonner.
Le quiz t’aide à comprendre les nuances entre chaque licence : quand utiliser CC-BY-SA plutôt que CC-BY-NC, ce que signifie le domaine public, ou pourquoi quelqu’un choisirait une licence sans utilisation commerciale.
🌘 Comment ça marche ?
Le jeu est construit avec Streamlit, un framework Python qui permet de créer des applications web interactives en quelques lignes de code.
sequenceDiagram
participant U as Utilisateur
participant App as Streamlit App
participant F as Fichiers JSON
App->>F: Charger licences.json et questions.json
App->>App: Initialiser session state
App->>App: select_question() → question aléatoire
App->>U: Afficher question + choix
U->>App: Sélectionner une réponse + cliquer Vérifier
App->>App: check_answer() → comparer à la bonne réponse
App->>U: Afficher succès/erreur + explication
App->>App: Afficher licence correspondante
App->>U: Nouvelle question?
🌘 Les données
Les licences sont définies dans un fichier JSON :
{
"licences": [
{
"licenceId": "CC-BY-4.0",
"logo": "by.png",
"name": "Creative Commons Attribution 4.0 International",
"url": "https://creativecommons.org/licences/by/4.0/"
},
{
"licenceId": "CC-BY-NC-4.0",
"logo": "by-nc.png",
"name": "Creative Commons Attribution Non Commercial 4.0 International",
"url": "https://creativecommons.org/licences/by-nc/4.0/"
},
{
"licenceId": "CC-BY-NC-ND-4.0",
"logo": "by-nc-nd.png",
"name": "Creative Commons Attribution Non Commercial No Derivatives 4.0 International",
"url": "https://creativecommons.org/licences/by-nc-nd/4.0/"
},
{
"licenceId": "CC-BY-NC-SA-4.0",
"logo": "by-nc-sa.png",
"name": "Creative Commons Attribution Non Commercial Share Alike 4.0 International",
"url": "https://creativecommons.org/licences/by-nc-sa/4.0/"
},
{
"licenceId": "CC-BY-ND-4.0",
"logo": "by-nd.png",
"name": "Creative Commons Attribution No Derivatives 4.0 International",
"url": "https://creativecommons.org/licences/by-nd/4.0/"
},
{
"licenceId": "CC-BY-SA-4.0",
"logo": "by-sa.png",
"name": "Creative Commons Attribution Share Alike 4.0 International",
"url": "https://creativecommons.org/licences/by-sa/4.0/"
},
{
"licenceId": "CC-PDDC",
"logo": "publicdomain.png",
"name": "Creative Commons Public Domain Dedication and Certification",
"url": "https://creativecommons.org/licences/publicdomain/"
},
{
"licenceId": "CC0-1.0",
"logo": "cc-zero.png",
"name": "Creative Commons Zero v1.0 Universal",
"url": "https://creativecommons.org/publicdomain/zero/1.0/"
}
]
}
Les questions du quiz :
{
"questions": [
{
"id": 1,
"licence": "CC-BY-4.0",
"question": "Dans le code civil du Québec, le concept de droit moral existe, mais il n'est pas présent dans le Common Law. Qu'est-ce que le droit moral signifie pour les créateurs de contenu ?",
"answers": [
"Le droit d'être reconnu comme l'auteur du contenu",
"Le droit de protéger sa réputation en tant que créateur de contenu",
"Le droit d'être publié par une maison d'édition",
"Le droit de recevoir une rémunération pour les copies de son contenu"
],
"explanation": "Le droit moral représente le droit d'être reconnu comme l'auteur du contenu, ce qui est maintenant appelé attribution dans les licences Creative Commons. Le 'BY' apparaît dans toutes les versions des licences, sauf celles pour le domaine public. Pour les utilisateurs, une licence Creative Commons Attribution 4.0 International (CC-BY-4.0) signifie l'obligation de citer les auteurs originaux d'une œuvre."
}
]
}
Chaque œuvre d’exemple est aussi documentée : tu peux voir comment des organisations comme le gouvernement du Québec, les RÉCIT nationaux, ou des chercheuses et chercheurs utilisent ces licences dans la vraie vie.
🌘 Le code de l’application
L’application est construite en une centaine de lignes de Python. Voici le coeur du jeu :
# Copyright (c) 2023, François Pelletier
# Disponible sous licence AGPL-3.0 or later (http://www.gnu.org/licenses/agpl)
import json
import logging
import random
from pathlib import Path
import streamlit as st
from streamlit import session_state as ss
# Initialize session state
if "current_question" not in ss:
ss.current_question = None
if "questions_lues" not in ss:
ss.questions_lues = False
with open("donnees/licences.json") as file:
licences_data = json.load(file)["licences"]
licences_dict = {}
for licence_data in licences_data:
licences_dict[licence_data["licenceId"]] = licence_data
licences_dict = licences_dict
# Function to select a random question
def select_question():
"""
This function selects a random question from the list of questions
and shuffles the answers for each question.
"""
if not ss.questions_lues:
with open("donnees/questions.json") as file:
ss.questions = json.load(file)["questions"]
random.shuffle(ss.questions)
ss.questions_lues = True
logging.info("Appel de la fonction select_question()")
ss.current_question = ss.questions.pop()
# Shuffle the answers
answers = ss.current_question["answers"].copy()
random.shuffle(answers)
ss.current_answers = answers
# Function to check the selected answer
def check_answer():
"""
This function checks the selected answer.
:return:
"""
logging.info("Appel de la fonction check_answer()")
correct_answer = ss.current_question["answers"][0]
selected_answer = ss.selected_answer
licence = ss.current_question["licence"]
nom = licences_dict[licence]["name"]
url = licences_dict[licence]["url"]
logo = licences_dict[licence]["logo"]
if selected_answer == correct_answer:
st.success("Bonne réponse!")
else:
st.error(f"Mauvaise réponse! La bonne réponse est: {correct_answer}")
st.subheader("Explication")
st.write(ss.current_question["explanation"])
st.markdown(f"Cette licence se nomme [{nom}]({url})")
st.image(f"logos/{logo}")
ss.clear()
# Main app
st.image("images/banniere.jpeg")
st.title("Culture Créative - Version Bêta !")
# Haut de page
header_content = Path("donnees/header.md").read_text()
st.markdown(header_content, unsafe_allow_html=True)
# Check if a question is already selected
if not ss.current_question:
select_question()
# Form for answer
with st.form("answer_form"):
logging.info("Afficher la question")
# Display the current question
st.subheader("Question")
st.write(ss.current_question["question"])
# Display the answer options
logging.info("Afficher les réponses possibles")
st.subheader("Réponses possibles")
ss.selected_answer = st.radio(
f"Choisis une réponse",
options=["---"] + ss.current_answers,
key=0
)
# Display the correct answer
if st.form_submit_button(label="Vérifier") and ss.selected_answer != "---":
logging.info("Vérifier la réponse")
check_answer()
if st.form_submit_button(label="Prochaine question"):
logging.info("Prochaine question")
ss.clear()
select_question()
# Pied de page
footer_content = Path("donnees/footer.md").read_text()
st.markdown(footer_content, unsafe_allow_html=True)
🌘 Essayer le jeu
Tu peux tester l’application en ligne sur jevalide.ca/culture-creative.
Si tu préfères l’exécuter localement :
pip install -r requirements.txt
streamlit run app.py
Ou avec Docker :
docker build -t culture-creative .
docker run -p 8501:8501 culture-creative
🌘 Licence
Le contenu textuel et les illustrations sont disponibles sous licence Creative Commons Attribution - Partage dans les Mêmes Conditions 4.0 International. Le code source est disponible sous licence GNU Affero General Public License.
Tout le code et les données sont sur mon dépôt GitLab.