# -*- coding: utf-8 -*-
# PAIRES_MINIMALES — 30 paires tirees du corpus commit (POSITIVE_JOKES, cell[35]).
# Les textes humour (4e champ) sont les textes EXACTS du corpus, accents reels
# compris. Chaque paire : (id, forme, ood, texte_humour, texte_unfun,
# note_annotateur_humour, note_annotateur_unfun,
# mecanisme_attendu, justification_edit)
# - forme : pun (jeu de mots) / sociale (blague sociale intemporelle) /
# topical (reference culturelle ou metier d'epoque)
# - ood : tranche hors distribution = texte code-mixe FR/EN
# - mecanisme_attendu : grille explicite [(element, [mots-cles FR/EN]), ...] ;
# le 1er element = le NOYAU (l'incongruite essentielle). Le scoring (cell
# explication) normalise casse + accents puis cherche les mots-cles.
# - notes 0-3 : annotation humaine unique, gelees a la construction AVANT toute
# evaluation (limite annotateur unique : cf tache appreciation).
# - justification_edit : ce que l'edition retire et ce qu'elle conserve.
# AUCUN champ ci-dessous ne derive d'une sortie de modele.
PAIRES_MINIMALES = [
("paire-p01", "sociale", False,
"Un informaticien rentre dans un bar et dit : 'je voudrais une bière,",
"Un informaticien rentre dans un bar et dit : 'je voudrais une bière bien fraîche.'",
2, 0,
[("refrain inachevé 'je voudrais'", ["refrain", "repetition", "x10", "dix fois", "inacheve"]),
("structure d'accumulation absurde", ["accumul", "absurd", "en boucle", "incantation"])],
"Achever la phrase platement ('bien fraîche') supprime le refrain suspendu ; sujet, citation et longueur conservés."),
("paire-p02", "pun", False,
"Pourquoi les développeurs confondent Halloween et Noël ? Parce que Oct 31 == Dec 25.",
"Pourquoi les développeurs évoquent Halloween et Noël ? Parce que Oct 31 vient avant Dec 25.",
3, 0,
[("lecture octale de 31", ["octal", "base 8", "base huit"]),
("équivalence numérique inattendue", ["equival", "31", "25", "egale", "meme nombre"]),
("double lecture de la notation", ["decimal", "notation", "double lecture", "deux sens", "ambigu"])],
"Remplacer l'égalité incongrue (==) par l'ordre calendaire littéral 'vient avant' ; notations Oct/Dec et fêtes conservées."),
("paire-p03", "pun", False,
"Il y a 10 types de personnes au monde : ceux qui comprennent le binaire et ceux qui ne le comprennent pas.",
"Il y a à peu près 10 types de personnes au monde : ceux qui comprennent le binaire et ceux qui ne le comprennent pas.",
3, 0,
[("le '10' lu en base 2", ["10", "binaire", "base 2", "zero un", "deux en base dix"]),
("méta-récursivité de l'énoncé", ["meta", "lui-meme", "recursif", "auto"]),
("double lecture du nombre", ["double lecture", "deux sens", "ambigu", "dix"])],
"L'approximation 'à peu près' force la lecture décimale triviale du '10' ; la phrase reste identique ailleurs."),
("paire-p04", "topical", True,
"Un SQL entre dans un bar, voit deux tables et leur dit : 'SELECT * FROM...'",
"Un SQL entre dans un bar, voit deux tables et demande laquelle est libre.",
2, 0,
[("double sens de 'tables'", ["table", "tables", "base de donnees"]),
("requête SELECT", ["select", "requete", "from", "interroge"]),
("personnification du langage", ["personnifi", "sql parle", "langage qui parle"])],
"Retirer la punchline 'SELECT * FROM...' au profit d'une question littérale de bar ; la personne (SQL) et le décor (tables) restent."),
("paire-p05", "sociale", False,
"Combien d'ingénieurs faut-il pour changer une ampoule ? Aucun, c'est un problème hardware.",
"Combien d'ingénieurs faut-il pour changer une ampoule ? Un seul, muni d'un escabeau.",
2, 0,
[("inversion de responsabilité", ["responsabilite", "rejet", "renvoi", "pas au"]),
("clivage logiciel/matériel", ["hardware", "materiel", "software", "logiciel"]),
("réponse 'aucun' déflationnaire", ["aucun", "zero", "pas besoin d'ingenieur"])],
"La réponse déflationnaire 'aucun + hardware' devient une réponse littérale ('un seul, escabeau') ; format question-réponse conservé."),
("paire-p06", "pun", False,
"Je suis tombé amoureuse d'une fonction quadratique. Mais elle avait deux racines.",
"Je suis tombé amoureuse d'une fonction quadratique. Mais elle avait deux zéros.",
2, 0,
[("double sens de 'racines'", ["racine", "root", "double sens"]),
("métaphore amoureuse mathématique", ["amoureus", "relation", "coeur", "sentiment"]),
("propriété de la quadratique", ["quadratique", "deux solutions", "deux racines", "polynome"])],
"'racines' (double lecture sentimentale/math) remplacé par 'zéros' (terme technique neutre) ; la confession amoureuse est intacte."),
("paire-p07", "topical", True,
"Un null et un undefined entrent dans un bar. Le barman dit 'On accepte pas les non-définis ici'.",
"Un null et un undefined entrent dans un bar. Le barman leur demande ce qu'ils veulent boire.",
2, 0,
[("référence JavaScript", ["null", "undefined", "javascript", "js", "typage"]),
("double sens de 'non-définis'", ["non defini", "non-defini", "double sens", "exclu"]),
("mécanisme de blague de bar", ["bar", "barman", "refus", "entrent"])],
"La réplique excluante ('on accepte pas les non-définis') devient un service ordinaire ; le couple null/undefined demeure."),
("paire-p08", "topical", True,
"Je voulais te raconter une blague sur UDP... mais je sais si elle arrive.",
"Je voulais te raconter une blague sur UDP... mais je ne sais pas si elle arrive.",
3, 0,
[("UDP sans garantie de livraison", ["udp", "best-effort", "best effort", "sans garantie", "livraison", "paquet"]),
("négation manquante = paquet perdu", ["negation", "ne...pas manquant", "paquet perdu", "omis"]),
("méta : la phrase incarne le protocole", ["meta", "la phrase elle-meme", "incarne"])],
"Restaurer la négation grammaticale ('ne...pas') désamorce la chute : la phrase redevient littérale."),
("paire-p09", "pun", False,
"Le père Noël a-t-il déjà eu un problème de pile ? Non, il a toujours des piles neuves.",
"Le père Noël a-t-il déjà eu un problème de pile ? Non, ses lampes fonctionnent toujours bien.",
1, 0,
[("double sens de 'pile(s)'", ["pile", "piles", "double sens"]),
("réponse par l'objet électrique", ["batterie", "electrique", "neuve"]),
("cadre Noël", ["noel", "pere noel"])],
"L'écho 'piles neuves' (reprise du mot de la question) remplacé par une réponse détournée ('lampes') ; le cadre questions-réponses reste."),
("paire-p10", "pun", False,
"Pourquoi le café est-il si bon au travail ? Parce qu'il est fraîchement moulu par l'échéance.",
"Pourquoi le café est-il si bon au travail ? Parce qu'il est fraîchement moulu chaque matin.",
2, 0,
[("métaphore échéance/mouture", ["echeance", "deadline", "moulu", "mouture"]),
("double sens de 'fraîchement moulu'", ["fraichement", "double sens", "moulu par"]),
("registre bureau", ["travail", "bureau", "cafe"])],
"'par l'échéance' (agent incongru) devient 'chaque matin' (circonstance banale) ; question et registre identiques."),
("paire-p11", "pun", True,
"J'ai essayé d'écrire une blague sur les coroutines, mais je n'arrive pas à la yield.",
"J'ai essayé d'écrire une blague sur les coroutines, mais je n'arrive pas à la terminer.",
2, 0,
[("yield : mot-clé et céder/livrer", ["yield", "ceder", "mot-cle"]),
("référence coroutines", ["coroutine", "async", "generateur"]),
("double lecture du verbe", ["double lecture", "deux sens", "je n'arrive pas"])],
"Le mot-clé 'yield' (double lecture) remplacé par le verbe banal 'terminer'."),
("paire-p12", "topical", True,
"Docker, Kubernetes, Prometheus, Grafana. On m'a dit que c'était simple, alors je stack.",
"Docker, Kubernetes, Prometheus, Grafana. On m'a dit que c'était simple, alors je m'y mets.",
2, 0,
[("double sens de 'stack'", ["stack", "empiler", "pile", "stacker"]),
("accumulation d'outils DevOps", ["docker", "kubernetes", "prometheus", "grafana", "outils"]),
("ironie de la promesse de simplicité", ["simple", "ironie", "promesse"])],
"'je stack' (anglicisme-jeu) remplacé par 'je m'y mets' (locution neutre) ; l'énumération d'outils reste."),
("paire-p13", "pun", False,
"Mon compilateur et moi on a une relation stable : il compile, je pleure.",
"Mon compilateur et moi on a une relation stable : il compile, je vérifie.",
2, 0,
[("double sens de 'stable'", ["stable", "build", "relation"]),
("inversion émotionnelle (pleure alors que ça compile)", ["pleure", "inversion", "absurd", "alors que"]),
("personnification du compilateur", ["compilateur", "relation"])],
"'je pleure' (réaction inversée, incongrue) devient 'je vérifie' (réaction attendue) ; 'relation stable' conservé."),
("paire-p14", "sociale", False,
"J'ai un ami palindrome. On ne peut pas se différencier.",
"J'ai un ami palindrome. C'est un mot comme un autre.",
2, 0,
[("propriété du palindrome appliquée à l'amitié", ["palindrome", "deux sens", "miroir", "endroit envers"]),
("absurdité de la catégorie (ami palindrome)", ["ami", "absurd", "personne", "mot"]),
("jeu sur la différenciation", ["differencier", "distinguer", "differents"])],
"La seconde phrase cesse d'appliquer la propriété du palindrome à la relation ; elle ramène le palindrome à un fait lexical."),
("paire-p15", "topical", False,
"Les regex sont comme des licornes : tout le monde en parle, personne les a vues.",
"Les regex sont comme des licornes : on en voit surtout dans les livres.",
2, 1,
[("simile absurde (les regex se voient partout)", ["regex", "licorne", "personne ne", "jamais vue"]),
("véracité littérale fausse = incongruité", ["inversion", "faux", "exactement le contraire"]),
("mythe du métier", ["mythe", "legende", "metier", "rumeur"])],
"La chute inversée ('personne les a vues') devient une vérité littérale sur les licornes ; le cadre de comparaison reste."),
("paire-p16", "sociale", False,
"Un physicien, un biologiste et un chimiste voient 2 bâtiments. L'un entre, l'autre sort. 'Tiens, ils ont échangé.'",
"Un physicien, un biologiste et un chimiste voient 2 bâtiments. L'un entre, l'autre sort. 'Tiens, ils se croisent.'",
1, 0,
[("trois corps de métier (format classique)", ["physicien", "biologiste", "chimiste", "trois"]),
("non-séquence finale ('ils ont échangé')", ["echange", "echangent", "non-sequence", "absurd"]),
("banalisation d'une observation triviale", ["observ", "tiens", "remarque"])],
"'échangé' (verbe impossible pour des bâtiments) devient 'se croisent' (description littérale des faits)."),
("paire-p17", "topical", True,
"Que dit un informaticien quand il s'ennuie ? 'printf(mot)\n'",
"Que dit un informaticien quand il s'ennuie ? 'Il regarde par la fenêtre.'",
1, 0,
[("printf = dire/afficher", ["printf", "affiche", "print", "impression"]),
("réponse en code à une question de parole", ["code", "reponse en code", "dire"]),
("minimalisme absurde", ["minimal", "absurd", "laconique"])],
"La réponse-code ('printf') remplacée par une réponse en parole ordinaire ; la question reste."),
("paire-p18", "topical", False,
"Si Dieu existe, il est Objective-C : tout est message.",
"Si Dieu existe, il est Objective-C : les conventions sont strictes.",
2, 0,
[("parallèle théologie/paradigme", ["dieu", "theolog", "religion", "objective-c"]),
("double sens de 'message' (passage de messages/révélation)", ["message", "passage de message", "revelation", "double sens"]),
("absorption : tout est X", ["tout est", "toute chose", "omni"])],
"La proposition totalisante 'tout est message' (double lecture) remplacée par une remarque technique plate sur les conventions."),
("paire-p19", "pun", False,
"Le temps est une illusion. Le décalage horaire, doublement.",
"Le temps est une illusion. Le décalage horaire aussi.",
2, 0,
[("référence Hitchhiker's Guide", ["hitchhiker", "guide", "adam", "douglas"]),
("jeu sur l'adverbe 'doublement'", ["doublement", "double", "doubly"]),
("amplification en cascade", ["cascade", "encore plus", "amplifie"])],
"L'adverbe inattendu 'doublement' (chute) devient l'extension plate 'aussi' ; la première phrase demeure."),
("paire-p20", "topical", False,
"Un photon entre dans un bar et commande une bière. Le barman dit 'Pour vous, c'est gratuit, on vous voit pas partir'.",
"Un photon entre dans un bar et commande une bière. Le barman lui sert la bière et lui souhaite la bonne soirée.",
3, 0,
[("physique du photon (vitesse c, temps propre)", ["photon", "lumiere", "vitesse", "temps propre", "relativite"]),
("incongruité : le barman applique la physique", ["barman", "gratuit", "voit pas partir", "incongrui"]),
("blague de bar détournée", ["bar", "biere", "commande"])],
"La réplique physique du barman ('on vous voit pas partir') devient un service et une formule de politesse ordinaires."),
("paire-p21", "pun", False,
"J'ai une blague sur les matrices, mais c'est hors de portée du public.",
"J'ai une blague sur les matrices, mais elle est trop longue à raconter.",
1, 0,
[("double sens de 'portée' (range math/accessible)", ["portee", "range", "matrice", "math"]),
("méta-humour : retenir la blague", ["meta", "retient", "ne la raconte pas", "promesse"]),
("registre mathématique", ["matrice", "matrices", "algebre"])],
"'hors de portée' (jeu mathématique) remplacé par le motif banal 'trop longue à raconter'."),
("paire-p22", "topical", False,
"Un chat roux dans une salle de serveurs est dangereux : il pourrait activer l'incident majeur.",
"Un chat roux dans une salle de serveurs est dangereux : il pourrait débrancher un câble.",
1, 0,
[("mème du chat roux = chaos", ["chat roux", "meme", "internet", "chaos"]),
("vocabulaire NOC/production", ["incident", "noc", "production", "severite"]),
("exagération absurde du risque", ["exagere", "absurd", "risque"])],
"L'aboutissant spectaculaire ('activer l'incident majeur') devient un risque physique banal et plausible ('débrancher un câble')."),
("paire-p23", "sociale", False,
"Pourquoi les plongeurs plongent-ils toujours en arrière et jamais en avant ? Parce que sinon ils tomberaient dans le bateau.",
"Pourquoi les plongeurs plongent-ils toujours en arrière et jamais en avant ? Parce que c'est plus simple pour repartir du bateau.",
3, 0,
[("logique absurde de la chute", ["tomberaient", "bateau", "logique absurde", "inversion"]),
("format devinette", ["pourquoi", "devinette", "question"]),
("géométrie inversée (avant = bateau)", ["en avant", "arriere", "geometrie", "sens"])],
"La chute géométriquement absurde ('tomberaient dans le bateau') devient une raison mécanique plausible ('repartir du bateau')."),
("paire-p24", "topical", False,
"Le HTML n'est pas un langage de programmation. Et le plus dur, c'est de le dire à mon patron.",
"Le HTML n'est pas un langage de programmation. Et le plus dur, c'est de le documenter proprement.",
2, 0,
[("débat tech canonique", ["html", "langage de programmation", "debat"]),
("tension hiérarchique (patron)", ["patron", "hierarch", "travail", "dire"]),
("déplacement : difficulté sociale d'un fait technique", ["le plus dur", "difficile de dire", "social"])],
"La difficulté sociale ('dire à mon patron') devient une difficulté technique ('documenter proprement') ; l'affirmation technique reste."),
("paire-p25", "topical", False,
"Si vous pensez que personne ne s'intéresse à votre vie, regardez vos logs Git.",
"Si vous pensez que personne ne s'intéresse à votre vie, regardez vos notifications.",
2, 0,
[("métaphore de surveillance", ["surveill", "trace", "espion", "interesse"]),
("logs Git comme trace de vie", ["log", "git", "historique", "commits"]),
("réconfort ironique", ["personne ne", "ironie", "regarde"])],
"'logs Git' (trace technique détournée en preuve d'intérêt) remplacé par 'notifications' (objet littéralement fait pour ça)."),
("paire-p26", "sociale", False,
"Comment debug-on un avion ? On retire les composants un par un jusqu'à ce qu'il ne plante plus.",
"Comment répare-t-on un avion ? On remplace les composants défectueux selon la procédure certifiée.",
3, 0,
[("transfert de la procédure de debug", ["debug", "bisection", "un par un", "procedure"]),
("double sens de 'plante' (crash)", ["plante", "crash", "double sens", "tomber en panne"]),
("danger absurde (avion de prod)", ["avion", "danger", "absurd"])],
"'debug-on' devient 'répare-t-on', la bisection incongrue devient la maintenance certifiée ; le sujet (avion, composants) reste."),
("paire-p27", "pun", True,
"Mieux vaut avoir un git pull que deux tu l'auras.",
"Mieux vaut faire un git pull régulier que de tout merger d'un coup.",
3, 0,
[("paronomase du dicton", ["dicton", "proverbe", "mieux vaut", "tu l'auras"]),
("git pull substitué au mot attendu", ["git pull", "tirer", "fusion"]),
("double lecture de l'avoir", ["avoir", "double sens", "posseder"])],
"La paronomase ('un git pull' / 'un qui tu l'auras') défusionnée en conseil technique plat."),
("paire-p28", "sociale", False,
"Mon chat a appris Python. Maintenant il chasse les exceptions au lieu des souris.",
"Mon chat a appris Python. Maintenant il marche sur le clavier au lieu de chasser les souris.",
2, 0,
[("chasse redirect vers les exceptions", ["chasse", "exception", "proie", "souris"]),
("anthropomorphisme technique", ["chat", "python", "appris", "anthropomorph"]),
("métabole 'au lieu de'", ["au lieu", "remplace", "desormais"])],
"L'appariement absurde (chasser des exceptions) devient un comportement félin réel (marcher sur le clavier) ; la structure 'au lieu des souris' reste."),
("paire-p29", "sociale", False,
"Les submodules Git, c'est comme les voisins : mieux vaut ne pas les déranger.",
"Les submodules Git, c'est une fonctionnalité à manier avec précaution.",
2, 0,
[("métaphore sociale (voisins)", ["voisin", "voisins", "deranger", "social"]),
("folklore des submodules", ["submodule", "sous-module", "git"]),
("conseil de sagesse détourné", ["mieux vaut", "sagesse", "conseil"])],
"La comparaison sociale ('comme les voisins') supprimée ; il reste une phrase technique prudente."),
("paire-p30", "pun", True,
"Il était une fois un UTF-8 qui ne savait pas où était la fin. Il était perdu dans un BOM.",
"Il était une fois un UTF-8 qui ne savait pas où était la fin. Il a trouvé la réponse dans la norme.",
2, 0,
[("conte détourné + jargon d'encodage", ["utf-8", "encodage", "bom", "conte", "il etait une fois"]),
("BOM : le délimiteur qui égare", ["bom", "marqueur", "octet", "debut"]),
("double lecture de 'la fin' (fin de chaîne/fin du conte)", ["fin", "chaine", "terminaison", "double lecture"])],
"La chute technique ('perdu dans un BOM') remplacée par un dénouement plat ('la réponse dans la norme') ; le cadre du conte reste."),
]
FORMES = ["pun", "sociale", "topical"]
assert len(PAIRES_MINIMALES) == 30
assert all(p[1] in FORMES for p in PAIRES_MINIMALES)
n_par_forme = Counter(p[1] for p in PAIRES_MINIMALES)
n_ood = sum(1 for p in PAIRES_MINIMALES if p[2])
print(f"[paires] {len(PAIRES_MINIMALES)} paires, formes : {dict(n_par_forme)}, tranche OOD code-mixé : {n_ood}")
# Fidelite au corpus, verifiee AU RUN contre le corpus execute (cell[35]) :
# chaque texte humour doit etre le texte EXACT de POSITIVE_JOKES.
_corpus_par_id = {inst["id"]: inst["texte"] for inst in positive_instances}
for p in PAIRES_MINIMALES:
ref = _corpus_par_id["joke-" + p[0].replace("paire-", "")]
assert p[3] == ref, f"{p[0]} : texte humour != corpus\n paire : {p[3]!r}\n corpus: {ref!r}"
print("[paires] 30/30 textes humour verbatim du corpus (assert de fidélité passé)")