Un chatbot en Python

Un chatbot en Python

La logique d’un chatbot en Python n’est pas très compliquée à comprendre. Nous allons voir dans cet article l’essentiel de cette logique.

chatbot en Python
chabot en Python

Ce dont nous aurons besoin pour créer un chatbot en Python

La liste est relativement courte. Nous aurons besoin des modules:

  • tkinter (pour ce qui est interface graphique)
  • json (pour gérer les interactions avec les fichiers json)
  • difflib (pour la fonction get_close_matches, qui sert à trouver les meilleurs résultats correspondant à un mot-clé).

Comme à notre habitude, nous n’importerons pas tout le module tkinter, mais seulement ce dont nous nous servirons, à savoir : Tk, Label, Entry, Button, Text, Scrollbar et Frame.

Une classe “Chatbot” Python

On peut créer une classe représentant le chatbot Python. Nous voulons quelque chose qui ressemble à cela :

chatbot python
Screenshot chatbot
class Chatbot:
    def __init__(self, window):
        window.title('Mathweb Assitant')
        window.geometry('400x400')
        window.resizable(0,0)
        self.message_session = Text(window, bd=3, relief="flat", font=("Times", 10), undo=True, wrap="word")
        self.message_session.config(width=45, height=15,bg="#008a9c", fg="white", state='disabled')
        self.overscroll = Scrollbar(window, command=self.message_session.yview)
        self.overscroll.config(width=20)
        self.message_session["yscrollcommand"] = self.overscroll.set
        self.message_position = 1.5
        self.send_button = Button(window, text='Envoyer', fg='white', bg='#00813b',width=9,font=('Times', 12), relief ='flat', command = self.reply_to_you)
        self.Message_Entry = Entry(window, width=40, font=('Times', 12))
        self.Message_Entry.bind('<Return>', self.reply_to_you)
        self.message_session.place(x=20, y=20)
        self.overscroll.place(x=370, y=50)
        self.send_button.place(x=0, y=360)
        self.Message_Entry.place(x=135, y=365)
        self.Brain = json.load(open('mathweb.json',encoding='utf-8'))

Le constructeur (__init__) définit une fenêtre à l’aide de tkinter. Dans ce constructeur, on définit bien plus qu’une fenêtre : on y définit aussi sel.Brain, le fichier qui va nous servir de référence pour les réponses. C’est lui qui contient les mots-clés (nous verrons plus loin sa structure).

Ajouter une méthode à la classe pour la question

def add_chat(self, message):
        self.message_position+=1.5
        self.Message_Entry.delete(0, 'end')
        self.message_session.config(state='normal')
        self.message_session.insert(self.message_position, message)
        self.message_session.see('end')
        self.message_session.config(state='disabled')

La ligne 2 spécifie que l’on ajoute 1.5 à la position de la ligne où l’on va afficher la question. La ligne 3 supprime la question que l’on a entrée dans le champs de saisie (sur fond blanc, en bas de la fenêtre). On configure l’objet message_session avec un état “normal” à la ligne 4 sans quoi nous ne voyons pas le message dans la partie verte. Ensuite, on insère la question (le message dans un cas général) à la ligne 5. La ligne 6 (la méthode see(‘end’)) permet de voir la dernière ligne, le dernier message, dans la fenêtre verte, quand cela déborde verticalement. Cela évite d’utiliser la barre de défilement vertical à chaque fois. La ligne 7 permet de configurer la fenêtre verte de sorte à ne pas pouvoir saisir de texte dans cette zone… car ce n’est pas son rôle !

Ajouter une méthode pour répondre

def reply_to_you(self, event=None):
        message = self.Message_Entry.get().lower()
        message = 'Vous: '+ message+'\n'
        close_match = get_close_matches(message, self.Brain.keys())
        if close_match:   
            reply = 'Bot: '+ self.Brain[close_match[0]][0] + '\n'
        else:
            reply = 'Bot: ' + 'Là... je ne vois pas mon gars !\n'
        self.add_chat(message)
        self.add_chat(reply)

On commence (ligne 2) par transformer le texte en minuscules. On définit ensuite (ligne 3) le message que l’on va afficher (on précède ce qui a été saisi par “Vous:”). Et c’est à la ligne 4 que tout se jour avec la fonction get_close_matches, qui retourne une liste des meilleurs résultats correspondant à une chaîne de caractères. Ici, on puise dans le dictionnaire créé dans le constructeur à partir du fichier json.

Le script final

import json
from difflib import get_close_matches
from tkinter import Tk, Label, Entry, Button, Text, Scrollbar,Frame

class Chatbot:
    def __init__(self, window):
        window.title('Mathweb Assitant')
        window.geometry('400x400')
        window.resizable(0,0)
        self.message_session = Text(window, bd=3, relief="flat", font=("Times", 10), undo=True, wrap="word")
        self.message_session.config(width=45, height=15,bg="#008a9c", fg="white", state='disabled')
        self.overscroll = Scrollbar(window, command=self.message_session.yview)
        self.overscroll.config(width=20)
        self.message_session["yscrollcommand"] = self.overscroll.set
        self.message_position = 1.5
        self.send_button = Button(window, text='Envoyer', fg='white', bg='#00813b',width=9,font=('Times', 12), relief ='flat', command = self.reply_to_you)
        self.Message_Entry = Entry(window, width=40, font=('Times', 12))
        self.Message_Entry.bind('<Return>', self.reply_to_you)
        self.message_session.place(x=20, y=20)
        self.overscroll.place(x=370, y=50)
        self.send_button.place(x=0, y=360)
        self.Message_Entry.place(x=135, y=365)
        self.Brain = json.load(open('mathweb.json',encoding='utf-8'))

    def add_chat(self, message):
        self.message_position+=1.5
        self.Message_Entry.delete(0, 'end')
        self.message_session.config(state='normal')
        self.message_session.insert(self.message_position, message)
        self.message_session.see('end')
        self.message_session.config(state='disabled')
        
    def reply_to_you(self, event=None):
        message = self.Message_Entry.get().lower()
        message = 'Vous: '+ message+'\n'
        close_match = get_close_matches(message, self.Brain.keys())
        if close_match:   
            reply = 'Bot: '+ self.Brain[close_match[0]][0] + '\n'
        else:
            reply = 'Bot: ' + 'Là... je ne vois pas mon gars !\n'
        self.add_chat(message)
        self.add_chat(reply)

root = Tk()
Chatbot(root)
root.mainloop()

Le fichier json du chatbot Python

Vous l’aurez compris, ce fichier ne contient qu’un dictionnaire. Ensuite, tout dépend de ce que vous voulez faire de votre chatbot. Il est donc de la forme:

{
"mot-clé 1" : [ " Une réponse au mot-clé 1"] ,
"mot-clé 2" : [ " Une réponse au mot-clé 2"] ,
...
}

Donc au final, on pourrait facilement se passer de la partie json, mais il est de coutume d’utiliser de tels formats pour des bots bien plus élaborés…

Conclusion

Ce genre de projet peut-être intéressant à faire pour des élèves de NSI.

Le résultat en vidéo

J’ai légèrement amélioré le code précédent pour arriver à cela:

vidéo de démonstration du chatbot Python

Les abonné.e.s. de mathweb.fr trouveront le fichier ainsi modifié et le fichier json dans un ZIP sur cette page.

Evariste_Galois1973

Laissez votre message

Supportscreen tag