📱

Get Our Mobile App

Take your business learning on the go!

Download on the App StoreGet it on Google Play

Cybersecurity, Python, & Threat Hunting w/Agentic AI (Full Course)

Josh Madakor11:52:55

Transcription

Alors, comme vous le savez, l'IA affecte le monde de manière assez significative. Euh, en particulier l'industrie technologique et surtout la cybersécurité. Nous sommes simplement capables de faire beaucoup plus avec beaucoup moins de nos jours. Et le résultat de cela, c'est que cela augmente la barre et augmente ensuite la barrière à l'entrée pour accéder à la cybersécurité, en particulier pour les futurs emplois. Vous devrez non seulement connaître ces choses de sécurité et comme le réseau personnel et tout ça, mais vous devrez savoir comment exploiter l'IA en plus de cela pour être efficace dans votre travail, être embauché et maintenir votre position pour les rôles futurs. Et ma mission est d'essayer d'aider tout le monde à garder une longueur d'avance autant que possible et à introduire des choses qui seront utiles pour vos futurs entretiens et vos futurs emplois et toutes ces choses.

Donc, ce cours, nous allons essentiellement construire une IA agentique de cybersécurité, comme un analyste SOC IA qui fait de la chasse aux menaces et peut agir et ce genre de choses. Mais pour ce faire, nous devons construire nos fondations. Euh, donc ce cours sera en trois parties. La première partie étant les bases de Python. Vous pouvez donc le faire, même si vous n'avez aucune expérience en programmation, comme tout le monde peut commencer à le faire.

Et ensuite, la deuxième partie du cours consistera à utiliser Python pour interagir avec l'API OpenAI, car cela sera fortement exploité lorsque nous construirons réellement l'agent dans la troisième partie du cours. Donc, après avoir terminé le cours, vous serez non seulement capable de construire une IA agentique comme un analyste SOC IA, mais vous aurez une très bonne compréhension du fonctionnement des API LLM et de la manière d'interagir avec elles. Et cela vous ouvrira un monde littéral de possibilités.

Une fois que vous saurez programmer et que vous comprendrez le fonctionnement des API et comment interagir avec l'API de ChatGPT, par exemple, vous pourrez faire beaucoup de choses. Et l'avenir de la cybersécurité inclura très probablement une sorte d'orchestration d'IA agentiques, comme l'orchestration d'analystes SOC IA. Une autre façon de le voir, et en suivant ce cours et en faisant tout, vous aurez une très bonne compréhension de la façon dont un agent IA pourrait penser et prendre des décisions et de la façon dont il interagit avec un modèle et tout ça.

Le but de ce cours n'est pas de pouvoir construire une IA agentique et de la vendre ou quelque chose comme ça, car ce que nous fabriquons est relativement simple. Il s'agit plutôt de vous aider à comprendre comment tout fonctionne et de vous donner une bonne base mentale et d'élargir votre esprit, essentiellement. Et ce cours a été initialement créé pour la communauté Cyber Range. C'est une longue série de nombreuses vidéos différentes et nous les avons simplement assemblées et mises sur YouTube.

Et éventuellement, vous arriverez à un point où vous aurez besoin d'accéder à la base de données de journaux organiques du Cyber Range, car beaucoup de trafic organique et d'attaques y sont placés. Et ensuite, nous utiliserons ce référentiel de journaux pour faire de la chasse aux menaces et ce genre de choses. Mais vous pourrez parcourir environ sept heures du cours et apprendre à utiliser l'API OpenAI et toutes ces choses avant même d'y arriver. Mais quand nous arriverons à ce point, vous aurez juste besoin d'accéder au Cyber Range pour utiliser les journaux.

Mais si vous le souhaitez, je peux vous fournir des exemples de journaux réels, mais je les fournirai en échantillons pour que vous puissiez les utiliser avec votre code. Mais je recommande quand même de rejoindre le Cyber Range. Euh, le support communautaire est tout simplement inégalé et c'est un environnement de très haute qualité avec des outils d'entreprise et une belle plateforme de production. C'est juste vraiment, vraiment bien. Et tous les liens et tout ce dont vous avez besoin et comme les signets et tout sont en bas, comme lorsque nous commencerons à interagir avec l'API OpenAI, vous devrez utiliser un code différent et je fournirai tout cela en bas dans quelques liens.

Et une petite note avant de commencer le cours, je vais vous donner une petite démonstration de l'agent en action, l'agent IA agentique de cybersécurité, et cela peut sembler un peu intimidant car il y a beaucoup de code et de choses, mais éventuellement quand nous aurons terminé le cours et appris tout ça, cela semblera beaucoup moins intimidant et aura beaucoup plus de sens. Mais lorsque vous regardez la démo, essayez simplement de la comprendre et de comprendre ce que je dis. Et bien sûr, si vous avez des questions, posez-les dans les commentaires. Je ferai de mon mieux pour y répondre. Mais encore une fois, je passe la plupart de mon temps dans la communauté et je consacre quelques heures par jour à répondre aux messages de la communauté.

Donc, si vous rejoignez le Cyber Range, au lieu de laisser des commentaires sur YouTube, laissez simplement un commentaire dans le Cyber Range et identifiez-moi et je répondrai certainement ou l'un des membres du personnel répondra. Ne vous stressez pas. Faites de votre mieux pour absorber les choses et progressez lentement et vous arriverez à la fin. Soyez juste constant. Oui. Bonne chance. Posez toutes les questions si vous êtes bloqué et nous vous verrons dans la prochaine vidéo.

Bonjour à tous, bienvenue au cours Agentic Cyber Security AI et Python. Euh, si vous ne le saviez pas déjà, l'IA agentique est juste une IA agent qui peut faire quelque chose puis prendre une sorte d'action par elle-même avec une intervention minimale ou nulle de la part des humains. Et si vous mélangez la cybersécurité à cela, vous obtenez une IA agentique de cybersécurité. Et alors vous pouvez imaginer des choses comme la remédiation automatique de quelque chose qu'elle a trouvé, comme peut-être isoler une machine virtuelle basée sur des journaux qu'elle a analysés, ou comme la remédiation d'une vulnérabilité, ou comme l'arrêt d'une VM, la notification de quelqu'un, l'IA peut réellement faire quelque chose au-delà d'une simple analyse.

Donc, dans ce cours, nous allons construire un agent qui peut faire ces choses. Et la réalité est qu'avec toute l'avancée de l'IA folle et de GPT et de toutes ces choses qui sortent de nos jours, elle devient vraiment, vraiment bonne et vous savez que les entreprises veulent minimiser et économiser autant d'argent que possible et gagner de l'argent et tout ça. Donc, bien sûr, elles essaieront d'automatiser autant qu'elles le peuvent et ce que cela signifie pour la cybersécurité, c'est certainement beaucoup de ces emplois d'analystes SOC de bas niveau, ce que vous connaissez maintenant comme ces emplois d'analystes SOC de niveau un, cela sera certainement automatisé à terme. Ce ne sera pas pour aujourd'hui ou même cette année, mais à mesure que les gens adoptent davantage l'IA, ces emplois d'entrée de gamme disparaîtront et cela créera d'autres postes qui exploiteront massivement les agents IA pour faire ces types d'opérations de cybersécurité.

Cela augmente la barre en cybersécurité. Vous pouvez y penser comme ça. Les emplois de bas niveau disparaîtront et il y aura d'autres emplois comme l'ingénierie des agents, l'orchestration du SOC, l'orchestration des agents, leur réglage fin et ce genre de choses. Donc, nous devons construire sur la fondation que nous avons déjà et apprendre ces nouvelles compétences liées à l'IA. Et la raison pour laquelle nous avons créé ce cours est que je veux simplement que les gens prennent de l'avance. Je ne veux pas que les emplois commencent à disparaître en 2027 ou quoi que ce soit, puis que les gens se disent "oh, je dois apprendre à gérer les agents de cybersécurité à ce moment-là". Il vaut mieux le faire maintenant.

Donc, nous allons en construire un à partir de zéro, puis nous apprendrons son fonctionnement interne et tout le reste. Donc, d'ici là, même maintenant, lorsque vous commencerez à passer des entretiens, ce sera vraiment, vraiment solide. En ce qui concerne votre CV et pendant l'entretien, ce dont vous pourrez parler sera vraiment, vraiment bien. Mais d'ici là, lorsque nous devrons commencer à utiliser ces applications SaaS entièrement développées qui utilisent des agents IA, vous aurez une très bonne idée et une bonne intuition de leur fonctionnement. Vous devriez donc être bien mieux loti que la personne moyenne qui ne fait rien à ce sujet pour l'instant.

Dans la prochaine vidéo, je vais vous montrer une démo de ce que nous allons construire. Je mettrai probablement à jour cette vidéo au fur et à mesure que nous développerons l'agent, mais en gros, c'est un agent analyste SOC IA. Il prendra une invite d'un utilisateur, décidera où rechercher les données, collectera et analysera les journaux, recherchera les menaces potentielles, générera un rapport, puis prendra une sorte d'action basée sur ses conclusions. Et vous verrez ce que je veux dire par le fait que les postes d'analystes SOC de niveau un disparaîtront à terme, car l'agent, s'il est correctement construit, fonctionne 3 à 500 fois plus vite qu'un humain.

Et la façon dont ce cours est structuré, il y aura peut-être trois sections principales. La première section concerne les bases de Python. Ce n'est pas vraiment lié à l'IA ou quoi que ce soit, mais nous utiliserons Python pas mal. Et je ne l'enseignerai pas dans le sens où je couvre simplement toute la théorie. Je vais le couvrir d'une manière qui vous aidera à comprendre les composants spécifiques de Python dont nous avons besoin lorsque nous construirons réellement l'agent.

Et la deuxième partie du cours, Python plus bases de l'IA, nous parlerons de la façon de combiner Python avec des outils d'IA et différentes API, comment utiliser Python et interagir avec l'API ChatGPT, et comment utiliser Python pour interagir avec notre espace de travail d'analyse de journaux et ce genre de choses, les blocs de construction de niveau supérieur pour construire l'agent IA. Et ensuite, la troisième partie du cours, nous allons tout assembler et construire notre propre analyste SOC IA intelligent qui peut réellement effectuer la chasse aux menaces et effectuer ces actions autonomes.

Et puis les exigences pour ce cours, à l'heure actuelle, tout le monde doit avoir son propre compte OpenAI. Ce n'est pas vraiment cher. Nous en parlerons plus tard, mais nous devons utiliser l'API ChatGPT. Donc, nous devons enregistrer ce compte. C'est relativement bon marché et c'est un peu comme payer à l'usage. La deuxième chose est que vous devez, ou plutôt je vous recommande vivement d'avoir terminé le cours d'opérations de sécurité à l'intérieur du Cyber Range, car il vous fournit cette base de chasse aux menaces et d'opérations de sécurité où nous examinons les journaux et apprenons à utiliser KQL et tout ça, car nous allons construire là-dessus.

Et puis la troisième chose dont vous avez besoin est l'accès au Cyber Range. La raison en est qu'il y a une tonne de trafic organique et de journaux à l'intérieur que nous allons utiliser pour construire notre agent. Donc, il est important d'avoir ces trois choses. Oui, bienvenue au cours. Nous vous verrons dans la prochaine vidéo.

Bienvenue et bienvenue à l'introduction à ChatGPT. Et je voulais juste faire cette vidéo rapidement au cas où des gens ne sauraient pas ce qu'est ChatGPT ou quelqu'un qui en a entendu parler ou peut-être que vous ne l'avez pas encore utilisé. Essentiellement, vous pouvez l'utiliser gratuitement. Je pense que vous devrez peut-être vous y inscrire pour pouvoir envoyer plus qu'un certain nombre de messages, mais vous pouvez vous y inscrire gratuitement et l'utiliser avec cette démo si vous le souhaitez, allez simplement sur chat2pb.com.

Mais la meilleure façon de penser à cela, c'est comme un extraterrestre super hyper intelligent avec lequel vous avez une conversation et qui connaît tout sur l'humanité. Essentiellement, ne l'utilisez pas comme Google. Vous pouvez lui dire des phrases complètes. Par exemple, donnez-moi une recette de gâteau aux carottes pour l'anniversaire de mon fils, ses parents sont allergiques au gluten. Je fais des fautes d'orthographe, mais ça n'a pas d'importance car il est vraiment intelligent. Farine sans gluten et ils sont hyper militants végétaliens. Ils aiment la couleur blanche quand il s'agit de nourriture. Vous pouvez dire des choses folles comme ça, toutes sortes de choses. Et il vous donnera une recette décente et probablement, surtout avec les dernières versions de GPT, cela finira par être assez bon si vous le cuisiniez.

Dites que c'est trop long, par exemple, vous pouvez dire quelque chose comme "ok, c'est trop d'ingrédients, peu importe" et ensuite il le simplifiera un peu pour vous. Vous pouvez changer la façon dont il communique avec vous, comme vous pouvez dire, même si vous apprenez l'anglais, ce n'est pas votre première langue, vous pouvez dire [renifle] comme "je suis ESL, je suis un apprenant d'anglais langue seconde, pouvez-vous utiliser un anglais un peu plus facile pour" et ensuite il le fera. Et vous pouvez dire, vous savez, "s'il vous plaît, mettez cela sous forme de tableau et rendez-le encore plus facile à comprendre" et il le fera.

Ceci s'appelle l'ingénierie des invites, où vous créez, oh au fait, la chose que vous envoyez à ChatGPT, ce message s'appelle une invite, et l'ingénierie des invites, c'est lorsque vous créez ce message que vous envoyez à GPT d'une certaine manière où il, vous savez, je ne veux pas dire qu'il incite, mais il amène GPT à vous répondre dans un certain format, par exemple, nos invites ont abouti à un anglais plus facile, une recette plus courte avec moins d'ingrédients et ensuite sous forme de tableau, essentiellement.

Donc, vous pouvez dire des choses comme "expliquez la photosynthèse en termes simples" ou "expliquez quelque chose d'une manière facile à comprendre". Expliquez comme si j'avais cinq ans, expliquez comment une bombe atomique fonctionne comme si j'avais 3 ans. Il dira quelque chose de ridicule. Je ne sais pas si un enfant de trois ans peut comprendre cela, mais vous comprenez l'idée, n'est-ce pas? Et si vous voulez faire quelque chose de vraiment, vraiment spécifique, comme si vous aviez une question sur la loi, vous pouvez dire quelque chose comme "Ok, maintenant vous êtes un avocat, spécialisé. Je fais des fautes d'orthographe, mais peu importe. Spécialisé dans, je ne sais pas si c'est une chose. Droit du logement dans l'État de Washington. Mon propriétaire ne répare pas la moisissure depuis des semaines. Quels RFC violent-ils? Vous pouvez faire quelque chose comme ça, n'est-ce pas?

Et il a un grand, grand modèle, un gros cerveau modèle qui a été entraîné sur à peu près tout sur Internet, essentiellement. Donc, il sait à peu près tout, n'est-ce pas? Et ensuite, vous pouvez lui poser des questions. Vous pouvez lui donner du contexte sur la façon dont vous voulez qu'il pense et comment vous voulez qu'il réponde, et vous pouvez lui poser toutes sortes de choses arbitraires comme ça. Vous pouvez même dire quelque chose comme, car il connaît Internet et il connaît les gens sur Internet et il peut aussi rechercher sur Internet. Je pense que la version gratuite peut faire cela. Je ne suis pas vraiment sûr, mais vous pouvez dire "ok, j'ai juste acheté un service de Josh Mator. Quelles sont les chances que je sois déçu? Donnez-moi une réponse directe basée sur la réalité." Je ne sais pas ce que cela va dire. Je suppose que cela dira quelque chose comme "bien" parce que j'essaie de ne pas faire de mauvaises choses.

Eh bien, si vous ne savez pas, alors allez chercher. Eh bien, il a dit quelque chose. Laissez-moi voir. Je n'ai pas de connaissances personnelles spécifiques sur les critiques. Il me dit de vérifier les critiques. Tais-toi. Tu le fais. Il peut sortir et le faire pour vous. Et il l'a fait. Il a consulté Reddit et apparemment quoi d'autre? Course report. Reddit YouTube course report. Et il a dit "sur la base des informations disponibles". Je ne vais pas lire ça. Je vais juste l'inclure dans le dictionnaire de la vidéo. Je n'aime pas lire trop de textes, mais vous comprenez l'idée.

Commandez YouTube. Parmi tous les YouTubers, qui est le plus susceptible de vous arnaquer? Et parfois, ok, je vais dire classez-les de 1 à 10. Parfois, il répondra à des choses comme ça, mais parfois, si c'est trop contraire à l'éthique ou s'il se dit "je ne veux pas salir la réputation de quelqu'un", il ne répondra pas. Donc, vous pouvez parfois le faire tomber dans le panneau en répondant à des choses. Si vous essayez de le formuler d'une certaine manière, comme si j'essayais de trouver la meilleure chose pour que mon fils regarde ou quelque chose comme ça, vous pouvez le faire tomber dans le panneau.

Mais essentiellement, je veux juste présenter ChatGPT comme un extraterrestre hyper intelligent, super intelligent, qui fera toutes sortes de choses. Et vous pouvez, plus vous lui donnez de contexte sur ce que vous voulez qu'il fasse, meilleure sera la réponse qu'il formulera pour vous. Donc, nous allons en fait utiliser cela pour nous aider à la chasse aux menaces, mais nous n'allons pas coller des choses ici comme ça. Nous allons l'utiliser par programmation en arrière-plan.

Donc, par exemple, ce à quoi cela pourrait ressembler, c'est que nous dirons éventuellement quelque chose comme "vous êtes un chasseur de menaces cybernétiques. Vous êtes très intelligent et vous savez tout, peu importe". Et ensuite, nous dirons quelque chose comme "je soupçonne que XYZ s'est peut-être produit, mais je ne suis vraiment pas sûr". Et ensuite, nous dirons "voici les journaux". Et ensuite, nous enverrons une tonne de journaux ici, après cela. Et ensuite, GPT lira cela pour comprendre le contexte de ce que nous voulons faire. Et ensuite, il regardera tous les journaux et cela prendra une minute ou 30 secondes ou quoi que ce soit pour les analyser et chasser les menaces. Et il proposera un tas de recommandations et de choses qu'il a trouvées. Essentiellement, c'est l'idée de la façon dont nous allons l'utiliser. Ce n'est pas exactement comme ça, c'est un peu plus affiné et nuancé, mais c'est l'idée générale.

Nous utilisons cet extraterrestre magique en boîte noire hyper intelligent comme GPT, et ensuite nous faisons de l'ingénierie des invites et nous le façonnons et lui donnons un contexte parfait, pas parfait, mais très bon, pour ce que nous voulons faire, puis nous prenons la sortie et faisons ensuite une sorte de remédiation actionnable avec elle, comme l'isolement de VM, etc. Donc, oui, c'est ChatGPT. Il y a beaucoup de choses qui entrent en jeu et il y a beaucoup de vidéos sur YouTube sur la façon de l'utiliser et tout ça. Mais je voulais juste donner cette brève introduction au cas où il y aurait des gens qui ne sauraient pas ce que c'est ou qui ne sauraient pas vraiment comment l'utiliser. Mais oui, nous vous verrons dans la prochaine vidéo.

Bienvenue à la démo de l'agent analyste SOC IA. Je vais juste vous montrer ce que c'est maintenant et vous donner une idée de ce que nous allons réellement construire. Il est probable qu'au moment où vous arriverez à cela, cette chose sera encore plus développée. Mais je vais juste vous montrer la fonctionnalité telle qu'elle est actuellement. Et encore une fois, ce cours est en fait conçu pour les personnes qui sont déjà dans le Cyber Range. Donc, je vais faire référence à des choses qu'elles devraient déjà connaître, mais je vais les expliquer au fur et à mesure.

Mais avant de lancer cela, je veux juste vous montrer quelque chose de très rapide pour que vous ayez un contexte ou une idée. Essentiellement, à l'intérieur du Cyber Range, il y a beaucoup de trafic et beaucoup de journaux organiques et de choses qui sont créées et il y a beaucoup de tables différentes où les différents journaux sont stockés. Par exemple, les journaux d'audit, c'est si vous mettez à jour un compte dans Azure Active Directory, comme si vous lui attribuez des autorisations, le supprimez ou quelque chose comme ça. Les activités Azure, c'est lorsque vous créez des machines virtuelles ou créez ou supprimez n'importe quel type de ressource dans le portail. Les journaux de connexion, c'est lorsque vous vous connectez réellement à Azure. Toutes ces activités connexes sont placées là. Le journal Syslog, c'est comme les serveurs Linux et ce genre de choses, comme les machines virtuelles Linux, les machines virtuelles Ubuntu, et il y a juste une tonne de tables différentes ici et elles sont toutes remplies de trafic organique réel d'utilisateurs. Il y a environ mille utilisateurs ici et une grande partie des machines virtuelles et des serveurs sont intentionnellement exposés à Internet. Donc, ils reçoivent beaucoup de trafic d'attaque organique de bots malveillants et de mauvais acteurs.

Donc, je veux juste vous donner une idée de ce qu'il y a en arrière-plan. Et les membres du Cyber Range, bien sûr, vous avez accès à tout cela et c'est ce que nous allons réellement utiliser pour construire notre agent. Donc, nous avons besoin d'une sorte de journaux pour faire de l'analyse. Donc, pour entrer directement dans la démonstration. Je ne vais pas expliquer tout ce code maintenant. Tout cela sera couvert éventuellement, mais je vais juste faire une démo rapide pour vous.

Donc, je vais exécuter ceci. Je vais juste dire "start debugging". Et vous obtenez un message en bas pour ce que vous voulez faire. Et au fait, cela peut être transformé en une interface utilisateur web, mais je l'utilise juste en ligne de commande pour l'instant pour simplifier. Donc, l'agent que nous construisons, il demande "analyste SOC à votre service, que souhaitez-vous faire?". Et vous pouvez dire quelque chose comme "j'ai vu aux informations hier qu'il y avait un nouvel utilitaire pour énumérer et collecter des informations sur les locataires Azure. Les locataires Azure, c'est juste notre environnement cloud. Nous sommes un peu inquiets que notre environnement puisse être compromis. Y a-t-il quelque chose dans la dernière journée environ que vous puissiez trouver, s'il vous plaît, aidez-moi rapidement."

L'idée est que vous lui donnez une sorte de phrase humaine comme celle-ci. Et ensuite, je vais juste mettre le code en pause et ensuite le parcourir. Je ne vais pas le laisser aller tout seul. Je vais juste le parcourir étape par étape afin que nous puissions voir lentement ce que fait l'agent IA. Donc, il regarde actuellement notre phrase en anglais et utilise ensuite le point de terminaison GPT pour décider des paramètres de recherche de journaux en fonction de la demande de l'utilisateur. Il essaie de déterminer dans quelles tables nous devons regarder.

Par exemple, devons-nous regarder dans les journaux d'audit ou dans les journaux d'opérations ou dans les journaux Syslog ou où devons-nous commencer notre recherche et il a terminé. Il a décidé qu'il devait regarder dans les journaux de connexion et il a donné une plage de temps des dernières 36 heures et il va regarder ces champs spécifiquement. Il a décidé de tout cela en fonction de votre saisie et de la justification. Vous pouvez lire la justification de sa décision "chasse aux menaces potentielles d'énumération de locataires Azure via les connexions cloud et les utilisations d'applications" et il dit que cette table, les journaux de connexion, montre XYZ bla bla bla. C'est pourquoi nous allons y regarder.

Donc, nous pouvons continuer à parcourir cela. Il a construit cette requête KQL. Si vous avez suivi le cours d'opérations de sécurité, cela aura beaucoup de sens pour vous. Mais je vais copier cela, par exemple. Maintenant, si je vais dans Log Analytics, c'est la requête qu'il a faite. Donc, si je recherche cela, cela devrait être comme les dernières 36 heures, mais ce n'est pas grave. Il trouvera un tas de journaux. Cela ressemble à ceci. Et ensuite, il utilisera ces journaux pour faire sa chasse aux menaces et son analyse. Il a retourné 1167 enregistrements de la requête. Il va construire des instructions d'invite de chasse aux menaces basées sur les journaux qu'il a trouvés. Il va sélectionner un modèle adéquat et approprié. Il va compter le nombre de jetons. Vous apprendrez ce que cela signifie lorsque nous entrerons dans le cours. Parce que tous les modèles ne peuvent pas gérer, vous savez, ils gèrent un nombre différent de jetons et de données, s'il y en a trop, nous devons utiliser un modèle différent potentiellement. L'agent a déterminé que la quantité de jetons était sûre. Elle est dans le budget pour GPT5.

Et ensuite, il va commencer la chasse aux menaces. Je vais juste appuyer sur continuer. Et c'est la partie qui est 3 à 500 fois plus rapide qu'un analyste SOC humain. Donc, je vais laisser cela aller. Je vais exécuter cette chasse aux menaces une fois de plus, mais pour un autre scénario différent. Mais cette fois, je vais juste le laisser aller jusqu'au bout pour que vous puissiez avoir une bonne idée de sa vitesse. Et pendant que cela se passe, au fait, les cours de Python, les fondamentaux, les blocs de construction, etc. Tous ces cours sont conçus pour nous aider à comprendre toutes les choses qui se trouvent ici. Et le but de tout cela est de donner à chacun une très bonne intuition de son fonctionnement. Et mon espoir est que vous pourrez construire là-dessus et étendre, étendre les fonctionnalités et ensuite être capable de faire votre propre chose.

Car si vous comprenez vraiment comment cela fonctionne et que vous êtes capable d'en parler lors des entretiens et de l'articuler dans votre profil et tout ça, vous serez bien en avance sur la personne moyenne qui a juste suivi Google Cybersecurity ou obtenu Security Plus ou quelque chose comme ça, ou même le diplôme de licence, une licence traditionnelle. Vous pourrez appliquer ce genre de chose au monde réel et en parler et cela aura l'air vraiment, vraiment bien. Donc, la chasse aux menaces se déroule en ce moment même. Cela prend généralement 1 à 2 minutes. Donc, c'est terminé. Je vais laisser cela continuer. Il a fallu environ une minute et demie et il a trouvé trois menaces potentielles. Donc, nous allons appuyer sur Entrée. Je ne sais pas ce que ce sera. Et ensuite, j'ai mis le code en pause à la toute dernière ligne. Donc, nous pouvons examiner ces menaces.

La première est une compromission probable de compte, une connexion réussie soutenue depuis le Kazakhstan avec un niveau de confiance élevé en reconnaissance de compte et elle explique ce qu'elle a trouvé dans le compte utilisateur réel de Cyra, un vrai compte, une vraie IP du Kazakhstan, et elle explique ce qu'elle a trouvé. Elle inclut le niveau de confiance, les informations sur les attaques MITRE, qui sont les tactiques, techniques et procédures, les lignes de journaux très spécifiques qu'elle a considérées comme des indicateurs de compromission. Elle a des indicateurs de compromission ici. C'est probablement un meilleur terme pour cela, ce sont probablement des entités malveillantes ou quelque chose comme ça, puis des balises et des recommandations, créer un incident, pivoter, surveiller et ensuite plus d'informations.

Puis la menace numéro deux, des connexions de compte Gmail externes au portail Azure depuis le Japon, vérifiez l'accès invité. C'est intéressant. Elle l'a classé comme moyen. Et c'est en fait moi parce que je suis au Japon en ce moment. Je ne suis pas à Fukuoka, mais le fournisseur d'accès Internet l'est probablement. Mais elle a juste remarqué quelque chose d'intéressant parce qu'elle sait que le locataire est un locataire de connexion Pacifique, mais elle a reconnu ma connexion depuis l'extérieur des États-Unis avec un compte non-lo Pacifique. Donc, elle l'a signalé comme moyen. Vous pouvez lire la description dans les IOC et tout ça si vous voulez.

Puis la dernière, une connexion inactive depuis une IP VPN d'hébergement avec plusieurs défis MFA puis succès. Donc, vous pouvez lire à ce sujet. C'était probablement quelque chose qu'elle a considéré comme inhabituel. Ce n'est probablement pas malveillant. Je devrais examiner cela plus en détail. Mais oui, elle a pu parcourir tout cela, créer ce rapport et tout comprendre en 2 minutes et demie. Et c'est beaucoup plus rapide qu'un humain, n'est-ce pas?

Donc, je vais laisser ce programme se terminer. Je vais le relancer sans débogage cette fois. Je vais juste le laisser s'exécuter jusqu'au bout. Et pour ma nouvelle invite, peut-être que je dirai quelque chose comme "je pense que du trafic malveillant a peut-être franchi le pare-feu aujourd'hui. Au moins, vous savez, les dernières 8 heures environ. Je ne suis pas vraiment sûr. Je pense à cela parce qu'un stagiaire a désactivé certaines règles de pare-feu. Je ne sais pas. Je suis juste en train d'inventer ça."

Donc, si je dis Entrée, cela prendra l'invite. Il décidera quels journaux rechercher, quelle table regarder et quels journaux extraire. Cela prend généralement quelques secondes. Il a décidé de regarder dans la table CL d'analyse des réseaux Azure. La justification, il a créé une requête. Il a retourné beaucoup d'enregistrements, puis en fait, il y a eu une erreur. Ceci est intégré au programme, donc c'est plutôt bien. Essentiellement, l'agent a vu que les jetons, la quantité de journaux retournés est trop importante pour être envoyée à l'agent ChatGPT en une seule fois, car les jetons estimés sont de 345k, où GPT5 ne peut gérer que 72 000, par exemple. Et normalement, j'intégrerais dans cette application ou dans l'agent "oh, si vous dépassez trop de jetons, dépassez ce que ce modèle peut gérer, peut-être utiliser un autre modèle". Nous pouvons intégrer cette fonctionnalité, mais au lieu de cela, je vais juste définir manuellement le modèle par défaut sur GPT 4.1, car je ne l'ai pas encore intégré.

Donc, nous allons juste exécuter cela. Nous allons le déboguer à nouveau. En fait, je vais prendre la même invite. Et ensuite, je vais simplement l'exécuter à nouveau sans débogage. Même chose, mais j'ai changé le modèle pour utiliser GPT 4.1. Et vous voyez à quelle vitesse GPT4.1 est comparé à GPD5. GPT4.1 est beaucoup plus rapide et peut prendre plus de jetons, mais je pense que son analyse est un peu plus lente car il faut du temps pour, vous savez, s'assurer de ses conclusions. C'est donc ce qui se passe en ce moment.

Donc, essentiellement, il a choisi cette table à examiner en fonction de mon invite concernant les règles de pare-feu désactivées, a choisi cette table, a créé ceci, c'est la requête KQL qu'il a créée. Donc, si nous copions cela, par exemple, nous allons dans Azure, nous pouvons rechercher cela et ce sont les journaux que nous allons réellement examiner, comme ce sont les journaux de pare-feu, la plupart des flux, l'IP de destination, le port source, la VM a autorisé les flux entrants, etc. Et il va analyser, prendre tout cela et voir ce qu'il peut comprendre.

GPT 4.1 a sélectionné, calculant les jetons 300K sur un maximum d'un million, donc c'est environ un tiers du maximum, et ensuite il a fallu seulement 40 secondes et il a trouvé trois menaces potentielles. Donc, nous pouvons appuyer sur Entrée et nous pouvons regarder les menaces qu'il a trouvées. C'était vraiment rapide, n'est-ce pas?

La première menace, mouvement latéral de masse et activité potentielle d'exfiltration de commande et de contrôle sur plusieurs VM. C'est probablement légitime, cela se produit dans le Cyber Range car il est conçu pour permettre ce type d'activité exactement pour ces scénarios où nous pouvons faire des chasses aux menaces avec. Il parle des informations sur les attaques MITRE, tactiques, techniques, journaux réels ou certains des journaux. Il y en a beaucoup. Il dit des centaines de lignes similaires. Comment il a découvert, comment il est arrivé à la conclusion que c'était une activité malveillante. Certaines des entités impliquées. Certaines balises. C2 signifie commande et contrôle, recommandations, etc.

Menace numéro deux, flux refusés inhabituels vers des IP publiques, tentatives de communication externe potentielles. Donc, il a trouvé beaucoup de flux sortants bloqués, probablement. Je ne suis pas sûr. Je ne vais pas tout lire. Vous pouvez le lire si vous voulez.

Et puis le troisième, niveau de confiance élevé, volume élevé de trafic SSH, RDP et de protocoles hérités répétés. C'est probablement légitime. C'est probablement soit des gens qui essaient d'attaquer en entrée, soit des choses qui ont été compromises à l'intérieur du Cyber Range et qui essaient d'attaquer en sortie. Je peux passer plus de temps à examiner cela si je veux. Celui-ci est probablement légitime.

Et puis éventuellement, c'est relativement trivial à faire par rapport au reste. Mais nous pouvons faire des choses comme mettre de la logique dans notre agent où, par exemple, si la requête de l'utilisateur concerne une machine virtuelle spécifique et qu'il y a eu des conclusions et que la confiance est élevée, alors nous pouvons créer une règle de pare-feu, isoler la machine virtuelle, l'arrêter, créer un rapport, toutes ces choses. C'est là que réside la partie agentique de l'IA agentique. Elle peut réellement agir en fonction de ce qu'elle a trouvé. Et c'est ce que nous allons construire et aborder. Et encore une fois, mon espoir est que les gens auront une idée de son fonctionnement et qu'ils pourront développer leurs propres actions personnalisées que leur agent IA peut faire. Mais oui, nous vous verrons dans la prochaine vidéo.

Bienvenue. Dans cette leçon, je veux juste parler de l'objectif du cours Python. Essentiellement, le but de ce cours est que je voulais juste vous aider à développer vos compétences suffisamment pour être capable de reconnaître ce que fait un code, puis potentiellement de l'augmenter et de le modifier pour qu'il fasse ce que vous voulez. Je n'essaie pas de transformer tout le monde en ingénieurs logiciels Google ou quoi que ce soit de ce genre. Je veux juste que vous développiez vos compétences en codage suffisamment pour pouvoir reconnaître les choses, puis comprendre la sortie que ChatGPT vous donne lorsque vous lui posez des questions, et ensuite vous pourrez apporter les modifications nécessaires à votre code.

Sans aucun doute, nous allons approfondir tout le code et je vais expliquer littéralement ce que fait chaque chose. Mais essentiellement, ce sont les niveaux de codage, à mon avis, que les gens peuvent atteindre. Comme le niveau zéro jusqu'à trois, c'est un peu ce que j'espère pour vous qui regardez ceci. Donc, le niveau zéro signifie juste pas de cours de codage, littéralement zéro connaissance. Imaginez votre grand-mère ou quelque chose comme ça, qui n'a absolument aucune idée.

Et puis le niveau un est la littératie du code. Vous pouvez lire et comprendre ce que fait le code de base. Vous pouvez le comprendre, peut-être juste en le regardant. Le niveau deux est la modification de code. Vous pouvez modifier un script existant pour répondre à vos besoins. Par exemple, peut-être que vous voulez utiliser le modèle GPT 5.0 au lieu de 4.1 ou GP5, je suppose qu'il s'appelle, au lieu de 4.1. Vous pouvez dire "ok, je l'ai trouvé. Je vais l'ajuster et le faire fonctionner."

Et puis le niveau trois est le codage de base où vous pouvez écrire du code relativement simple à partir de zéro et automatiser les tâches quotidiennes et vous n'avez pas à vous fier à GPT pour ces choses de base comme les boucles, les conditions et le contrôle de flux et ce genre de choses. Si vous pouvez atteindre le niveau trois à partir des leçons suivantes, c'est plus que suffisant pour faire, vous savez, quelque chose de décent et produire quelque chose de valeur, n'est-ce pas? Surtout en ce qui concerne les entretiens et la création d'un beau portfolio et tout ça.

Et plus votre codage est élevé, plus vous pourrez exploiter GPT. Donc, cela a du sens, n'est-ce pas? Quelqu'un qui a un niveau de codage zéro, il peut taper quelque chose dans GPT comme "créez une page web pour moi" et il la créera, n'est-ce pas? Mais la personne ne sait pas, elle ne sait pas comment l'étendre ou la modifier ou littéralement faire quoi que ce soit. Et plus vous descendez dans cette liste de compétences, jusqu'au niveau sept, plus GPT vous sera utile en termes de génération de code et de capacité à le modifier et à identifier quand GPT fait des erreurs.

Votre objectif est d'atteindre le niveau trois. Ne vous inquiétez pas, pendant que nous suivons les tutoriels et tout ça, ne vous sentez pas mal si vous vous dites "il n'y a aucun moyen que je puisse produire cela par moi-même". Ce n'est pas le but. Le but est au moins d'atteindre le niveau trois. Vous avez une compréhension de base. Vous pouvez écrire des choses de base par vous-même. Et ensuite, lorsque GPT produit quelque chose, vous avez au moins suffisamment de connaissances pour pouvoir l'identifier et poser les bonnes questions.

Et le codage, c'est essentiellement juste déplacer des données. C'est juste créer, lire, mettre à jour et supprimer ou se débarrasser des choses. Vous n'avez pas à y penser trop en profondeur. Il s'agit juste de déplacer des données pour faire ce que vous voulez faire d'un point de vue commercial ou, vous savez, quoi que ce soit que vous essayez de faire. Et je ne veux pas que vous vous stressiez et que vous essayiez de mémoriser la syntaxe et de mémoriser des choses. C'est une bonne façon de vous stresser. Et comme je ne mémorise rien, vous mémoriserez accidentellement des choses si vous le faites assez.

Mais le but est d'essayer de comprendre ce qui se passe et de comprendre la logique derrière le code, et j'essaierai de faire un très bon travail pour l'expliquer et pour parcourir le code et tout le reste. Donc, ne vous inquiétez pas trop. Concentrez-vous sur la compréhension et essayez de comprendre ce dont nous parlons. Et oui, personne ne sait tout, n'est-ce pas? Je ne sais presque rien, pour être honnête. Je suis assez à l'aise pour savoir que je peux trouver des solutions. Donc, j'espère juste que d'autres personnes pourront atteindre ce niveau.

Et vous vous sentirez probablement dépassé à un moment donné. Parce que c'est beaucoup. Mais ce n'est pas que plus vous pratiquez, plus vous devenez stupide. Cela n'a pas de sens, n'est-ce pas? Plus vous vous exposez avec intention, plus vous vous concentrez et plus vous passez de temps et d'efforts, plus vous vous améliorerez avec le temps. Et tout le monde a du mal avec le codage. Tout le monde le fait. Même moi, j'ai abandonné l'informatique la première fois que j'y étais. Mais je n'avais pas les outils et l'état d'esprit que j'ai aujourd'hui.

Donc, n'abandonnez pas et exploitez beaucoup le forum, la section communautaire. Exploitez ChatGPT et continuez d'essayer et vous en sortirez mieux. Vous en sortirez mieux. Et oui, enfin, je veux juste dire, exploitez énormément la communauté. Si vous êtes dans le Cyber Range ou la communauté cyber, allez dans la section communautaire et publiez des messages, et si vous voulez que je le voie, identifiez-moi simplement. Ne m'envoyez pas de message direct à propos du code. Je ne répondrai pas si vous m'envoyez un message direct à propos du code, car ce n'est pas évolutif et beaucoup de gens poseront des questions.

Donc, s'il vous plaît, utilisez la communauté, car lorsque vous le faites, cela vous donnera des points de réputation et cela donnera aux autres une chance de comprendre ce qui se passe et de répondre aux questions, car il y a cette composante de stage, n'est-ce pas? Si vous fournissez une aide technique ou une solution technique, vous pouvez obtenir des points pour cela si vous faites le stage. Donc, utilisez beaucoup la communauté. Ne m'envoyez pas de message direct à propos du code. Vous pouvez toujours m'envoyer un message direct, mais assurez-vous simplement qu'il s'agit de choses qui ne peuvent pas être répondues dans la communauté. C'est quelque chose de spécifique à moi.

Oui, j'espère arriver au point où je pourrai simplement aller dans la communauté et passer une longue période à répondre aux questions. Mais si ce n'est pas moi, quelqu'un d'autre y arrivera éventuellement. Mais oui, ne vous stressez pas. Rappelez-vous, nous visons juste le niveau trois et faites de votre mieux et continuez. Et nous vous verrons dans la prochaine leçon.

Bienvenue à la première vidéo où nous allons réellement faire des choses. Nous allons configurer notre environnement où nous allons faire tout notre développement Python et ce genre de choses. Et je vais faire cela sur un PC Windows car je pense que la plupart des gens ont Windows. Je ne suis pas sûr. Mais tout ce que nous faisons ici, vous pouvez le faire sur Mac également. C'est un processus assez similaire pour les choses où vous êtes bloqué, vous savez, utilisez Google, ChatGPT ou bien sûr, utilisez le forum de la communauté Cyber Range ou Cyber pour poser des questions. Mais je vais y aller directement.

Donc, la première chose que nous allons faire est d'installer Python. C'est comme un tout nouvel ordinateur, donc il va probablement me poser un tas de questions. Donc, ok. Donc, nous allons juste aller sur Google et nous pouvons, pas ce que je voulais, mais nous allons juste télécharger Python et un éditeur. Qui que ce soit qui édite ceci, coupez ça. Nous allons télécharger Python et vous pouvez juste, il devrait y avoir un bouton ici qui dit comme la dernière version. Allez-y et obtenez la dernière. Probablement pas de gros problèmes à l'avenir si la version change. Et nous allons juste ouvrir cela et ensuite attendre avant de cliquer sur tout et de l'installer.

Donc, nous allons cocher ceci, ajouter au chemin, puis cliquer sur ceci également. Et ensuite, dites simplement installer. Et nous allons juste le laisser. Quoi? Et nous allons fermer cela. Et ensuite, nous allons installer VS Code. Donc, allez sur Google à nouveau ou vous pouvez utiliser Bing si vous voulez. LBS code et ensuite je vais l'obtenir pour Windows. Si vous utilisez Mac, vous savez, si vous avez un Mac M1, eh bien, faites de votre mieux pour le découvrir. Je ne vais pas entrer dans les détails, mais si vous utilisez Windows, téléchargez simplement Windows et cela devrait se télécharger automatiquement. Je vais juste l'ouvrir quand ce sera fait. Je vais dire ok. Et ensuite, je vais couper le volume de mon système. Nous n'entendrons plus ça. Accepter. Et ensuite, installez simplement cela avec les paramètres par défaut, c'est bien. Et ensuite, créez une icône de bureau. Et ensuite, ajoutez ces choses également. Ce n'est pas la fin du monde si vous ne le faites pas, mais nous allons le laisser installer.

C'est notre environnement de développement. Donc, le programme dans lequel nous allons réellement écrire le code Python. C'est ce qu'est VS Code. Et nous pouvons dire "lancer VS Code". Bien sûr. Ensuite, nous pouvons fermer Internet, peu importe, Edge à ce stade. Et ensuite, VS Code s'ouvre. Et avant de faire quoi que ce soit, créons un dossier sur notre bureau. Nous l'appellerons code, un nouveau dossier et nous le renommerons en code. Donc, je vais juste nommer mon code et ensuite à l'intérieur de VS Code ici, maximiser cela et nous pouvons dire, nous pouvons soit dire "fichier" puis "ouvrir dossier" ou vous pouvez cliquer sur ces deux pages ici et dire "ouvrir dossier" ici et ensuite nous allons naviguer vers notre bureau, puis nous ouvrirons le dossier code, puis nous dirons "sélectionner dossier" et ensuite nous pouvons voir sur la gauche notre dossier est là. Juste, je fais confiance à cela si vous obtenez cette fenêtre contextuelle et ensuite nous voyons notre dossier code ici, mais il n'y a encore rien dedans.

Donc, la première chose que nous allons faire, nous allons installer quelques plugins. Nous allons installer le plugin Python en premier, ou extension, je suppose qu'elle s'appelle, qui nous permettra d'exécuter facilement du code Python à l'intérieur de VS Code. Donc, cliquez sur extensions, puis recherchez simplement Python, puis installez. Vous devriez voir, il devrait avoir 178 millions d'installations. Donc, cliquez simplement sur installer. Nous allons juste attendre un peu qu'il finisse. Je vais fermer cette chose, si vous l'avez ouverte. Cool. Donc, cette chose est installée, puis la prochaine extension, ouvrez simplement extensions si vous l'avez fermée et recherchez le mot "black" et ensuite il devrait y avoir un formateur "black" par Microsoft. Il devrait avoir ce badge et ensuite installez-le. Cette chose va nous permettre de...

capable de vous formater. Cela n'aura pas de sens pour l'instant, mais cela nous permettra de formater le code JSON d'une manière facilement lisible. Et euh, c'est vraiment très utile à avoir. Alors, allez-y et installez ce formateur noir. Et nous pouvons fermer ceci. Et euh, je vais juste fermer VS Code et le rouvrir juste pour que nous puissions voir. Alors fermez-le et puis ouvrez VS Code. Et alors vous voyez que notre dossier de code est déjà ouvert ici. Euh, s'il n'est pas là pour une raison quelconque, je vais juste fermer le mien. Donc je peux dire fermer le dossier. Et alors si vous voulez rouvrir ce dossier, vous juste, vous savez, encore une fois, vous pouvez aller dans fichier puis ouvrir le dossier ou ou utiliser ces deux pages et puis parcourir le bureau et puis parcourir le dossier de code et dire sélectionner. Et alors nous avons notre dossier de code ici. Mais il est vide. Euh, mais nous sommes prêts à faire des choses. Alors, à l'intérieur du dossier de code, nous allons créer euh un fichier de projet. Nous l'appellerons simplement main.py. Les fichiers Python se terminent par py, juste fy. Alors, nous allons écrire notre première ligne de code. Ce sera comme cette impression emblématique, vous savez, imprimer bonjour le monde. Alors, nous allons juste taper imprimer et puis copier ce que j'ai à l'écran comme parenthèses. D'accord. Quoi qu'il en soit. Permettez ceci. Je ne sais pas si vous allez voir ça, mais tapez juste ce que j'ai à l'écran. Et alors vous pouvez aller dans exécuter et puis exécuter sans débogage ou vous pouvez appuyer sur le bouton de lecture et puis choisir le débogueur Python. Et alors il ouvrira ce terminal en bas et le code s'exécutera. Et alors vous voyez qu'il dit bonjour le monde en bas. Et c'est tout ce qu'il y a pour celui-ci. Euh, je voulais juste mettre l'environnement en place et en marche. Si vous êtes capable de tout faire et de suivre et que vous êtes capable d'imprimer bonjour le monde et que tout semble bien, super. Nous pouvons passer au suivant. Euh, si vous êtes bloqué, allez-y et posez des questions dans la communauté, comme le forum, soit le cyber-range, soit la communauté cyber, je suppose, en fonction de l'endroit où vous regardez ceci. Et alors n'hésitez pas à me taguer là-dedans. Euh, ne m'envoyez pas de messages directs sur le code individuellement. Ce n'est pas évolutif, mais taguez-moi et alors quelqu'un s'en chargera probablement avant moi, mais s'ils ne le font pas, quelqu'un me le dira et je m'en occuperai. Oui, c'est la fin de cette leçon et nous nous verrons dans la prochaine. Bienvenue de retour. Dans cette vidéo, nous allons couvrir le débogage et le flux général de base du code euh en Python ou je suppose dans n'importe quel langage. Alors, euh, je vais y aller directement. Euh, je vais faire quelques messages supplémentaires euh ici juste pour que nous ayons comme du code à l'écran qui peut faire quelque chose. Euh, et d'ailleurs, euh tout ce que je fais ici, c'est juste vraiment basique et je vous montre juste euh comme les outils fondamentaux de comment les choses fonctionnent en Python et tout cela aura du sens et nous allons le lier à un contexte du monde réel euh quand nous commencerons à construire les composants et à construire l'agent IA sock et quand je pourrai, j'essaierai de donner des exemples du monde réel de la façon dont les choses sont utiles euh et comment elles sont utilisées dans la vie réelle ou quoi que ce soit. Mais euh parfois je ne pourrai pas. Je montre juste une fonctionnalité ou quelque chose comme ça. Alors, euh comme je l'ai dit dans cette vidéo, nous allons couvrir juste comme le flux de base du code et puis euh la capacité de déboguer. Alors, oh, et aussi avant que nous commencions vraiment, euh mon intention est que vous copiez ce que je fais et si j'ai besoin que vous obteniez un certain fichier pour faire quelque chose comme il y a trop de code à écrire ou vous savez que vous avez besoin d'un fichier, je vous le ferai savoir. Euh, mais sinon, n'hésitez pas à taper et puis juste comme vous savez taper le code vous-même. Mais d'accord, c'est notre fichier. Euh, nous avons notre fichier main.py. Si vous n'avez plus le fichier, vous savez, vous pouvez toujours rouvrir le dossier sur votre bureau, le dossier de code, et alors vous pouvez créer un nouveau fichier comme comme ça, comme, vous savez, main py quelque chose comme ça. Euh, je vais supprimer ceci cependant. D'accord, alors voici notre fichier main.py. Et si nous exécutons ceci tel quel, vous remarquerez qu'il imprime immédiatement tout à l'écran, n'est-ce pas ? Mais Python euh il exécutera séquentiellement comme il imprimera celui-ci et puis celui-ci et puis celui-ci et puis celui-ci et puis comme le programme se termine essentiellement. Alors si nous ne voulons pas qu'il traverse immédiatement tout le programme quand nous voulons inspecter des choses, euh cela devient vraiment utile plus tard. Nous pouvons définir ce qu'on appelle un point d'arrêt. Comme si vous placez votre souris sur le côté gauche de ceux-ci, c'est vraiment très important d'ailleurs. Euh, donc vous pouvez vous arrêter n'importe où. Donc ça s'appelle s'arrêter. Alors je vais aller et m'arrêter à la ligne un. Et alors vous remarquerez si vous cliquez sur lecture, il s'exécute simplement. Il s'exécute de toute façon. Et si vous cliquez sur exécuter et que vous dites exécuter sans débogage, il s'exécutera comme d'habitude de toute façon. Mais si vous voulez que le code s'arrête ici, vous pouvez dire exécuter et puis démarrer le débogage et puis fichier Python. Et alors vous remarquerez cette chose jaune qui met en surbrillance la première ligne où nous avons mis notre point d'arrêt. C'est là que l'interpréteur, je suppose que vous pouvez y penser comme ça. Euh, où il s'arrêtera l'exécution et alors vous avez la possibilité de euh pas à pas et pas à pas. Je parlerai de ce que tout cela signifie plus tard, mais pour l'instant, utilisons pas à pas. Alors si vous cliquez sur l'interpréteur ici, n'est-ce pas ? Il est sur le point d'exécuter cette ligne de code. C'est ce que signifie cette chose jaune. Alors si vous passez à l'étape suivante, vous remarquerez bonjour le monde un s'imprime et puis il passe à la ligne suivante et ainsi de suite comme ça. Et alors et alors il se termine, n'est-ce pas ? C'est à peu près tout ce qu'il y a. Euh, c'est à peu près tout ce que je voulais montrer. Et c'est vraiment surprenant parce que quand votre code commence à devenir plus complexe, vous avez vraiment besoin de pouvoir le déboguer et observer ce qui se passe pour avoir une compréhension et une intuition. Et j'ai vu des gens aller à mi-chemin du programme de licence en informatique et ensuite ne pas savoir que vous pouvez déboguer votre code, ce qui est vraiment insensé pour moi. Alors habituez-vous à déboguer des choses tout le temps pour que nous puissions observer et inspecter de près ce que fait le code. Et je vais vous montrer quelque chose de vraiment rapide ici. Euh, nous en parlerons plus en détail plus tard, mais il y a des décisions que Python peut prendre. Alors par exemple euh si vous savez que 10 est supérieur à neuf, imprimez chat et je ferai une autre chose si vous savez que un est ou si zéro est supérieur à un, imprimez chien. Alors intuitivement euh et je mettrai un à la fin, imprimez. Alors intuitivement, vous pouvez penser dans votre tête si 10 est supérieur à 9, peut-être qu'il imprimera chat. Si zéro est supérieur à un, peut-être qu'il imprimera chien. Euh, alors au lieu de juste courir tout ça, nous pouvons nous arrêter et alors nous pouvons observer le code comme il s'exécute et prend des décisions sur les choses. Alors je vais m'arrêter ici à la ligne un. Et alors je vais exécuter et démarrer le débogage. Et alors nous pouvons observer les choses lentement. Alors nous pouvons voir comme ça. Et nous pouvons voir qu'il imprime des choses en bas. Et alors il arrive à ce point. Si 10 est supérieur à 9, imprimez chat. Alors est-ce que 10 est supérieur à 9 ? Dans votre tête, vous pourriez penser oui. Alors il semble que chat s'imprime. Et alors il passe à l'instruction suivante. Et alors si 0 est supérieur à un, imprimez chien. Est-ce que zéro est supérieur à un ? Ce n'est pas le cas. Alors nous pouvons observer l'interpréteur sauter ceci parce que cette condition n'a pas été remplie et alors il passe à la dernière ligne et alors nous pouvons passer à l'étape suivante et alors il se termine. Euh, oui, c'est le débogage et le flux du code en Python. Euh, bien sûr, cela deviendra beaucoup plus complexe, mais je voulais juste vous présenter le débogage et vous le graver dans le cerveau que vous devez toujours l'utiliser et nous nous verrons dans la prochaine vidéo. Cool. Bienvenue de retour. Euh, dans celle-ci, nous allons couvrir les variables et je ne sais pas si vous avez déjà pris de l'algèbre ou quelque chose comme ça où vous traitez des choses comme vous savez que x est égal à quelque chose comme ça, mais c'est un peu similaire dans ce sens où euh vous aurez un nom de variable quelque chose et alors vous pouvez lui assigner une valeur comme ça. Alors si vous voyez quelque chose comme ça, cela ne signifie pas que cela ne signifie pas que x est égal à 7 exactement. Si vous voyez un seul signe égal, cela signifie que tout ce qui se trouve de ce côté du signe égal sera mis dans tout ce qui se trouve de ce côté du signe égal. Alors par exemple, nous disons imprimer et alors disons juste x. Je vais arrêter ceci ici. Alors arrêtez votre code ici et nous dirons exécuter et démarrer le débogage. Et c'est important. Alors quand le code est en cours de débogage, comme quand vous avez cette chose jaune qui met en surbrillance et que c'est en mode débogage, vous pouvez aller à cette chose de bug avec un bouton de lecture. Et alors par exemple, si je passe à l'étape suivante, vous verrez que x est maintenant égal à 7 ou plutôt x a la valeur sept. Alors si nous imprimons x, vous pourriez vous attendre à ce que sept soit imprimé et il l'est par exemple. Alors c'est à peu près tout ce qu'il y a. C'est juste que je voulais juste dire que vous pouvez avoir des variables et alors vous pouvez leur assigner des valeurs. Et les meilleures pratiques en programmation en général consistent à créer des noms de variables qui ont vraiment du sens, même si c'est long. Alors, par exemple, je pourrais avoir une variable comme vous savez, c'est vraiment artificiel, mais vous savez mon nom de famille complet et alors c'est ce qu'on appelle une chaîne de caractères dont nous parlerons bientôt. C'est juste une collection de caractères aléatoires. Alors mon nom de famille complet Namdi Joshua Mator et alors je peux faire quelque chose comme imprimer mon nom de famille complet. D'ailleurs, vous pouvez taper comme vous savez tant que les lettres sont en séquence. Alors par exemple, je peux taper mon MF fn comme quelque chose comme ça et appuyer sur tabulation et alors il complétera automatiquement la variable. Alors je peux faire ceci et alors si j'exécute ceci, alors je peux l'arrêter ici et alors je peux continuer ou passer à l'étape suivante et alors il imprimera mon nom de famille complet. Et vous pouvez aussi mettre des nombres dans des variables bien sûr. Alors je peux dire comme mon âge réel comme quelque chose comme ça. Je peux faire comme ça. Oh, zut. Mon âge réel. Et alors je vais juste exécuter ceci sans débogage. Vous comprenez l'idée du débogage. Oh, zut. Je l'ai débogué de toute façon. Désolé. Continuez juste. Et vous verrez qu'il imprime NAMD Joshua Mator et alors il imprime 40. Et alors nous allons entrer dans ceci euh oh euh laissez-moi vous montrer autre chose aussi. Vous pouvez faire comme par exemple euh mon a par exemple mon mon âge je peux créer une variable appelée mon âge et la définir à 40. Ensuite, je peux dire votre âge je peux le définir à 30. Et alors je peux faire quelque chose comme notre âge combiné égal mon âge plus votre âge comme ça. Et alors je peux faire ceci notre âge combiné. Zut. Notre âge combiné comme ça. Et alors je vais arrêter ceci ici. Et alors je dirai exécuter et alors démarrer le débogage. Et alors essentiellement ce qui se passe euh rappelez-vous de cette chose que j'ai dite plus tôt s'il y a un seul signe égal comme ce qui est du côté droit sera assigné à ce qui est du côté gauche. Alors tout ce qui est ici sera évalué et alors il sera mis ici essentiellement. Alors nous voyons sur la gauche, nous sommes sur l'écran de débogage, n'est-ce pas, notre code est en cours de débogage. Vous pouvez voir cette chose est mise en surbrillance. Mon âge est 40, votre âge est 30. Si nous passons à l'étape suivante, ce calcul se produira. Et alors maintenant nous avons une nouvelle variable comme notre âge est 70, qui est ici ou notre âge combiné. Et alors si nous continuons ce programme, vous voyez qu'il est imprimé à l'écran comme ça. Et bien sûr, cela deviendra plus compliqué avec le temps. Euh, mais je voulais juste vous montrer ce qu'est une variable et quelques cas d'utilisation généraux. quand nous commencerons à créer le modèle IA réel et des choses comme ça, nous pourrions avoir quelque chose qui ressemble à ceci, je ne veux pas rendre cela trop compliqué pour vous, mais nous aurons beaucoup de choses qui sont fixes et qui ne changent pas et qui ont plus de sens dans une variable. Alors par exemple, nous pourrions avoir un exemple de modèle par défaut, par exemple, modèle chat GPT et alors peut-être pour notre modèle par défaut, nous voulons utiliser comme GPT5 qui est tout nouveau, vous savez, ou techniquement ou vous savez GPD 4.1 ou quelque chose comme ça et alors plus tard quand nous ferons quelque chose avec notre modèle, nous pouvons juste référencer cette variable au lieu de taper une chaîne de caractères ou quelque chose comme modèle tangent par défaut. Si nous imprimons ceci, bien sûr, cela imprimera GPD5. Oui, ce sont les variables. Euh, c'est juste quelque chose qui peut stocker la valeur de quelque chose d'autre. Et vous pouvez faire des calculs. Nous allons juste faire une dernière chose. Vous pouvez faire des choses comme ça. Ils stockent la valeur. Vous pouvez calculer des choses, etc. voir que ceci a été imprimé et alors vous pouvez les utiliser ailleurs dans votre code. Et cela deviendra bien sûr beaucoup plus intuitif quand nous commencerons réellement à faire des choses avec et alors à faire plus d'exemples. Mais oui, ce sont les variables. Et nous nous verrons dans la prochaine leçon. Bienvenue de retour. Euh, dans cette leçon, je vais parler des types ou des types de données, ce qui est plus communément appelé types de données. Et essentiellement euh c'est juste les différents euh je ne sais pas comment dire le format différent ou comme ce qu'est quelque chose. Alors par exemple, je pense que ce sont en fait tous des types de données différents. Ceci est techniquement une chaîne de caractères même si c'est 20. Euh, ceci est un entier et alors ceci est un flottant je crois parce qu'il a une période même si ce sont tous 20. N'est-ce pas ? Alors si j'essaie de faire quelque chose comme âge combiné égal âge1 non je ferai âge2 + âge3 et alors j'essaierai d'imprimer âge combiné. Nous pouvons voir ce qui se passe. Je vais définir un point d'arrêt ici. Je vais exécuter ce débogage et alors nous pouvons passer à l'étape suivante et nous pouvons voir nos trois variables. H1 est 20.0 est 20 et alors ceci est aussi 20. Et nous essayons de combiner 20 + 20. H2 est 20. H3 est aussi 20. Et alors ceux-ci devraient, il est censé les additionner et alors les assigner à l'âge combiné, ce qui intuitivement devrait être 40. Et alors il devrait imprimer. Mais si nous essayons de passer à l'étape suivante, il dit comme il ne peut pas le faire parce que nous essayons d'ajouter ce qui est considéré comme une chaîne de caractères et ensuite un nombre. Comme pour nous, regarder ceci a du sens intuitif, mais pour l'ordinateur, c'est littéralement la même chose que de dire comme d'accord, faisons comme chat + 20 ou comme Inde + 5 ou quelque chose comme ça, ça n'a pas de sens, n'est-ce pas, d'ajouter ce qui est considéré comme une chaîne de caractères et un entier ou un nombre et d'ailleurs une chaîne de caractères est juste comme n'importe quels caractères arbitraires qui sont entourés de guillemets, cela pourrait être un guillemet double ou un guillemet simple, mais vous pouvez forcer par exemple, vous pouvez forcer ceci à devenir un nombre. Euh, si vous faites quelque chose comme ça, science ou codage ou quoi que ce soit, cela s'appelle le transtypage. Alors je vais transtyper ceci en un entier. Alors nous devrions avoir deux entiers et alors nous devrions être capables de les additionner. Alors je vais juste exécuter ceci, vous savez, sans débogage. Cela devrait juste imprimer 40 parce que 20 + 20 est assigné à ceci et alors ceci imprimera 40 comme ça. Et je vais le déboguer, je vais le déboguer pour que vous puissiez le voir en direct et nous pouvons voir qu'il s'est arrêté ici. Nous pouvons voir nos trois variables. Nous passons à l'étape suivante. Nous voyons que l'âge combiné est maintenant 40. Et alors si nous l'imprimons, il imprime 40. Et vous pouvez aussi voir quel est le type de quelque chose. Alors par exemple, vous pouvez voir si c'est comme un flottant ou un entier ou quoi que ce soit. Exemple, si vous imprimez le type et que vous mettez la chose à l'intérieur dont vous voulez connaître le type. Alors par exemple, H1, H2, H3, comme ça. Je vais peut-être arrêter ceci ici. Et nous allons déboguer. Il s'arrête ici. Alors H1, nous allons imprimer ceci. Il imprime un flottant parce que c'est comme un nombre avec une décimale. Même si c'est zéro, c'est toujours un flottant à cause de la décimale. La chose suivante est une chaîne de caractères parce qu'elle est entourée de guillemets. La chose suivante est un entier. comme ça parce que c'est un nombre plat. Je ne sais pas comment dire ça, un nombre non décimal. Et nous pouvons faire quelque chose comme ça. Nous n'avons pas encore appris cela, mais cette chose s'appelle une liste où vous pouvez avoir comme un regroupement d'éléments. Ils n'ont pas à être similaires. Ils peuvent être comme n'importe quel type d'élément. Alors par exemple, ceci est comme un groupe de nombres de 1 à 7. Ceci est un groupe de euh, laissez-moi imprimer le type de ceci, c'est ce que je veux faire. Nous apprendrons les listes plus tard, alors ne vous inquiétez pas trop, mais je veux juste vous montrer. Alors, je vais mettre une liste ici, et alors je vais mettre une autre liste dans celle-ci, et je vais mettre comme âge un, âge deux, et âge trois. Alors nous allons imprimer ceci et alors nous pouvons terminer la leçon, démarrer le débogage et juste essayer de penser à ce que cela va imprimer, comme quel est le type de âge un, cela ressemble à un flottant et il imprime flottant. Quel est le type de âge deux ? Ceci est une chaîne de caractères. Quel est le type de âge trois et ceci [renifle] devrait être un entier. Et alors quel est ce type ? Ceci est une liste, une liste d'entiers. Ceci est une liste de choses aléatoires. Rappelez-vous, ceci est comme un flottant, ceci est une chaîne de caractères, ceci est un entier. Mais dans l'ensemble, c'est toujours une liste et les deux dernières choses sont des listes. Et cela semble vraiment arbitraire et je promets qu'il y a un cas d'utilisation pour cela. Euh, parce que le type compte. Euh, cela compte beaucoup plus quand vous commencez à faire des choses complexes. Et je veux juste vous le montrer. Alors je peux un peu préparer votre cerveau pour quand nous commencerons à regarder des choses plus compliquées. Euh, cela semble un peu ambigu pour l'instant, mais cela aura du sens plus tard et ce sera beaucoup plus facile à interpréter et à comprendre quand nous commencerons réellement à faire et à construire des choses. Mais oui, ce sont les types de données. Je voulais juste passer rapidement en revue cela et nous nous verrons dans la prochaine leçon. Bienvenue de retour. Euh, dans cette leçon, nous allons couvrir l'entrée et la sortie. Euh, nous avons déjà couvert une version de la sortie qui consiste simplement à imprimer des choses à l'écran, mais dans celle-ci, nous allons couvrir en fait la prise d'entrée de l'utilisateur, comme de la ligne de commande. Alors par exemple, nous pouvons dire quelque chose comme euh je vais juste imprimer un message de bienvenue. Bienvenue dans notre programme et alors nous pouvons dire euh prénom. Ensuite, nous pouvons dire comme c'est ainsi que vous obtenez l'entrée de l'utilisateur. Cela aura du sens dans un instant. Je peux dire euh s'il vous plaît, entrez votre prénom et alors juste vous pouvez me suivre. Alors, et alors la barre oblique inverse n signifie euh cela signifie juste nouvelle ligne en Python. Vous verrez ce que cela signifie dans une seconde. Et alors nous pouvons dire, vous savez, nom de famille. Ceci est ceci est une variable. Et alors ceci est comme une fonction pour obtenir l'entrée de l'utilisateur. Mais nous verrons à quoi cela ressemble dans une seconde. Alors, nous allons faire ceci. Vous pouvez deviner ce que nous allons mettre ici. S'il vous plaît, entrez votre nom de famille. Alors, et alors je vais dire imprimer bonjour et alors faire une virgule et un espace et alors après cette citation, faire un espace plus et alors nous dirons prénom espace ou faire un plus et alors juste copier ce que je fais, virgule espace et alors un autre plus et nom de famille comme ça et alors nous allons tout arrêter ceci. Euh, je ne vais pas l'arrêter. Je vais juste l'exécuter d'abord. Alors, je vais juste exécuter ceci tel quel. Et vous pouvez voir en bas qu'il a imprimé bienvenue dans notre programme. S'il vous plaît, entrez votre prénom. Et alors vous voyez que cette chose est passée à la ligne suivante. Et alors nous pouvons cliquer ici en bas et alors mettre votre nom. Dire entrer. S'il vous plaît, entrez votre nom de famille Mator. Je dirai entrer. Et alors il a imprimé bonjour Josh, oh, ce n'était pas nécessaire cette virgule. Mais vous pouvez voir qu'il dit bonjour, Josh, Mator. Alors en fait, je peux supprimer cette virgule d'ici et je vais resauvegarder ceci. Et alors je vais aller et arrêter ceci et je vais exécuter et dire déboguer. Et alors vous voyez qu'il s'arrête ici et alors je vais passer à l'étape suivante. Bienvenue dans notre programme. Et alors il s'arrêtera ici. Et alors essentiellement cette chose d'entrée met la chose sur la ligne de commande qu'elle dira ceci et alors tout ce que nous tapons et que nous appuyons sur entrée, cela sera stocké dans cette variable. Alors si nous passons à l'étape suivante, vous voyez qu'il dit s'il vous plaît, entrez votre prénom. Je vais juste mettre Josh et dire entrer. Et vous pouvez voir que la ligne suivante s'est cassée mais sur ou elle s'arrête d'exécuter sur la ligne suivante. Mais nous voyons ici comme la valeur, la valeur de chaîne Josh a été assignée à prénom. La même chose se produira ici. Entrez votre nom de famille Mator avec un A majuscule par accident. Maintenant, nous voyons nom de famille est ici dans le débogage, par ailleurs. C'est ce que c'est. Et alors nous pouvons juste continuer à exécuter le programme et je vais vous montrer euh je vais juste euh je vais changer ceci euh non je vais juste le laisser tel quel et je vais vous montrer quelque chose d'intéressant. Alors euh je vais déboguer ceci encore et l'arrêter ici. Bienvenue dans notre programme. S'il vous plaît, entrez votre prénom. Je vais passer à l'étape suivante. Je vais mettre euh Bob. Dire entrer et alors nom de famille, je vais passer à l'étape suivante, je vais mettre je vais juste mettre comme Mator et alors vous voyez ici sur la gauche dans la fenêtre de débogage cette chose, vous pouvez voir les variables ici en fait et alors vous pouvez en fait modifier les variables en direct si vous avez une raison de le faire comme si vous testez quelque chose. Alors même si j'ai tapé Bob, je peux le modifier, je peux le changer en vous savez Josh entrer et il a changé. Maintenant, quand je passe à l'étape suivante de la dernière ligne de code, il imprime bonjour Josh Matachor au lieu de Bob Mator. Mais oui, c'est obtenir l'entrée de la ligne de commande. Et la façon dont cela est utilisé dans notre IA sémantique comme l'analyste IA sock que nous allons faire, il y aura quelque chose là-dedans qui dit quelque chose comme vous savez euh quelles sont vos préoccupations de sécurité euh quelles sont vos préoccupations de sécurité avec l'environnement ou comme ou juste comme ce que vous voulez faire par exemple et alors l'utilisateur invite et ce n'est pas exactement, mais c'est ce qui est envoyé à chat GPT en quelque sorte euh aussi une partie de l'invite. Alors par exemple, comme dans le vrai analyste IA sock que nous construisons, par exemple, bienvenue dans notre programme, quelles sont vos préoccupations de sécurité ? Que voulez-vous faire ? Et alors remarquez comment je n'ai pas mis de barre oblique inverse n ici et maintenant le curseur est comme ici au lieu d'être en bas. Mais je peux dire comme euh je pense que quelqu'un a piraté l'un des ordinateurs VM nommé Windows cible un. Oh, j'ai fait une erreur. Cible un comme ça. Et alors ceci est une simplification excessive, mais cette invite serait alors envoyée à GPT et alors une analyse serait effectuée dessus et alors une chasse aux menaces s'ensuivrait essentiellement. Euh, mais c'est comme cela qu'il est utilisé. Il est juste utilisé pour prendre l'entrée de l'utilisateur quand nous essayons de faire quelque chose. Euh, mais oui, j'espère que cela a du sens. Euh, c'est l'entrée. Euh, comme toujours, vous pouvez toujours poser des questions dans comme la communauté Cyber Cyber, comme la section communauté. Ne m'envoyez pas de messages directs, mais posez des questions là-bas et n'hésitez pas à me taguer. Et nous nous verrons dans la prochaine leçon. Bienvenue de retour. Cette leçon est super simple. Nous allons couvrir les commentaires. Euh, un commentaire est juste essentiellement quelque chose dans le code que l'interpréteur ignorera et c'est juste pour que les humains regardent et lisent juste pour qu'ils sachent ce qui se passe. Et il y a deux façons de faire des commentaires. Vous pouvez faire comme une seule marque de hachage comme ceci et alors taper ce que vous voulez. Alors je peux dire comme un accueil de l'utilisateur au programme au lancement. Et alors pour celui-ci, je dirais comme vous savez collecter des informations sur ce que l'utilisateur veut faire. Et alors ce serait comme dire à l'utilisateur que dire à l'utilisateur ce qui sera envoyé à chat GPD quelque chose comme ça. Euh, c'est juste pour décrire ce qui se passe dans le code. Et bien sûr, si quelque chose est trop facile, comme peut-être vous n'avez pas besoin de le commenter, n'est-ce pas ? Alors, par exemple, comme quelque chose comme ceci, vous savez, vous ne feriez pas comme imprime le mot chat parce que ceci est déjà comme ceci est déjà trop explicite et c'est en fait plus de caractères que le code réel. Alors, comme ce n'est pas quelque chose que vous devez commenter et que souvent le code sera plus compliqué. il y aura un gros morceau ou un gros bloc de quelque chose que vous savez, peut-être a besoin d'une explication ou peut-être que vous utilisez une sorte d'API où vous mettriez comme euh vous mettez comme plus d'informations à euh vous savez euh quoi que ce soit euh vous savez quoi que ce soit openai.com référence API comment euh xyz donc un futur développeur peut voir ceci dans le futur et alors dire oh d'accord et aller là-bas. Mais c'est essentiellement juste des commentaires, vous savez, pour que d'autres humains sachent ce qui se passe. Et il y a deux types de commentaires. Il y a juste comme un seul hashtag et alors il y a l'autre type qui est comme par exemple comme ceci. Vous pouvez faire trois guillemets simples comme ça et alors tout ce que vous mettez à l'intérieur devient des commentaires. Ceci est techniquement une chaîne de caractères, mais vous pouvez l'utiliser comme commentaire à l'intérieur de Python comme ça. Zut. Comme ça. Et je crois que vous pouvez arrêter ces types de commentaires, mais vous ne pouvez pas arrêter ceux-ci ou vous ne pouvez pas euh si par exemple si vous mettez un point d'arrêt et que je dis démarrer le débogage, le programme s'exécutera simplement jusqu'au bout. Euh, il s'arrête juste ici. Même je n'ai pas mis de point d'arrêt là. Je clique ici. Désolé. Il ne s'exécutera pas jusqu'au bout. Il essaiera juste de s'arrêter ailleurs. comme il ne s'arrêtera pas sur le commentaire où j'ai mis comme le point rouge si cela a du sens. Alors par exemple, si j'efface juste tout ceci et que je fais quelque chose comme ça et que j'essaie de l'arrêter, le programme ne s'arrête pas. Le programme s'exécute simplement jusqu'au bout comme ça. Mais si je fais le commentaire avec trois guillemets, il le fera, vous pouvez vous arrêter sur ceci. Ce n'est pas super important. Euh, mais je crois que ceux-ci s'arrêteront. Alors si j'exécute ceci et que je débogue, oui, voyez, il s'arrête comme ça. Oui, ce sont les commentaires. Euh, c'est juste une façon de laisser savoir aux autres humains ce qui se passe dans votre code et juste essayer de prendre l'habitude de les utiliser, pas seulement pour les autres développeurs, mais aussi pour vous-même. Surtout quand vous êtes nouveau et que les gens ont tendance à écrire du code un peu ambigu et que vous pourriez avoir besoin de vous le rappeler à l'avenir, surtout quand vous avez trouvé comment faire quelque chose de très compliqué. Je mettrai comme oui, je mettrai des URL dans mes commentaires parfois. Mais oui, ce sont les commentaires. [renifle] Euh, assez simple. Euh, nous nous verrons dans la prochaine vidéo. Bienvenue de retour. Euh, dans cette vidéo, nous allons couvrir les instructions if. Euh, cela va devenir un peu plus difficile ici. Euh, c'est ainsi que vous contrôlez le flux de votre code en fonction de si quelque chose a une certaine valeur ou quelque chose comme ça. Euh, cela aura beaucoup plus de sens quand nous commencerons à faire le code. Mais essentiellement euh je vais juste faire quelque chose de très très basique. Je vais dire comme mon âge égal vous savez 17 ou quelque chose. Votre âge égal euh 40 ou 55. Ensuite, nous dirons quelque chose comme euh si nous ignorerons en fait, nous ignorerons ceci pour l'instant. Je dirai si mon âge est supérieur à 18, nous allons imprimer bienvenue au club. Et alors je vais juste aller très loin ici et je dirai imprimer terminé juste pour montrer que notre programme est terminé. Alors je vais définir un point d'arrêt ici et alors je vais déboguer ceci. Voyez, il s'arrête ici. Nous allons passer à l'étape suivante. Nous voyons que mon âge est 17. Il a la valeur 17. Maintenant, une décision va être prise ici. Si mon âge est supérieur à 18, nous allons faire [tousse] quelque chose. Euh, sinon, nous ne ferons rien. Alors passez à l'étape suivante. Voyez ce qui va se passer. Tout ceci a été sauté. Rien n'a été imprimé parce que mon âge n'est pas supérieur à 18. Et alors le code se termine comme ça. Alors si vous voulez euh si vous voulez faire quelque chose si ce n'est pas vrai, vous pouvez dire quelque chose comme euh sinon euh revenez plus tard quelque chose quelque chose comme ça. Revenez plus tard. Alors si nous exécutons ceci, j'essaie juste de vous faire comprendre ceci moins 17. Si ceci est vrai, alors ceci sera imprimé. Sinon, ceci sera imprimé. Alors si nous passons à l'étape suivante, ceci ne s'imprime pas parce que ce n'est pas vrai. Et alors celui-ci, cette chose sera toujours imprimée. Tout ce qui est à l'intérieur de sinon, il reviendra plus tard. Et alors imprimez terminé. Mais nous pouvons ajouter plus d'instructions ici. Nous pouvons dire comme euh lse if lse if mon âge égal 17, nous pouvons dire revenez l'année prochaine. Alors nous allons sauvegarder ceci. Nous allons exécuter le débogage. Le code s'arrête ici. Nous pouvons passer à l'étape suivante. Nous voyons que ceci ne s'exécute pas parce que mon âge n'est pas supérieur à 18 et alors il va sauter. Il passera à la prochaine évaluation et il dira est-ce que mon âge est égal à 17 ? Et en Python quand vous comparez deux choses comme ceci est une assignation. Ceci assignera 17 à mon âge. Mais s'il y a deux signes égaux, ceci comparera deux choses. Alors nous disons sinon si mon âge est égal à 17, alors nous allons faire quelque chose. Alors si nous passons à l'étape suivante parce que mon âge est égal à 17, il va continuer et alors exécuter ceci comme ça, revenez l'année prochaine et alors vous remarquerez qu'il a complètement sauté ceci et est juste allé à la fin du code. C'est parce que euh ceci est comme j'oublie comment ça s'appelle un bloc sinon si ou un bloc si euh seulement une fois que l'une de ces conditions est remplie, tout le code sous cette condition s'exécutera et alors une fois qu'il le fait, la chose est comme c'est fait, l'interpréteur sortira juste du bloc et alors commencera à exécuter le code suivant. Alors par exemple, je vais vous montrer ce que cela signifie. Alors si nous copions juste un tas de ceux-ci et d'ailleurs, c'est pourquoi les choses sont indentées en Python. Cela les regroupe avec la chose qui est au-dessus. Alors par exemple, je vais vous montrer ce que cela signifie. Alors si nous redémarrons ceci, le code s'arrête ici ou le code s'arrête. Nous passons mon âge est égal à 17. Ceci n'est pas vrai. Alors aucun de ceux-ci ne s'exécutera. Nous passons à l'étape suivante. Est-ce que mon âge est égal à 17 ? C'est vrai. Alors maintenant l'interpréteur est entré dans ce bloc de code sous cette instruction et il va exécuter toutes ces choses. Alors il imprimera trois fois. Et alors parce que l'une des instructions if a été satisfaite, tout le reste de la chose est complètement sauté. Alors j'ajouterai une autre chose ici. Euh, peut-être que vous pouvez obtenir comme une intuition ou plutôt laissez-moi faire ceci. Laissez-moi faire ceci. Alors je vais réexécuter ceci. Le code s'arrête ici. Il s'arrête. Nous voyons que mon âge est égal à 18. Alors pensez-y comme est-ce que mon âge est supérieur à 18 ? Il n'est pas supérieur parce qu'il est égal à 18. Alors vous remarquerez que cette chose a été complètement sautée. La prochaine chose qui sera évaluée est-ce que mon âge est égal à 17 ? Ce n'est pas le cas. Alors tout ceci a été sauté et alors cette chose sera imprimée. Ce bloc de code sera imprimé comme ça. Et alors terminé. Et vous pouvez avoir beaucoup de je pense que vous pouvez avoir pratiquement un nombre illimité de instructions else if. Alors si j'en ajoute une autre ici, lse if mon âge euh est vous savez je peux dire je peux dire supérieur ou égal à 18. Nous pouvons dire imprimez wow vous venez de réussir. Oh non, ça n'a pas de sens. Wow. Bienvenue au club. Je ne veux pas dire un vrai club. Je veux dire vous savez un club pour enfants quoi que ce soit. Alors euh et je vais copier ceci quelques fois de plus juste pour que vous puissiez avoir l'intuition que une fois qu'une de ces conditions est remplie, tout ce qui est en dessous ou tout ce qui est en dessous s'exécutera. Par exemple, nous exécutons ceci, toujours arrêté ici. Le point d'arrêt mon âge est 18. Est-ce que mon âge est supérieur à 18 ? Ce n'est pas le cas. Alors cette chose est sautée. Est-ce que mon âge est égal à 17 ? Ce n'est pas le cas. Alors ceci est sauté. Est-ce que mon âge est supérieur ou égal à 18 ? C'est comme ça que vous dites ceci. Et c'est supérieur ou égal parce que c'est égal à 18. Alors maintenant ce bloc de code est exécuté. Et alors ceci est sauté parce que quelque chose, une des conditions a été satisfaite et alors l'interpréteur va juste à la ligne suivante qui est euh va terminer le code et il le fait. Alors, comment cela se rapporte-t-il au monde réel ou plutôt à ce que nous allons faire ? Euh, je vais juste vous donner un exemple très basique. Ceci est utilisé littéralement partout d'ailleurs, mais dans chat GPT, vous ne pouvez pas envoyer un nombre infini de caractères au modèle GPT. Il a une limite, n'est-ce pas ? Alors par exemple, je peux dire comme vous savez mon invite égale vous savez s'il vous plaît trouvez la menace pour moi, je pense que quelqu'un s'est connecté à mon PC quelque chose comme ça et nous pouvons obtenir la longueur de ceci en termes de caractères, combien de caractères cela fait. Alors nous pouvons dire juste n'importe quel nom de variable aléatoire, je l'appellerai longueur et alors pour ce faire, nous utilisons une fonction de longueur appelée len et alors nous mettons la chose à l'intérieur que nous voulons mesurer comme ça. Et alors si l'invite est trop grande, nous ne voulons pas l'envoyer à GPT parce qu'elle aura une erreur, n'est-ce pas ? Alors nous pouvons dire comme euh et voici un autre exemple de variable. Nous pouvons dire comme ceci est vraiment aléatoire d'ailleurs. Comme bien sûr, vous savez que la taille maximale de l'invite est plus grande que ceci, mais je dirai comme taille maximale de l'invite et je peux la définir à 10. Alors si quelque chose est plus grand que 10 caractères, nous ne pouvons pas l'envoyer à GPT juste pour l'exemple pour simplifier. Alors nous pouvons dire comme euh si appelons ceci longueur de l'invite. Alors si la longueur de l'invite est supérieure à la taille maximale de l'invite, nous dirons à l'utilisateur votre invite est trop grande. Il faut la raccourcir. Sinon, vous savez, euh envoyez ceci est un commentaire, envoyez l'invite à chat GPT et alors en Python si vous ne voulez rien faire, vous tapez juste passer ceci est juste pour l'exemple, d'accord, je veux juste montrer un exemple. Alors si nous exécutons ceci, zut, alors si nous exécutons ceci, je vais définir un point d'arrêt ici, maintenant nous allons exécuter. Alors taille maximale de l'invite, ceci est juste une variable. Mettons-la à 10. Et alors mon invite, s'il vous plaît, trouvez les menaces pour moi. Je pense que quelqu'un s'est connecté à mon PC. Vous pouvez le voir ici. Mon invite. Et alors cette fonction de longueur calcule la longueur de cette invite. Alors si nous passons à l'étape suivante, nous voyons que la longueur de l'invite est 65. Cela signifie qu'il y a 65 caractères comme à l'intérieur d'ici, supposément. Et alors maintenant nous disons si la longueur de l'invite est supérieure à la taille maximale de l'invite, nous devons imprimer votre invite est trop grande. Il faut la raccourcir. Sinon, nous allons la traiter comme envoyer l'invite à chat dbt. Alors si nous passons à l'étape suivante, notre longueur d'invite est trop grande. C'est plus de 10 caractères. Alors il va imprimer quelque chose à l'écran. Votre invite est trop grande. Il faut la raccourcir et alors le code se termine. Et nous utilisons nous utilisons quelque chose de très similaire à ceci à l'intérieur de l'agent IA sock que nous allons construire. C'est juste une façon de contrôler le flux du code. Euh, de mesurer quelque chose et de contrôler le flux du code. Alors j'espère que cela a du sens. Euh, au moins au moment où vous les verrez dans la nature quand nous commencerons à coder et à construire des choses, j'espère que cela aura plus de sens. Euh, ils deviennent vraiment complexes. Euh, ils peuvent devenir vraiment complexes, mais euh si vous comprenez autant, vous êtes prêt et nous nous verrons dans la prochaine vidéo. Bienvenue de retour. Euh, cette leçon porte sur les listes. Euh, une liste est essentiellement juste une collection de choses. Cela pourrait être une collection de chaînes de caractères ou comme toute autre chose aléatoire. Comme cela pourrait être n'importe quoi. Cela ne doit pas nécessairement être des chaînes de caractères, mais je vais juste vous montrer, vous savez, à quoi cela ressemble. Habituellement, c'est comme une collection de choses similaires, des articles similaires. Euh, les chaînes de caractères sont plus utiles ou plutôt les listes sont plus utiles quand les articles sont similaires et c'est généralement des choses similaires. Mais je vais juste vous montrer à quoi cela ressemble et comment l'utiliser et ainsi de suite. Alors si j'imprime ceci et que je dis comme type et que je tape le nom de la variable, nous pouvons voir comme et je vais arrêter ceci. Je peux l'arrêter. Oui, je vais juste l'exécuter pour vous montrer. Alors il s'arrête ici et alors si nous passons à l'étape suivante, nous voyons la liste ici, la liste des membres aléatoires. Nous pouvons la voir de 0 à 4. Et si nous imprimons ce type de membres aléatoires, cela imprimera qu'il s'agit d'une liste. Nous imprimons le type. Mais si j'imprime juste la liste elle-même, comme ça. Arrêtez-la. Laissez-la s'exécuter. Vous pouvez voir qu'elle imprime juste Josh, Leia, Miho, Ken, tous. Elle l'imprime juste tous ensemble. Mais si nous voulons imprimer un particulier de ceux-ci pour une raison quelconque ou si nous voulons y accéder pour une raison quelconque, nous pouvons dire comme euh c'est comme le premier membre, le deuxième membre, le troisième membre. Alors si nous voulons le troisième membre de la liste par exemple, nous pouvons dire comme nous le faisons comme ça. Alors c'est la notation et en fait c'est la place zéro, index un, index deux, index trois, index quatre. Alors si nous voulons celui-ci, nous obtiendrons en fait le deuxième index. Alors c'est 0 1 2 3 4 comme ça. Et alors cela devrait retirer le deuxième index et le stocker ici. Et alors nous allons imprimer cela. Oh, zut. Alors, nous allons en fait imprimer ceci comme ça. D'accord. D'accord. Comme, qui que ce soit qui édite ceci, pouvez-vous supprimer cette URL parce qu'en fait je ne sais pas ce que c'est, vous savez, et je ne veux pas qu'ils y aillent. Mais bref, alors nous allons coller ceci et alors nous allons arrêter le code ici avec notre point d'arrêt. Nous allons démarrer le débogage et nous passons à l'étape suivante. Nous voyons notre liste ici et alors nous pouvons en fait voir la place zéro, la première place, la deuxième place, la troisième, la quatrième. Mais le troisième membre en anglais, vous savez, pour notre cerveau anglais, nous dirions comme 1 2 3. Alors nous allons passer à l'étape suivante et nous voyons que miho a été assigné au troisième membre de la liste qui est ici et alors il sera imprimé. Alors et nous pouvons faire d'autres choses avec ceci. Par exemple, nous pouvons dire nombre de membres. Nous pouvons créer une nouvelle variable et alors nous pouvons dire nous pouvons utiliser une fonction de longueur et alors passer cette chose ici la liste des membres aléatoires. Ensuite, nous pourrions dire si le nombre de membres est supérieur à trois, nous pouvons dire qu'il n'y a pas assez de nourriture. Désolé. Et alors nous pouvons dire sinon ou nous pouvons dire sinon si ou lse if le nombre de membres est inférieur ou égal à ou oui, nous pouvons dire si inférieur à trois, nous pouvons dire imprimer bienvenue, il y en a assez pour tout le monde comme ça et alors nous pouvons dire terminer juste pour savoir que le code est notre programme est terminé. Alors si nous exécutons ceci, nous pouvons commencer le débogage. Ceci est arrêté, point d'arrêt ici. Nous obtenons nos membres aléatoires. Nous les voyons ici. Et alors nous passons un et alors nombre de membres. Il prend la longueur des membres aléatoires. Alors nous voyons que le nombre de membres est égal à cinq. Et alors nous pouvons juste regarder ceci, le nombre de membres est cinq. Alors est-ce que cinq est supérieur à trois ? Cinq est supérieur à trois. Alors alors la ligne sous ceci devrait s'exécuter et elle le fait. Et alors quand ceci s'exécute, cela signifie que l'une de ces conditions a été remplie dans cette instruction if. Alors après que ceci s'exécute, le code va juste sortir. Alors comme ça, il n'y a pas assez de nourriture. Désolé. Et alors il se termine comme ça. Mais si nous supprimons comme vous savez peut-être moi et je ne sais pas Ken et aussi nous exécutons ceci à nouveau, nous obtenons un sens, passons à l'étape suivante, il n'y a que deux membres à nouveau ou il n'y a que deux membres, nous passons à l'étape suivante, la longueur des membres aléatoires n'est que deux. Alors si si le nombre de membres est supérieur à trois. Ce n'est pas le cas. Alors cela ne s'exécutera pas. Est-ce que le nombre de membres est inférieur à trois ? C'est le cas. Alors ceci s'exécute. Bienvenue. Il y en a assez pour tout le monde. Et alors le programme se termine. Alors oui, ce sont les listes. Euh, elles peuvent devenir plus compliquées. Euh, par exemple, vous pouvez avoir toutes sortes de choses aléatoires dedans. Alors par exemple, nous pouvons dire quelque chose comme vous savez peut-être que nous avons une chaîne de caractères. Laissez-moi comme peut-être que nous avons un nombre peut-être que nous avons comme vous savez quoi que ce soit et alors peut-être que nous avons une autre liste en fait, vous savez une autre liste. Ceci est en fait une autre liste, n'est-ce pas ? Euh, alors vous pouvez faire quelque chose comme ça et alors vous pouvez dire comme euh vous savez zut, laissez-moi renommer ceci à quelque chose d'autre. Je vais juste le nommer ma liste. Ceci est un peu intéressant. Alors nous pouvons dire comme imprimer ma liste et alors je vais juste exécuter ceci sans débogage. Euh, juste ça va l'imprimer. Et vous voyez qu'il imprime ceci. imprime comme ceci est la liste Josh 10 classe chaîne et alors il imprime une autre liste, n'est-ce pas, alors c'est l'élément zéro, l'élément un, l'élément deux, et ceci est le troisième élément, alors nous pouvons dire comme par exemple si nous disons ma liste et alors index 3 0 1 2 3, cela accédera à cette liste. Alors si nous imprimons ceci, je vais juste exécuter ceci, vous remarquerez qu'il imprime 1 2 3 4 parce qu'il imprime seulement cette liste. Mais que faire si nous voulons imprimer seulement trois par exemple ? Alors ceci est une liste elle-même. Alors nous devons obtenir si nous voulons imprimer trois, nous devons imprimer index 0 1 et alors ceci est le deuxième index. Alors ceci est

renvoie une liste. Donc si nous voulons imprimer le deuxième index de cette liste, nous ferions quelque chose Oh, je voulais dire faire ça. Nous faisons quelque chose comme ceci. C'est un peu déroutant, mais c'est juste comme ça. Alors, laissez-moi faire ceci juste pour que nous ayons quelque chose d'autre. Alors je vais commencer à déboguer ceci, ça casse. Ensuite, si nous regardons notre liste ici, nous voyons que l'index numéro trois est 0 1 2 3 4 5 comme ceci. 0 1 2 3. C'est notre index trois. Et ensuite, si nous obtenons, nous obtenons l'index trois de ma liste qui est cette euh une autre liste en fait et ensuite nous obtenons l'index deux à l'intérieur de cette liste. Donc c'est l'index 0 1 2. Donc cela devrait imprimer trois et ça le fait et puis se termine. Ce sont donc des listes. Bien sûr, vous pouvez faire beaucoup plus avec elles. Euh, nous allons de toute façon les utiliser pas mal à l'avenir, mais je voulais juste les introduire et vous donner une base. Je suppose quand vous commencerez à voir des versions de production de ceci. Mais oui, ce sont des listes et nous nous retrouverons dans la prochaine vidéo.

Donc, pour aborder la prochaine leçon, euh, c'est là que nous allons couvrir ce qui est connu sous le nom de JSON, qui signifie JavaScript Object Notation. C'est juste une façon de représenter euh quelque chose de manière structurée et agréable, facile à analyser et à comprendre pour l'ordinateur. Euh, cela peut être une représentation d'un objet du monde réel ou cela peut être littéralement n'importe quoi. Donc, je suis allé sur GPT et j'ai dit : "Je m'appelle Josh. J'ai 40 ans. Je suis un professionnel de la cybersécurité. J'habite aux États-Unis. J'aime ces choses. Euh, représentez-moi s'il vous plaît sous forme d'objet JSON." Et il a construit un objet qui ressemble à ceci. Donc, ceci est comme une propriété. Et puis la valeur, le nom, nous dirions que la propriété d'âge a une valeur de 40. La propriété de profession a une valeur de professionnel de la cybersécurité. Et puis les emplacements euh parce que j'ai dit que j'habitais dans ces trois endroits, il les a regroupés dans une liste ou un tableau. Vous pouvez appeler cela un tableau ou une liste d'objets. Donc, si vous voyez euh s'il y a un groupe d'objets dans JSON, il sera formaté comme ceci, vous verrez des crochets autour. Et donc les emplacements parce qu'il y en a trois comme vous savez qu'ils sont tous des emplacements, il les a formatés comme ceci. Et puis les choses que j'aimais, la même chose. Ce sont des goûts. Donc, il les a tous formatés ensemble dans une liste comme ceci. Donc, assez simple. Euh, vous pouvez avoir des choses vraiment élaborées avec cela, ce que nous couvrirons dans la prochaine leçon. Et puis j'ai dit à GBT, d'accord, créez trois autres humains avec le même schéma. Et schéma signifie juste la façon dont les données sont formatées ou le format des données. Donc, il y a moi, Marcus, puis Sophia, et ils sont tous dans le même format, vous savez, leurs emplacements, leurs goûts, etc. C'est juste une façon de formater les données. Et nous allons aborder cela un peu plus dans la prochaine leçon. Au fait, j'ai tout copié cela et j'ai créé une variable appelée personnes et j'ai juste euh assigné à personnes cet objet JSON et vous pouvez le faire. Donc, par exemple, si j'imprime simplement personnes comme ceci, cela imprimera tout cet objet. Tout l'objet avec tout le monde dedans. Vous pouvez voir Josh, Aiko, Sophia et tous les autres. Et cette chose, c'est en fait une liste, elle l'a retournée sous forme de liste. Vous pouvez voir que la chose extérieure est un crochet comme ceci parce que c'est une liste. Donc, si par exemple je le réduis, c'est un élément de la liste. Tout cela est un élément. Donc, je peux le réduire. C'est un autre élément entier. Donc, je peux le réduire, etc. Et si vous vous souvenez, vous pouvez accéder aux listes par, donc fondamentalement les listes sont ordonnées à partir de zéro. Donc, c'est l'élément zéro, le premier élément, le deuxième élément et le troisième élément ou l'élément à la position zéro. Donc, si je dis personnes, donnez-moi la personne à la position zéro, qui est moi, cela devrait juste renvoyer tout cela. Donc, si j'exécute ceci, cela imprimera juste les affaires de Josh uniquement. Donc, Josh, puis gâteaux, pizza et sushi comme ceci. Et c'est la personne zéro, n'est-ce pas ? C'est Josh. Et si je veux obtenir uniquement la propriété de nom, je peux choisir la personne à la position zéro, puis je peux obtenir sa propriété de nom et cela devrait juste imprimer Josh par exemple, comme ceci. Et nous approfondirons cela un peu plus dans la prochaine leçon, où nous parlerons des dictionnaires et je donnerai des exemples concrets d'où vous pourriez voir du JSON comme ceci. Et dictionnaire, cela n'aura pas de sens pour l'instant car vous n'avez pas encore abordé la leçon sur les dictionnaires, mais les dictionnaires sont essentiellement au format JSON. Ceci est essentiellement un dictionnaire. Donc, par exemple, c'est la dernière chose que je vais faire. Donc, personnes zéro. Je vais imprimer ceci à nouveau juste pour vous donner une idée. Et vous voyez que cela imprime cet objet JSON essentiellement qui est une représentation de Josh. Si nous voulons voir le type de ceci, qu'est-ce que c'est, nous pouvons faire ceci, nous pouvons le mettre à l'intérieur de cette fonction de type égale zéro et ensuite nous exécutons, nous exécutons sans débogage et cela nous dit que c'est un type de dictionnaire et la prochaine leçon porte sur les dictionnaires. Nous allons donc approfondir cela. Nous nous retrouverons là-bas. C'était des objets JSON ou JSON.

Bienvenue de retour et nous allons aborder les dictionnaires dans cette leçon. Et cela devient vraiment concret. Après avoir fait cet exemple simple, je vous montrerai à quoi ressemble un vrai dictionnaire de production et comment nous allons l'utiliser dans notre projet que nous allons faire. Mais fondamentalement, tout comme un vrai dictionnaire, il y a ce qu'on appelle une clé, puis une valeur correspondante. Donc, dans un vrai dictionnaire, vous auriez un mot, puis une définition. Mais en Python, cela s'appelle une clé et cela s'appelle une valeur, et ces choses ensemble s'appellent une KVP ou une paire clé-valeur. Donc, par exemple, voici comment vous définissez un dictionnaire. Eh bien, l'une des façons de définir un dictionnaire, cela s'appelle fruits, puis ce sont toutes les clés sur le côté gauche et ce sont toutes les valeurs. Donc, si je veux accéder à, si je veux accéder ou changer cette définition, ou si je veux accéder ou lire la définition, voici comment vous le feriez. Euh, mais je vais juste passer en revue et expliquer au fur et à mesure. Donc, je vais mettre un point d'arrêt ici et euh, au fait, je mettrai un lien vers ce fichier. Il devrait y avoir un lien vers cela ou quelques fichiers pour cette leçon. Vous pouvez donc soit copier le contenu, soit le coller ici, soit le mettre dans votre dossier de code, télécharger le fichier dans votre dossier de code si vous le souhaitez, mais je vais casser ceci, arrêter le débogage s'arrête ici, puis faire ceci, puis je vais passer par-dessus et alors vous verrez sur la gauche, nous pouvons voir notre dictionnaire de fruits, pomme, comme un mot, puis définition, mot, définition, etc. Et puis voici comment accéder à la définition de la pomme ou oui, la définition de la pomme ou la valeur de cette clé, comme ceci, c'est juste la notation pour le faire. C'est juste comme ça. Euh, vous pouvez donc vous y habituer. Je vous recommande de taper ceci pour développer votre mémoire musculaire et tout ça. Ça aide, ça aide vraiment beaucoup. Mais nous allons passer par-dessus et alors nous verrons qu'il a imprimé la définition de la pomme. fruit sucré et croquant qui existe en rouge, vert et jaune, juste comme ça. Comme ceci. Et puis nous allons, voici comment ajouter un nouveau fruit et sa description. Donc, c'est comme, ceci est notre dictionnaire de fruits. Et puis ceci est la nouvelle clé qui est ajoutée, puis la nouvelle valeur pour la clé, ou le nouveau mot en anglais, puis la définition du mot. Donc, si nous passons par-dessus ceci, nous voyons que raisin est ajouté au dictionnaire comme ceci. Et puis voici une façon de supprimer une clé ou une paire clé-valeur du dictionnaire. Donc, si nous exécutons ceci, delete space fruits mangue, cela devrait supprimer toute la paire clé-valeur de mangue et puis ce fruit tropical juteux. Donc, nous passons par-dessus ceci. Oh. Oh. Oh, j'ai accidentellement changé la description de la banane. Donc, laissez-moi juste euh, réexécuter ceci. J'ai sauté la banane par accident. Donc, je vais casser ceci ici et je vais juste le réexécuter. Donc, nous sommes ici à la banane. Voici comment changer la valeur de quelque chose. Donc, si j'agrandis ceci, euh, cela va changer la valeur de la banane en un fruit tropical doux et sucré. Donc, en ce moment, la banane est un fruit doux et sucré avec une peau jaune. Donc, si nous passons par-dessus ceci, nous voyons que la valeur change comme ceci. Et puis voici comment supprimer la mangue. Je ne sais pas comment j'ai réussi à sauter ça, mais euh, nous allons passer par-dessus ceci et alors la mangue devrait disparaître et elle le fait. Et puis euh, nous n'avons pas encore appris cette notation. Nous apprendrons cela plus tard. C'est ce qu'on appelle l'interpolation de chaînes ou les f-strings. Mais quoi qu'il en soit, cela imprimera chaque fruit. Cela imprimera le titre du fruit, puis la description. Donc, nous pouvons juste, nous n'avons pas encore appris cette boucle. Nous apprendrons les boucles plus tard. Donc, ignorez juste ceci. J'ai juste pris cet exemple de GPT parce qu'il était facile et avait du sens. Et puis nous pouvons voir toutes les nouvelles valeurs être imprimées comme ceci. Et puis le programme se termine. Donc, je vais faire un dictionnaire personnalisé très simple avec des noms et des âges de personnes. Donc, euh, nous pouvons dire par exemple euh, que je ferai personne, je ferai personne un, puis disons nom, je dirai juste non, je dirai personnes, désolé, personnes nom, puis Josh, non, d'accord, personnes âges, nous ferons ceci, personnes âges. Donc, je dirai Josh 40, Aiko 31, virgule, puis Leia, je ne sais pas, j'ai oublié 26, peut-être juste deux, et Jimmy, non, il n'y a pas de Jimmy, je pense que c'est 30. Donc, si nous voulons voir quel âge a Josh, nous dirions personnes âges comme ceci. Et puis nous accédons à la personne dont nous voulons voir. Et nous voyons que Python complète cela pour nous. Donc, si nous voulons faire ceci, cela va simplement, nous l'exécutons, cela imprimera simplement l'âge de Josh. Cela devrait dire 40. Comme ceci. Donc, c'est euh, ce sont des dictionnaires. Ça peut devenir beaucoup plus complexe. Euh, ce que je vais vous montrer dans une seconde. Donc, allez télécharger ce fichier appelé Big Dict. Cela signifie grand dictionnaire. Et ce que vous regardez ici, c'est essentiellement un euh, je suppose que c'est appelé une menace entière. Oui, c'est une menace qui a été découverte par les analystes du SOC IA et elle sera affichée dans ce format fou, ce format fou ici et c'est essentiellement un grand dictionnaire, mais il y a des dictionnaires à l'intérieur d'autres dictionnaires, etc. Donc, par exemple, juste pour que vous me croyiez, je vais imprimer le type et puis comment ai-je appelé cette chose, cela devrait en fait s'appeler instance de menace. Peu importe, mais c'est ce que c'est. Donc, si j'imprime le type pour ceci, je vais juste l'exécuter sans débogage. Oh, débogueur Python. Et alors vous pouvez voir que c'est une classe dictionnaire car cette chose est techniquement un dictionnaire. Donc, vous vous souvenez qu'un dictionnaire est plein de paires clé-valeur essentiellement, comme le mot et la définition, ou la clé et la valeur. Donc, ce que c'est, c'est une chose du monde réel. Fondamentalement, nous allons faire ceci et l'apprendre beaucoup à l'avenir, mais nous déversons beaucoup de journaux dans ChatGPT et nous lui disons essentiellement ou à l'API GPT, et nous lui disons de trouver les menaces, puis il parcourt les journaux et puis il corrélera des choses et trouvera quelque chose, et c'est juste l'une des menaces qu'il a trouvées. C'est comme un objet dictionnaire. Mais clé, c'est une clé. Et puis la valeur, c'est la clé. C'est la clé. C'est la valeur. C'est une clé. Et puis c'est une valeur. Et vous remarquez que cette valeur est en fait juste un autre dictionnaire. Et alors vous remarquerez que c'est une clé. Et puis c'est la valeur. Mais cette valeur est juste une liste ou un tableau. C'est une liste. C'est assez standard. Une clé et une valeur. C'est une clé. C'est une valeur. Mais cette valeur est une liste et cela continue. Donc, si par exemple nous allons traiter un dictionnaire à l'intérieur d'un dictionnaire. Donc, si nous disons imprimer, oops, je ne voulais pas faire ça. Donc, regardons cette clé miter. C'est une clé, n'est-ce pas ? Et puis c'est une valeur. Donc, si nous imprimons instance de menace, miter, comme ceci, je vais casser ceci, sauvegarder et puis je vais exécuter et commencer à déboguer et vous remarquerez que la variable instance de menace ici, c'est un dictionnaire et vous pouvez voir toutes ces choses, puis c'est la clé MITER, puis la valeur. Donc, si nous imprimons ceci tel quel, cela imprimera la valeur miter. Donc, cela devrait imprimer ces choses, n'est-ce pas ? Juste pour avoir une idée. Donc, si nous passons par-dessus, nous voyons qu'il imprime tactique accès initial technique bla bla bla sous-technique, qui est ces choses ici. Cela imprime juste un autre dictionnaire essentiellement. Mais par exemple, si nous voulons accéder à, qu'est-ce que c'était, la description, la description à l'intérieur de MITER, faire ceci accède juste à tout cela, qui est un dictionnaire. Mais si nous voulons y accéder, nous devons utiliser la clé de description réelle à l'intérieur du dictionnaire secondaire, comme ceci, description. Donc, si nous exécutons ceci, cela devrait imprimer la description pour ceci, comme ceci. Et ça le fait. Et puis je vais faire une chose de plus très rapidement. Donc, nous accédons à un dictionnaire à l'intérieur d'un dictionnaire. C'est un peu compliqué, je sais. Mais c'est juste comme ça. Donc, cette fois, nous allons accéder à une liste à l'intérieur du dictionnaire. Donc, c'est en fait un dictionnaire. Tout cela est une paire clé-valeur. C'est une clé. C'est la valeur. N'est-ce pas ? Donc, nous accédons par exemple aux recommandations. Donc, si nous imprimons simplement ceci tel quel ou si nous l'exécutons. Nous allons nous arrêter ici. Passer par-dessus. Cela imprime surveiller [reniflements] et pivoter. Et c'est juste une liste, n'est-ce pas ? Nous avons appris cela il y a quelques épisodes, il y a quelques vidéos. Mais disons que nous voulons accéder à, vous savez, pivoter par exemple, nous pouvons le faire. Euh, mais c'est l'élément zéro et c'est le premier élément ou le premier index, l'index zéro, le premier index. Donc, si nous voulons accéder à pivoter, nous devons accéder au premier index. Donc, si nous exécutons ceci, imprimons-le, cela imprime pivoter. Il atteint les recommandations, puis nous obtenons le premier index à l'intérieur des recommandations, qui est pivoter, et c'est un peu compliqué, mais je vous recommande de faire quelques activités avec ceci, de regarder différentes valeurs, je suppose, et d'essayer de les imprimer comme ceci, par exemple, essayez d'imprimer cette ligne, c'est une liste, n'est-ce pas, à l'intérieur de la paire clé-valeur des lignes de journal, donc essayez d'imprimer le premier index de ceci, ou essayez d'imprimer cette description, par exemple, et ou essayez d'imprimer mon adresse e-mail. Ceci est un vrai journal, au fait, essayez d'imprimer cette adresse e-mail car quand si vous traitez avec des API ou faites littéralement n'importe quel type de développement qui implique le web ou presque n'importe quoi, vous traiterez des données dans cette structure. Donc, c'est vraiment bien d'apprendre à l'analyser et à la gérer et tout ça. Et nous allons traiter cela beaucoup lorsque nous construirons le, le véritable analyste SOC IA ou comment vous voulez appeler cela. Donc, il est vraiment bon de le comprendre et oui, ce sont des dictionnaires. Euh, vous pouvez toujours, vous savez, si vous êtes bloqué ou si vous avez des questions, n'hésitez pas à demander dans la zone communautaire ou vous pouvez aller sur ChatGPT. Vous pouvez littéralement tout déverser dans GPT et dire, expliquez-moi cela comme si je ne comprenais pas ce qu'est un dictionnaire ou, vous savez, vous pouvez lui parler et obtenir qu'il vous explique les choses de manière plus simple. Mais oui, ce sont des dictionnaires. Euh, essayez juste de le reconnaître et d'être conscient de la façon de l'utiliser et tant que ce n'est pas complètement étranger pour vous lorsque vous le regardez, vous êtes en bonne posture. Mais oui, nous nous retrouverons dans la prochaine leçon.

Bienvenue de retour. Euh, dans cette leçon, nous allons couvrir ce qu'on appelle la concaténation de chaînes. Et concaténation signifie juste connecter ensemble, comme connecter quelque chose ensemble. Donc, connecter des chaînes ensemble. Et je vais essayer de vous donner un exemple de la façon de faire cela. Je suppose que cela a du sens que nous puissions utiliser certaines des autres choses que nous avons apprises. Donc, nous allons faire un programme. Nous allons dire, euh, pas Josh. Oh mon dieu. prénom = et nous allons obtenir une entrée de l'utilisateur. Quel est votre prénom et nous allons copier ceci. Celui-ci sera le nom de famille. Quel est votre nom de famille ? Et puis âge, nous demanderons quel âge avez-vous ? Et puis nous allons concaténer tout cela. Donc, nous allons dire que nous allons imprimer et puis nous dirons bonjour. Donc, c'est une chaîne et puis si nous voulons la concaténer [tousse] nous pouvons utiliser un signe plus et puis nous pouvons dire prénom, puis nous allons concaténer davantage comme une virgule. Oh, nous dirons prénom, puis désolé, nous ferons un espace. Ceci est désolé, c'est vraiment pénible, mais ça aura du sens. Bonjour, prénom, nom de famille, et puis nous allons concaténer. C'est comme ça qu'on connecte des chaînes ensemble avec le signe plus. Puis concaténer à nouveau. Oh, attendez. Vous êtes base. Nous dirons âge base ans, n'est-ce pas ? Je sais que cela semble vraiment arbitraire, mais nous allons y jeter un coup d'œil. Donc, disons ceci et nous allons le casser ici. Ou peut-être que je vais le casser ici et je vais juste le laisser s'exécuter. Donc, nous allons déboguer ceci et le code s'exécute. Nous disons quel est votre prénom ? Josh. Votre nom de famille Matakor. Quel âge avez-vous ? Six. Et puis le code, parce que nous avons mis un point d'arrêt ici, nous pouvons voir ici que notre prénom est Josh, nom de famille Matakor. Notre âge est six. Et puis si nous exécutons ceci, cela va juste mettre toutes ces choses ensemble. Nous l'exécutons, il dit bonjour Josh Mator. Vous avez 6 ans. N'est-ce pas ? C'est juste la concaténation de chaînes, essentiellement. C'est juste mettre des chaînes ensemble et puis dans le monde réel, quand nous allons construire le, vous savez, l'analyste SOC IA, nous allons l'utiliser pas mal, mais une utilisation principale, c'est de créer notre invite à envoyer au point de terminaison de l'API OpenAI, comme lorsque nous essayons de faire de la chasse aux menaces, nous aurons quelque chose qui ressemble à ceci, ce sera comme, utilisateur, désir de l'utilisateur, peu importe, désir de l'utilisateur, puis nous aurons une invite système, puis nous aurons, euh, quelques journaux, par exemple, donc pour instance, laissez-moi essayer de faire une chose du monde réel de ceci, une seconde. Donc, par exemple, euh, j'obtiens juste des journaux réels en direct de la gamme latérale, beaucoup d'échecs de connexion contre l'une de nos machines virtuelles. J'ai copié ceci. Donc, par exemple, nous aurons quelque chose comme ceci. Essayez de rendre cela aussi logique que possible. Donc, c'est une façon de faire un bloc de chaîne. Donc, je colle cette chose géante ici. C'est une tonne de journaux, n'est-ce pas ? J'ai juste, c'est une variable avec une tonne de journaux dedans. Donc, le désir de l'utilisateur sera quelque chose comme, nous suspectons qu'un ordinateur a été exposé à Internet. Nous craignons qu'il ait pu être compromis, quelque chose comme ça, une chose basique que nous allons demander à l'IA agentique, quelque chose ne va pas, pouvez-vous regarder et faire une chasse aux menaces s'il vous plaît, chassez, et puis c'est là que nous fournirons l'invite système, vous savez, qui serait comme, vous êtes un expert, vous savez, peu importe [reniflements] expert, expert chasseur de menaces et un dieu KQL et Azure. S'il vous plaît, examinez les journaux et dites-nous si quelque chose ne va pas. Veuillez couvrir miter, peu importe les ttps d'attaque, etc., quelque chose comme ceci. Donc, fondamentalement, nous allons finir avec trois chaînes, juste la façon dont le modèle, le contexte, le protocole et tout l'agent fonctionnent, puis nous devrons créer une grande invite, essentiellement, que nous envoyons au point de terminaison de l'API OpenAI, c'est comme l'API de ChatGPT essentiellement. Donc, par exemple, mon dieu, laissez-moi, donc par exemple, cela finira par être quelque chose comme ceci, vous savez, peu importe le message à envoyer à GPT, pas exactement comme ceci, mais pratiquement, ce sera une concaténation de ces choses. Donc, nous allons concaténer le désir de l'utilisateur avec l'invite système, puis avec les journaux à la fin. Oh oui, à la fin de ceci, il dira quelque chose comme, vous savez, veuillez examiner, oops, les journaux ci-dessous, quelque chose comme ceci, puis c'est la chose qui sera finalement envoyée à GPT essentiellement, puis il effectuera une chasse aux menaces et ainsi de suite. Donc, je vais juste exécuter ceci, juste pour le plaisir. Donc, message à envoyer à GPT. C'est comme la concaténation complète de nous avons concaténé ces trois chaînes en ceci, puis c'est ce qui va à GPT. Et pour le plaisir, si vous voulez, nous pouvons copier tout cela et nous pouvons aller sur GPT et puis c'est comme ce qui sera envoyé en arrière-plan à l'API, comme certains, cela ressemble à ceci. C'est comme un texte fou et énorme. Ce n'est pas exactement comme ça, mais c'est assez proche. Et puis c'est assez intelligent pour, vous savez, le parcourir et produire des résultats. C'est comme des données vraiment désordonnées et un peu folles, mais je voulais juste vous montrer la concaténation de chaînes et comment elle est utilisée essentiellement. Et il existe des moyens plus faciles de le faire, mais oui, je voulais juste vous montrer cela et nous regarderons une manière plus efficace de le faire dans la prochaine leçon lorsque nous couvrirons ce qu'on appelle l'interpolation de chaînes ou le fring. Donc, nous nous retrouverons là-bas.

Bienvenue de retour. Euh, dans cette leçon, nous allons couvrir l'interpolation de chaînes. C'est vraiment similaire à, euh, la concaténation de chaînes, mais c'est juste une manière plus facile ou plus lisible par l'homme de le faire, je suppose. Donc, euh, voyons si j'exécute ceci. Je vais juste l'exécuter à nouveau, euh, sans débogage juste pour que vous puissiez voir le résultat. Donc, quel est votre nom ? Euh, Josh. Nom de famille Matakor. Quel âge avez-vous ? Six. Et puis cela imprime cette chose comme bonjour Josh Mator, vous avez six ans, n'est-ce pas ? Et si nous voulons faire cela avec l'interpolation de chaînes, alias une f-string, c'est beaucoup plus facile. Et la notation est un peu arbitraire, mais c'est juste comme ceci. Vous tapez juste. Par exemple, bonjour. Et puis le prénom ira ici. Le nom de famille ira ici. Vous avez des années d'âge, n'est-ce pas ? Oops. Lire. Je ne sais pas pourquoi j'ai tapé ça. Et puis vous mettez juste les variables ici. Donc, prénom, nom de famille, puis âge. Oops. Âge. C'est de l'interpolation de chaînes. C'est juste plus intuitif à regarder. comme ceci, c'est assez difficile à lire, n'est-ce pas ? Et vous allez le gâcher avec des espaces. C'est juste difficile à gérer. Mais celui-ci, il est facile à lire. Donc, si nous exécutons ceci, euh, je vais juste l'exécuter sans débogage. Ou oui, et j'utiliserai un nom différent. Euh, je ne sais pas. Euh, Sandy Wandy Wang. D'accord. 90. C'est la même chose. Vous voyez, cela imprime exactement la même chose, mais celui-ci est plus facile à lire. C'est de l'interpolation de chaînes. Et la façon, laissez-moi voir par exemple, si vous vous souvenez de cette longue chose avec l'invite ou quoi que ce soit, où nous avons, vous savez, le message utilisateur, je veux faire X, puis système, invite système, vous êtes un maître chasseur de menaces, bla bla, utilisez les journaux ci-dessous, puis les journaux. Non, euh, n'importe quelle donnée de journal aléatoire. C'est un peu plus facile de, euh, faire de l'interpolation de chaînes avec ceux-ci car vous pouvez simplement faire quelque chose comme ceci. Message maître, peu importe, ou message combiné est une meilleure façon de le dire. message combiné. Vous pouvez faire quelque chose comme ceci = et vous pouvez faire une f-string et puis vous pouvez faire des triples guillemets ou comme ceci. Vous pouvez faire quelque chose comme, c'est vraiment simple, dites message utilisateur, chose, message système, et vous mettriez les journaux ici, comme ceci. Et puis c'est juste plus facile à regarder et à gérer, pour être honnête. Et vous pouvez aussi faire quelque chose comme ceci. Ce sont presque la même chose. Donc, par exemple, par exemple, faites quelque chose comme ceci, vous mettez toutes ces choses même sur la même ligne. Et vous pouvez revenir aux guillemets simples. Et puis vous mettez juste un saut de ligne entre eux ou une nouvelle ligne, quelque chose comme ceci. Comme ceci. Et puis c'est votre message système. C'est juste vraiment facile à assembler. Et si vous imprimez ceci, cela devrait probablement imprimer la même chose. Mon message un, je crois, imprimer un. Imprimer deux. Et je vais juste euh, exécuter ceci sans débogage. Cela devrait imprimer, vous savez, cela imprime la même chose. Donc, cela rend juste facile de mettre des chaînes ensemble sans utiliser le signe plus et tout ce truc fou, si cela a du sens. Donc, l'interpolation de chaînes, alias f-strings, c'est juste que vous savez, vous avez une chaîne. Je vais faire quelque chose de facile. Chat chien nom Jane. Vous avez juste une chaîne, n'est-ce pas ? Vous pouvez avoir une chaîne vide, mettez un F devant, mettez les accolades, puis vous mettez juste la variable que vous voulez combiner. Donc, et puis je vais casser ceci et puis je vais terminer la leçon. Donc, nom de chat Jim, nom de chien Jane, noms combinés, c'est juste nom de chat base nom de chien, puis imprime les noms combinés et Jim Jane. Mais oui, ce sont des f-strings, interpolation de chaînes, et nous nous retrouverons dans la prochaine vidéo. Et ceci est utilisé beaucoup dans le monde réel et vous le verrez certainement quand nous y arriverons et vous direz, d'accord, oui, j'ai appris ce que c'était. C'est tout l'intérêt de ceci. Encore une fois, je veux juste vous rappeler, nous n'essayons pas de devenir des ingénieurs fang ou quelque chose comme ça. J'essaie juste d'amener les gens au niveau ou de vous amener au niveau où vous pouvez reconnaître et interpréter le code, puis le modifier. Vous savez, vous pouvez le modifier si vous voulez changer quelque chose. Comme quelqu'un qui ne sait pas coder, qui n'a jamais vu Python auparavant, et s'il regarde ceci, il ne saura pas ce qu'il regarde. Mais vous au moins maintenant, vous avez une idée, vous savez ce que c'est et si vous voulez changer ce qui est imprimé, vous avez une idée, peut-être que vous voulez changer le nom d'un des animaux ou vous voulez avoir plus d'espaces ou une ligne entre eux, ou quelque chose comme ça. Donc, ne vous découragez pas ou quoi que ce soit. J'essaie juste, nous essayons juste de construire une intuition générale et d'être capables de reconnaître des modèles et des choses. Mais oui, nous nous retrouverons dans la prochaine leçon.

Nous reviendrons dans cette leçon. et nous allons couvrir ce qu'on appelle les boucles for. Une boucle for est essentiellement juste une façon, lorsque vous avez une collection de choses, par exemple, une liste, c'est une façon qui vous donne une chance de faire quelque chose ou d'interagir avec chaque élément de la collection, si cela a du sens. Cela aura plus de sens intuitif une fois que nous aurons exécuté le code, mais voici une liste de choses. Nous avons appris les listes récemment et elle est assignée à cette variable, puis c'est la boucle for réelle, comment elle est structurée, puis vous savez que le code se termine ici. Donc, nous allons juste l'exécuter et je vais juste expliquer les choses au fur et à mesure. Donc, j'ai aussi agrandi l'écran, mais cela a rendu mon exécution à l'intérieur d'ici. Donc, je dois y aller, mais nous voyons que le code s'arrête ici, puis si nous passons par-dessus, fruits a ces choses à l'intérieur et puis cette variable, c'est comme une variable de remplacement. Cela peut être n'importe quoi. Mais la façon dont c'est, la grammaire, la syntaxe est comme 4x dans votre collection ou votre liste, puis cela vous donnera une chance d'imprimer chaque chose. Donc, par exemple, si nous entrons ici, nous remarquons que la variable fruit, c'est ceci, elle a reçu la valeur pomme, qui est ceci. Et puis nous l'imprimons. J'aime la pomme. Et puis cela remonte ici. Et si nous passons à nouveau, maintenant le fruit est assigné banane, qui est ici. Nous passons, cela imprimera banane. Passer à nouveau. Et puis enfin, fruit a reçu cerise. Et puis nous passons. Cela imprime j'aime la cerise. Et puis cela se termine. Cela sort de la boucle parce que nous avons dit itéré, mais cela a parcouru chacun des éléments. Et maintenant le programme se termine. Et euh, cette variable, comme je l'ai dit, est arbitraire. Elle peut être nommée n'importe quoi. Donc, pour tout ce qui est dans ma liste, euh oh, pour tout ce qui est dans ma liste. Donc, par exemple, je peux en faire une variable arbitraire comme ceci, cela peut être n'importe quoi, n'est-ce pas ? Donc, si j'exécute ceci, le même résultat se produit. J'aime la pomme. J'aime la banane. J'aime la cerise. Comme ceci. C'est à peu près tout. Même chose. Je veux juste vous montrer que cette variable est arbitraire. Euh, voyez 1 2 3. Cela peut être n'importe quoi. Boum. Déboguer ceci. Et nous pouvons, c'est pourquoi le débogage est si important lorsque vous essayez d'avoir une intuition pour des choses comme les boucles, comment cela fonctionne. C'est essentiellement comme parcourir chacun de ces éléments de la liste et cela vous donne une chance de faire quelque chose avec, n'est-ce pas ? Mais par exemple, pour ajouter un peu plus de logique ici, nous pouvons dire, vous savez, c'est très artificiel, mais je vais remettre ceci à, je vais dire f. C'est aussi une pratique courante. Mais nous pouvons dire, nous pouvons dire si n'est pas égal à pomme par exemple. Cela signifie n'est pas égal. Nous pouvons dire imprimer f quelque chose comme ceci. Donc, par exemple, déboguer ceci. Et puis pour f dans fruits, f reçoit pomme, qui est la première. Nous pouvons dire si f n'est pas égal à pomme, nous allons imprimer le fruit. Nous allons imprimer f. Mais c'est égal à pomme. Donc, cela est effectivement sauté la première fois. Et puis nous pouvons dire continuer pour terminer le reste du programme. Et vous pouvez voir que cela a tout imprimé sauf la pomme, comme nous avons décidé de ne pas le faire. C'est une logique très arbitraire. Mais pour un exemple de la façon dont nous allons l'utiliser dans notre analyste SOC IA dans le monde réel, nous pourrions avoir quelque chose comme, par exemple, par exemple, en fait, je vais formater ceci. Au fait, je vais mettre ceci dans le lien, ce fichier, donc vous n'avez pas à faire tout cela. Je vais formater le document. Oops. Formater le document avec le formateur noir. Oh, pouvez-vous couper tout cela ? Qui édite ceci ? Laissez-moi configurer cela. D'accord, vous pouvez commencer à enregistrer à nouveau. Euh, donc un autre exemple de la façon dont nous pourrions l'utiliser. Euh, c'est comme une grande liste de menaces. C'est comme de notre véritable analyste SOC IA vidéo et je vais mettre ce fichier dans la description ou vous savez un lien ci-dessous ou quelque chose. Euh, donc vous pouvez juste le télécharger si vous voulez, mais je vais juste vous montrer quelque chose comme un exemple du monde réel de la façon dont une liste pourrait être utilisée. Donc, c'est en fait, ou plutôt comment une boucle for pourrait être utilisée. Donc, c'est comme une grande liste de menaces que l'analyste SOC IA a trouvées par exemple. Et nous pouvons, peut-être après que le code s'exécute, après qu'il ait fait toute sa chasse aux menaces et les ait trouvées, nous pourrions faire quelque chose comme, vous savez, imprimer toutes les menaces. Donc, nous dirions, ou menace dans menaces. Nous pourrions dire, vous savez, imprimer menace, quelque chose de vraiment simple comme ceci. Et nous dirions, imprimer terminé juste pour montrer que notre chose est terminée. Quelque chose comme ceci. Et si nous exécutons juste ceci, je vais juste l'exécuter. Et vous voyez, cela déverse toutes les menaces à l'écran. Et disons que nous ne voulons pas déverser tout cela. Peut-être que nous voulons juste déverser le titre de la menace. Donc, comme ceci est une collection, n'est-ce pas ? C'est une liste de dictionnaires ou une liste d'objets JSON essentiellement. Donc, nous savons qu'il y a une clé de titre avec la paire clé-valeur. Donc, nous savons qu'il y a une clé appelée titre. Donc, nous pouvons copier ceci. Par exemple, je vais le réduire. Nous pouvons dire imprimer titre de menace comme ceci. Nous pouvons casser ceci, démarrer le débogage et nous voyons que cela s'arrête et nous voyons la menace. Vous savez, la menace qui est comme notre, nous disons l'itérateur. C'est la chose qui représente chaque élément individuel à chaque fois que la boucle s'exécute. Et à l'intérieur de chaque menace, il y a un objet JSON complet, une chose de dictionnaire. Et si je veux imprimer le titre, je peux faire ceci. Je peux juste dire menace, puis titre. Donc, et puis cela imprimera, puis cela imprimera juste le titre uniquement de la menace, par exemple. Et ce sont de vrais journaux de menaces. Et encore une fois, je veux juste dire que ceci est l'itérateur. Cela peut être littéralement n'importe quoi, n'importe quelle variable facile. C'est juste, c'est comme un espace réservé. Il contiendra la valeur de chaque élément individuel qui se trouve dans la collection ou dans la liste dans notre cas. Donc, je vais exécuter ceci une fois de plus juste pour vous donner une idée. J'ai renommé la chose en X et voyez X. Il a juste la valeur de ce que ces menaces individuelles avaient dedans. Donc, même chose, imprimer les titres comme ceci. Oui, ce sont des listes. C'est juste, ou plutôt ce sont des boucles for. Euh, cela vous permet juste d'itérer. Nous voyons que cela vous permet d'itérer sur chaque élément d'une collection. Juste comme une collection courante sont les listes. Donc, j'ai juste utilisé des listes par exemple sur ceci. Mais nous verrons cela assez souvent dans le code de production réel, je suppose, que nous allons faire. J'espère que cela a du sens. Euh, n'hésitez pas à expérimenter un peu avec et puis nous nous retrouverons dans la prochaine leçon.

Bienvenue de retour. Euh, ce sera la leçon sur les fonctions. C'est là que ça commence à devenir un peu difficile pour les gens, mais la fonction est une partie intégrante de la programmation en général. Donc, vous devez vraiment vous assurer de la comprendre. Mais fondamentalement, euh, une fonction est lorsque vous voulez réutiliser le même code plusieurs fois sans avoir à taper le même code plusieurs fois. Donc, je vais juste vous donner un exemple très simple. Donc, c'est un exemple très simple. Donc, la notation pour créer une fonction, vous dites defaf et puis je dirai introduction. Je vais juste la nommer introduction et puis c'est l'indentation. Euh, tout ce qui est indenté sous, après cette définition de fonction, fera partie de la fonction. Donc, je dirai imprimer bonjour, mon nom est Josh par exemple. Imprimer. Mon plat préféré est le gâteau. Imprimer. J'ai 67 ans, par exemple. Et puis maintenant, maintenant je suis techniquement en dehors de la fonction. Donc, vous devez appeler ce qu'on appelle appeler la fonction pour qu'elle s'exécute. Donc, par exemple, si je, je suis en dehors de la fonction maintenant parce que j'ai effacé l'indentation, je suppose que vous pouvez dire, et je dirai ici, c'est samedi. Donc, et puis si j'exécute juste ceci par exemple, vous remarquez qu'il dit juste qu'il est samedi. Rien d'autre ne s'est passé parce que je n'ai pas appelé la fonction. Donc, pour appeler la fonction, tout ce que vous avez à faire est de taper, vous tapez juste le nom de la fonction b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b10000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000A.I.S.O.C. analyst and it will output it in this crazy format. This is basically one big dictionary, but there are dictionaries inside other dictionaries, etc. So, for example, just so you can believe me, I'll print type and then what did I call this thing? This should actually be called threat instance. It doesn't matter, but that's what it is. So, if I print the type for this, I'll just run this without debugging. Oh, Python debugger. And then you can see it's a class dictionary because this thing is technically a dictionary. So, you remember a dictionary is full of key-value pairs, essentially, like the word and the definition, or the key and the value. So, what this is from, this is like a real-world thing. Basically, we're going to do this and learn about it a lot in the future, but we dump a lot of logs into ChatGPT and basically tell it, or the GPT API, and we tell it, find the threats, and then it goes through the logs and then it will correlate stuff and find something, and this is just one of the threats it found. It's like a dictionary object. But key, this is a key. And then the value, this is the key. This is the value. This is a key. And then this is a value. And you notice this value is actually just another dictionary. And then you'll notice this is a key. And then this is the value. But this value is just a list or an array. It's a list. This is pretty standard. A key and a value. This is a key. This is a value. But this value happens to be a list, and it goes on and on. So, if, for example, we're going to deal with, like, maybe a dictionary inside of a dictionary. So, if we say, like, print, oops, I didn't mean to do that. So, let's look at this MITRE key. This is a key, right? And then this is a value. So, if we print, threat instance, MITRE, like so, I'm going to break this, save it, and then I'll run and then start debugging, and you notice like the threat instance variable over here, it's a dictionary, and you can see like all this stuff, and then this is the MITRE key, and then the value. So, if we print this, like it is, it's going to print the MITRE value. So, it should print this stuff, right? Just to get a sense for it. So, if we step over it, we see that it prints tactic initial access technique blah blah blah sub technique, which is this stuff right here. It just prints out another dictionary essentially. But, for example, if we want to get access to, like, what was the, you know, what was the description, the description inside of MITRE, like doing this just gets access to all of this, this whole thing, which is a dictionary. But if we want access to this, we have to use the actual description key inside of the secondary dictionary, like so, description. So, if we run this, it should print the description for this, like so. And it does. And then I'll do one more thing, really, really quick. So, we, this is like accessing a dictionary inside of a dictionary. It's a bit like complicated. I know. But that's just like how it is. So, this time we're going to access a list inside of the dictionary. So, this is actually a dictionary. This whole thing is a key-value pair. This is a key. This is the value. Right? So, we access, for example, recommendations. So, if we just print this as is, or we run it. We'll stop here. Step over. It prints out monitor [snorts] and pivot. And this is just a list, right? We learned about these a few episodes ago, a few videos ago. But say that we want to, like, access, you know, pivot, for example, we can do that. Um, but this is like the zeroth item, and this is the first item, or the first index, zero index, first index. So, if you want to access pivot, we have to access the first index. So, so if we run this, print it, it prints out pivot. It reaches into recommendations, and then we got the first index inside of recommendations, which is pivot. And it's a bit complicated, but I recommend you to, like, do some activities with this, like look at different values, I guess, and like try to print them out, like so, for example, like try to print this line out. This is a list, right, inside of the log lines key-value pair. So, try to print out the first index of this, or try to print out this description, for example, and or try to print out my email address. This is like a real log, by the way. Try to print out this email address because when, if you're dealing with, like, APIs or doing, like, really, like, literally any kind of development that involves the web or almost anything, you will be dealing with data in this structure. So, it's like really good to learn how to parse it and like deal with it and stuff. And we're going to, like, be dealing with this a lot when we're actually building the, like, the actual AI SOC analyst, or however you want to call that. So, it's really good to understand it, and yeah, that's dictionaries. Um, you can always, like, you know, if you get stuck or have questions, definitely ask in the community area, or you can go to ChatGPT. You can, like, literally dump anything into GPT and be like, explain this to me like I don't get what a dictionary is, or like, you know, you can talk to it and then get it to explain things to you in an easier way. But yeah, that's dictionaries. Uh, just try to acknowledge it and be aware of how to use it, and as long as it's not like completely foreign to you when you look at it, you're in good shape. But yeah, we'll see you in the next lesson.

Welcome back. Uh, in this lesson, we're going to cover what's called string concatenation. And concatenation just means like connecting together, like connecting something together. So, connecting strings together. And I'll try to, I'll give you like an example, um, of how to, how to do this. I guess that makes sense that we can like make use of some of the other stuff that we learned. So, we'll do a program. We'll say like, uh, not Josh. Oh my god. first name = and we're going to get input from the user. What is your first name? And we will, I'm going to copy this. This one will be last name. What is your last name? And then age, we'll say, how old are you? And then we're going to, uh, concatenate all of these. So, we're going to say, we're going to print, and then we'll say hello. So, this is one string, and then if we want to concatenate [clears throat] it, we can use a plus sign, and then we can say first name, and then we will concatenate more, like a comma. Oh, we'll say first name, and then, sorry, we'll do a space. This is, sorry, this is like really troublesome, but it will make sense. Hello, first name, last name, and then we're going to concatenate. That's how you like connect strings together with like the plus sign. Then concatenate again. Oh, wait. You are base. We'll say age base years old, right? I know this seems like really arbitrary, but we'll take a gander at this. So, say this, and we'll break it here. Or maybe I'll break it here, and I'll just like let this run. So, we'll debug this, and the code's running. We say, what is your first name? Josh. Your last name? Matakor. How old are you? Six. And then the code, because we put a breakpoint here, we can see here, our first name is Josh, last name Matakor. Our age is six. And then if we run this, it should just like put all these things together. We run it, it says, hello Josh Mator. You are 6 years old. Right? That's just string concatenation, basically. Um, it's just putting strings together. And then in the real world, um, when we go to, like, build the, you know, the AI SOC analyst, we're going to use this quite a bit. But one like really, like, um, main use case for it is, um, creating our prompt to send to the OpenAI, uh, API endpoint, like when we're trying to do threat hunting. We'll have something that looks like this. It will be like, uh, user, user desire, whatever, user desire, and then we'll have like a system prompt, and then we'll have, uh, like some logs, for example. So, for instance, instance, let me try to, like, do a real-world thing of this, one second. So, for example, um, I just, I'm getting some, like, actual live logs from the side range, a bunch of log-on failures against one of our virtual machines. I like copied these. So, for example, we'll have something like this. Try to make this make as much sense as possible. So, this is like a way to do a block of string. So, I paste this like giant thing in here. This is like a ton of logs, right? I just, this is a variable with like a ton of logs in it. So, the user desire will be something like, um, um, we suspect, you know, suspect a computer was exposed to the internet. We are worried, uh, it could have been breached, something like this, you know, a basic thing that we're going to ask the agentic AI, right? We, something's like wrong, can you like look into it and do a threat hunt, please hunt. And then this is where we would, we would provide like the system prompt, um, you know, that that would be like, you are an expert, you know, whatever [snorts] expert, expert threat hunter and an Azure and KQL god. Uh, please, you know, examine the logs and let us know if anything is wrong. Please cover MITRE, whatever attack TTPs, etc., something like this. So, basically, we're going to end up with like three strings, um, just the way the, uh, model context and protocol and like the whole agent works, and then we're going to have to, like, create like one, uh, basically large prompt, um, that we send to the, um, OpenAI, it's like the ChatGPT's API endpoint essentially. So, for example, my god, let me, so, for example, it, it will end up being something like this, um, you know, whatever message to send to GPT, not, not exactly like this, but pretty much, it's going to be a concatenation of these things. So, we'll concatenate user desire with, uh, system prompt, and then with the logs at the end. Oh, yeah, this at the end of this, it will say something like, you know, please examine, oops, the logs below, something like this, and then this is the thing that will end up getting sent to GPT essentially, and then it will perform a threat hunt, and then etc. So, I'll, I'll just like run this, you know, just, just for fun. So, message to send to GPT. This is like the full concatenation of, we concatenated those three strings into this, and then this is what goes to GPT. And for fun, if you want, we can just copy this whole thing, and we can go to GPT, and then this is like what will get sent on the back end to the API, like some, it looks like this. It's like some crazy, like, big thing of text. It's not exactly like this, but it's like pretty close. And then it's like smart enough to, like, you know, look through it and produce some kind of results. This is like really kind of like unstructured data and like a bit crazy, but I just wanted to show you like, um, string concatenation and how it's and how it's used essentially. And there's like easier ways to do this, but yeah, I just wanted to show you that, and we will look at a more efficient way to do it in the next lesson when we cover what's called string interpolation or f-string. So, we will see you there.

Welcome back. Uh, in this lesson, we're going to cover string interpolation. It's really similar to, um, string concatenation, but it's just like an easier way to, or more human-readable way to do it, I guess. So, uh, let's see if I run this. I'm just going to run this again, uh, without debugging, just so you can see the output of it. So, what is your name? Uh, Josh. Last name? Matakor. How old are you? Six. And then it prints out this thing like, hello Josh Mator, you're six years old, right? And if we want to do this with string interpolation, um, aka an f-string, it's much easier. And the notation is like a bit arbitrary, but it's just like this. You basically like just type it out. For example, hello. And then first name will go here. Last name will go here. You are age years old, right? Oops. Read. I don't know why I typed that. And then you just put the variables in here. So, first name, last name, and then age. Oops. Age. This is string interpolation. It's just like more intuitive to look at. Like this is quite hard to read, right? And you'll like mess it up with like spaces. It's just hard to deal with. But this one, it's easy to read. So, if we run this, um, I'll just run it without debugging. Or yeah, and I'll use like a different name. Uh, I don't know. Uh, Sandy Wandy Wang. Okay. 90. It's the same. You see it prints the exact same thing, but this one's easier to read. This is like string interpolation. And the way, let me see, for example, um, if you remember that like long thing with like the prompt or whatever, um, where we have like, you know, the user message, um, I want to do X, and then system, system prompt or system message, you are a master threat hunter, blah blah. Uh, use the logs below, and then the logs. No, uh, whatever random login data. It's a bit easier to like, um, do string interpolation with these because you can just do something like this. Uh, master message, whatever, or combined message is a better way to say it. combined message. You can do something like this = and you can do an f-string, and then you can do like a triple quotes or like this. You can do something like, it's like really straightforward, say like user message, thing, system message, and you would put like the logs here, like so. And then it's just, it's just easier to like look at and deal with, um, to be honest. And you can also do something like this. These are almost the same thing. So, for example, for example, do something like this, you put all these, like, even on the same line. And you can go back to single quotes. And then you just put like a line break between them or a new line, something like this. Like this. And then this is your system message. It's just like really easy to put it together. And if you print these, it should probably print the same thing. My message one, I believe, print one. Print two. And I'll just, uh, run this without debugging. It should print, like, you know, it prints the same thing. So, it just makes it easy to, like, put strings together without, like, using the plus sign and like all that, like, crazy stuff, if that makes sense. So, string interpolation, aka f-strings, it's just like, you know, you have a string. I'll do something easy. Cat dog name Jane. You just have a string, right? You can have an empty string, put an F in front of it, put the curly braces, and then you just put the variable in that you want to like combine together. So, and then I'll break this, and then I'll end the lesson. So, cat name Jim, dog name Jane, combined names, it's just cat name base dog name, and then prints the combined names, and Jim Jane. But yeah, that's, uh, f-strings, string interpolation, and we'll see you in the next video. And this is used like a lot in the real world, and for sure you're going to see it when we get there, and you're going to be like, okay, yeah, I learned what this was. That's the whole point of this. Again, I just want to remind you, I'm not like, we're not trying to become like fang engineers or something like this. I'm just trying to get people to like the level, or get you to the level where you can like recognize and interpret code and then change it. You know, you can change it, um, if you want to change something. Like someone who doesn't know how to code anything, like they've never seen Python before, and if they look at this, they won't know like what they're looking at. But you, at least now, you have like some idea, like you know what this is, and like if you want to change what gets printed out, you have some kind of idea, like maybe you want to change one of the animals' names, or you want to have like more spaces, or like a line, you know, a line between them, um, or something like that. So, don't get like discouraged or anything. Um, I'm just trying to, we're just trying to build like a general intuition and be able to recognize patterns and stuff. But yeah, we'll see you in the next lesson.

Welcome back. Uh, in this lesson, we're going to cover what's called for loops. Um, a for loop is basically just a way that when you have a collection of things, for example, like a list, it's a way that gives you a chance to do something or interact with each item in the collection, if that makes sense. It will make more intuitive sense once we actually run the code, but, um, here's a list of things. We learned about lists, uh, recently, and it gets assigned to this variable, and then this is the actual for loop, um, how it's structured, and then, you know, the code ends here. So, we'll just run it, and I'll just kind of explain things, um, as we go. So, I also, I also made the screen a bit bigger, but it made my run thing inside of here. So, I have to, like, you know, go in there, but we see the code breaks here, and then if we step, our fruits has these inside of it, and then this variable, this is like a placeholder variable. It can be anything. Um, but the way it's like the grammar syntax is like `for x in whatever your collection or your list is`, and then it will give you a chance to, like, print out every single thing. So, for example, if we step into here, we notice that the variable `fruit`, that is this, it got assigned the value `apple`, which is this. And then we print it. `I like apple`. And then it goes back up here. And if we step again, now the `fruit` is assigned `banana`, which is here. We step, it will print `banana`. Step again. And now finally, `fruit` got assigned `cherry`. And then we step. It prints `I like cherry`. And then it finishes. It gets out of the loop because it, we say iterated, but it went over each of the items. And now the program ends. And, uh, this, like I said, this variable is arbitrary. It can be named anything. So, `for whatever in my_list`, uh oh, `for whatever in my_list`. So, for example, I can make this like, you know, some arbitrary variable like so, it can be anything, right? So, if I run this, the same output happens. `I like apple`. `I like banana`. `I like cherry`. Like so. That's pretty much, that's pretty much all it is. Same thing. I just want to show you that this variable is arbitrary. Um, see 1, 2, 3. It can be anything. Boom. Debug this. And we can, this is why debugging is so important when you're trying to get an intuition for things like loops, like how it works. It's basically like going over each one of these items in the list, and it's giving you a chance to to do something with it, right? But, for example, um, to add a little bit more logic in here, we can say like, you know, this is like really contrived, but I'll put this back to, I'll say `f`. This is also like a common practice to do. But we can say like, um, we can say `if f != apple`, for example. This means `!=` does not equal. We can say print `f` something like this. So, for example, debug this. And then `for f in fruits`, `f` gets assigned `apple`, which is the first one. We can say `if f != apple`, we're going to print the fruit. We're going to print `f`. But it does equal `apple`. So, this actually gets skipped the first time. And then we can say like `continue` to just finish the rest of the program. And you can see that it printed everything out except for `apple`, as we just, you know, decided to not do it. This is some like really arbitrary logic. But for an example of how we are going to use this, um, when it comes to our AI SOC analyst in like the real world, um, we might have something like, uh, for example, for example, actually, I'm going to, uh, format this. By the way, I'll put this, uh, in the link, this this file, so you don't have to do all of this. I'll format document. Oops. Format document with black formatter. Oh, can you like cut this whole thing out? Who, who's ever editing this? Let me set this up. Okay, you can like start recording again. Uh, so another example of how we might use this. Um, this is like a big list of threats. This is like from our actual like AI SOC analyst video, and I'll, I'll put this file in the description or, you know, a link down below or something. Um, so you can just like download it if you want, but I'm just going to show you something like a real-world example of, um, how a list might be used. So, this is actually like, or rather, how a for loop might be used. So, this is like a big list of threats, um, that the AI SOC analyst found, for example. And we can, like, maybe after the code runs, after it did its whole threat hunt and found them, we might do something like, you know, print out all the threats. So, we'd say like, `for threat in threats`. We could say like, you know, print `threat`, something like really like simple as this. And we'd say like, print `finished`, just to show that our, our thing is finished. Something like like this. And if we just run this, I'll just run it. And you see it just dumps like all the threats out onto the screen. And say we don't want to, like, dump the whole thing. Maybe we just want to, like, dump the threat title. So, like, this is a collection, right? It's a, it's a list of, uh, dictionaries, or a list of JSON objects essentially. So, we know that there's like a `title` key with like a, the value key-value pair. So, we know that there's a key called `title`. So, we can, like, copy this. For example, I'll collapse this. We can say print `threat['title']` like so. We can break this, start debugging, and we see it breaks, and we see the threat. You know, the threat, which is like our, we say the iterator. This is the thing that represents each individual item every time the the loop runs. And inside each threat is like a full-on like JSON object dictionary thing. And if I want to print the title, I can do like this. I can just say `threat['title']`. So, and then it will print, and then it just prints the title only of the threat, for example. And these are like actual real threat logs. And again, I just want to say like, this, this is the iterator. It can be like literally anything, any easy variable. Um, it's just, it's like a placeholder. It's going to hold the value of each individual item that's in the collection or in the list in our case. So, I'll run this one more time just to give you a sense. I renamed the thing to `x`, and see `x`. It just has the, um, the value of whatever these individual threats had in them. So, same thing, print the titles like so. Yeah, that's lists. It's just, uh, or rather, that's for loops. Um, it just lets you iterate. We see like, it lets you iterate over every item in a collection. Just like a really common collection is lists. So, I just used lists for example on this. But we'll see this, um, a decent amount in the actual like production code, I guess, that we're going to make. Hope that makes sense. Um, feel free to experiment it with a bit, and then we'll see you in the next lesson.

Welcome back. Uh, this is going to be the lesson on functions. This is where it starts like getting kind of hard for people, but a function is like an integral, integral part of just coding in general. So, you really need to like make sure you understand it. But, um, basically, um, a function is when you want to reuse the same code many times without having to type the same code out many different times. So, I'll just like give you a really simple example. So, this is like a really simple example. So, the notation for how to make a function, you say `def` and then I'll say like `introduction`. I'll just name it `introduction`, and then this is the indent. Um, everything that's indented under, like, after this function definition is going to be part of the function. So, I'll say like, `print("Hello, my name is Josh")` for example. `print("My favorite food is cake.")` `print("I'm 67 years old.")` for example. And then now, now I'm technically outside of the function. So, this, you have to call what's called call the function in order for it to run. So, for example, if I, I'm outside of the function now because I like erased the indent, I guess you can say, and I'll say `print("It's Saturday.")`. So, and then if I just run this, for example, you notice it says, it only says `It's Saturday.`. Like, none of this other stuff happened because I didn't call the function. So, to call the function, um, all you have to do is type, you just type the function name, `introduction()`. And then it will call it. I'll just run it with this button from now on. You can see it printed `It's Saturday. Hello, my name is Josh. I'm 67 years old.`. But you can call the same function like multiple times, like so. Like, instead of typing like this out like 10 times, you can just simply call the function a bunch of times, and it'll, it will just run the same code, if that makes sense. So, I'll, I'll break the code here and here. So, actually, I'll just break it here, and then I will start debugging. So, the code started, uh, the break, just like it didn't run the function, but it just stopped here. So, this is where the code actually starts. So, um, this is the difference between step into and step over. So, I'm just going to use step into, but I'll explain step over later. So, if I step into this, it will print `It's Saturday.`. This is the function, right? So, if I step into this, it actually shows that it goes into the function, and then it will print the stuff, and then the function will exit, and then it will go to the next one. And if I say step into, it will go into the function again, print the stuff, go to the next one, like so. You kind of get the idea if you, this is why debugging is really important because you can see the actual, like, flow of the code, right? You can see, like, what happens? So, I'm going to break this code again here. I'll show you, uh, what step over means now. So, if I debug this bug, so it stops here. If I step over, now, remember, if I step into, it will go into the function, and it will actually allow me to step over each line of code. But if I say like step over, it will execute the whole function. It won't go inside. It will just execute it immediately and then, um, pause on the next main line of the code, if this makes sense. And it doesn't look like anything's changing down here, but it is. Yeah, that's functions. You can have a lot, you know, a lot more stuff in here. For example, you can, you can do like, um, something like this, you know. So, what am I doing? Make an f, make these into an f-string. `name`, `age`, something like this. I'll just run this all the way through. Rather, I'll debug it. We step into, see, then the variables get assigned, prints. So, keep doing this so you can get a sense, you know, for what the function is doing. Cool. So, that's introduction to functions. Um, I'm going to, uh, take it a step further in this lesson. So, I'll, uh, I'll just leave this one actually. Um, yeah, let me, let me get rid of this, and then I'll make a new function. I'll stop this. So, you can, you can make functions take what's called an argument. So, for example, I'll define, oops, I'll define the same function again, `introduction`. But you can say stuff like, uh, um, you can, this will make intuitive sense, but you can define it with parameters `name`, `age`, `height`, for example, and you can do stuff like this, for example, um, `print(f"My name is {name}, I'm {age} years old and {height} centimeters tall.")`. So, and I can put like `name` in here, uh, `age` in here, and `height` in here. And by the way, people have like really hard time with this. Um, so if you're, sorry, I just woke up. If you're, if you think this is like kind of getting kind of difficult, um, a lot of people do, so like, don't worry about it, but I'll try to make it, uh, intuitive. So, um, this, when you define like, um, arguments or parameters that you can pass into the function, then you can make the function a bit more dynamic and useful. So, for example, if I call this, and for the name I pass in like Josh. For the age I pass in 50. For the height I pass in, uh, what's a good height? 200 cm. Then you can do stuff like this. I'll just, uh, debug this. It will break here. Do this, and then when this calls this, `name` gets assigned `Josh`, this `age` gets assigned 50, and then this `height` gets assigned 200, and then it will print like like this. It makes it a bit more dynamic. So, for example, what this means is we can use the same function, uh, but pass different parameters to it. I was, well, you can pass different things to it. So, for example, example, so I think Ken's 28, I'm not sure, for example, you can do this. This is the same function, but we're passing different parameters to it, or different arguments. So, it's going to print different things, even though it's the same function. So, and I'll, I'll give you like an idea of how this is like useful in the real world. But so we'll start debugging, and it will break here, and then we can get a sense. We see our local variables now, `age` 50, `height` 200, `Josh`. It will print down below. The next one, you see the variables change, `age` 90, 150, Miho, it corresponds to this, and it prints, etc., etc. And I'll, I'll make a new function definition, um, just to help you get a sense. So, I'll call this one `addition`, `number_one`, `number_two`, and I'll just keep printing these for now. `number_one`, `number_two`, something really, really simple like this. So, if we call this `addition`, we can say we just pass the two numbers that we want to add up. So, `number_one`, oops, equals 100, `number_two`, 200, like so. And then I'll break this here. And I will debug. And it breaks. So, then we step into it. It just will print the summation of these two numbers, 300. And then the code ends. And you notice that this function didn't, it never got called. We defined it, but we never called it. So, this is technically, we would say it's dead code. Dead code. Oh my god, I can't even. Or a dead function, because we don't call it. It's just like sitting there. It's like kind of bad practice to do that. But, and then we're going to take this like a step further, and we're going to talk about function returns. So, instead of just like printing something out, we're going to actually have the function do what's called like returning a value. And people like really have a hard time with this. Um, it's just one of those things that takes some getting used to. So, for example, I'm just going to get rid of this. And then instead of like printing out the numbers, I'm

nous allons les combiner dans une variable, puis retourner cette variable. Donc, euh, nous l'appellerons la somme de nos nombres égale et je vais définir cela comme num un plus num deux. Et puis nous retournerons ceci de notre num comme ceci. Et puis nous pourrons dire que nous pouvons l'appeler, euh, et nous pouvons retourner la valeur et la mettre dans une variable, puis l'imprimer. Et je vais vous montrer ce que cela signifie. C'est un peu complexe et il faut du temps pour s'y habituer, mais bref. Nous allons donc créer une autre variable appelée notre nombre. Et c'est ainsi que vous faites cela. Vous dites égal addition. Et puis nous passerions une valeur à number one. Donc 50 et puis une valeur à number two. Euh, quelque chose de facile, 25. Ensuite, nous pouvons imprimer notre nombre. Et c'est pourquoi le débogage est vraiment important car vous pouvez voir le flux de tout ce qui se passe. Je vais donc casser cela, l'enregistrer, puis nous exécuterons le point d'entrée. Donc, en gros, j'expliquerai ce qui va se passer. Cette fonction appellera comme ceci, puis l'interpréteur monte ici. Maintenant, nous voyons que number one est 50 et number two est 25 car nous avons passé 50 à number one et 25 à number two. Donc, lorsque le code s'exécute ici, nous pouvons voir que ce sont les valeurs, puis elles vont être ajoutées, puis mises dans la somme de nos nombres. Donc, si nous passons par-dessus ceci, nous voyons que la somme de nos nombres est 75. Et puis lorsque ce code s'exécute, il va retourner cette valeur ici et l'assigner à notre nombre. Donc, si nous cliquons sur ceci, nous voyons que le retour est 75. Et puis lorsque nous avançons, nous voyons que notre nombre reçoit la valeur 75. Et maintenant, il va simplement l'imprimer à l'écran, puis le programme se termine. Je vais donc faire cela plusieurs fois pour que vous puissiez avoir une idée. Un un 3 cinq six. Je vais donc casser cela, exécuter le débogage, puis nous pourrons avancer lentement et essayer de comprendre ce qui se passe. Oh, euh, eh bien, c'est bon. Cette variable va être écrasée à chaque fois, mais ce n'est pas grave. Donc, si nous entrons dans ceci, nous voyons que number one est 50, two est 25 car nous l'avons passé ici. Ils ont ajouté la somme de nos nombres, c'est 75. Elle est retournée. Et maintenant notre nombre est égal à 75 actuellement. Mais maintenant, cette fonction va appeler à nouveau. Si nous entrons dedans, nous voyons maintenant que number one est 51. Number two est 21 à cause de ceci. Additionnez-les. 72. Nous avançons, 72 est retourné. Donc, 72 est retourné. Notre nombre est toujours égal à 75, ou plutôt, il contient toujours 75 de l'appel de fonction précédent. Mais si nous avançons, il va aller à 72 de cet appel, qui va être assigné à notre nombre, ce qui vient de se passer. Si nous exécutons ce troisième, vous pouvez voir que ceux-ci ont été passés, ils sont ajoutés à quatre. Il est retourné, puis notre nombre est toujours égal à 72, mais une fois que nous avançons, il est maintenant égal à quatre à nouveau. Ensuite, le dernier va appeler. Voyez ceci changer. Ils sont ajoutés à 11. Il est retourné. Le retour est 11. Maintenant, il va écraser notre nombre. Il va stocker 11 dans notre nombre. Et puis il va imprimer 11 à l'écran comme ceci. Oui, ce sont les fonctions. Euh, assez basique. Il y a un peu plus, bien sûr, que vous pouvez faire avec elles, mais c'est si vous pouvez arriver à ce point où vous pouvez comprendre ce qui se passe ici, vous serez en très bonne posture. Et la façon dont j'apprends personnellement le codage, j'ai, je suis à peu près sûr que j'ai, j'ai un TDAH et probablement un peu d'autisme. Et je n'apprends pas très bien le codage à partir de cette théorie et de définitions rigides et de choses comme ça. J'apprends davantage par la mise en correspondance de modèles et si vous faites ceci, alors ceci se produira, et si vous faites ceci, alors ceci se produira. Donc, cela pourrait vous aider si vous voulez y penser dans ce sens. Euh, cela peut aider. Je ne sais pas. Euh, mais les fonctions, les fonctions sont utilisées, utilisées assez souvent. Comme nous pourrions faire quelque chose comme, euh, j'ai un deck ou j'ai du code qui crée des cartes mémoire. Euh, eh bien, ce n'est probablement pas un bon exemple. vous pouvez effacer ça. Donc, nous allons probablement utiliser du code à l'avenir, euh, où une fonction est quelque chose comme je ne vais pas vraiment écrire la fonction, mais elle s'appelle demander à chat GPT et ensuite vous passeriez l'invite dedans comme ceci et il y aurait du code, euh, je vais mettre un commentaire, euh, du code qui contacte GPT et pose une question, puis GPT retournera la réponse ou quoi que ce soit. Je vais juste mettre la réponse de GPT. Je vais mettre une interpolation de chaîne. Donc, je vais mettre comme invite invite et puis je vais faire une nouvelle ligne et puis je vais dire comme la réponse de GPT peut-être la réponse de GPT comme XYZ quoi que ce soit et puis vous appelleriez ceci par, vous savez, vous diriez comme, euh, ma question, vous pouvez faire quelque chose comme ceci, par exemple, ma question, entrée, que voudriez-vous demander à chat GPT, par exemple, quelque chose comme ceci, puis nous pouvons dire, euh, demander à chat GPT, appeler notre fonction, puis nous passerions ma question ici comme ceci, comme ceci. Et nous allons exécuter ceci pour que vous puissiez avoir une idée. Euh, normalement, il y aurait un tas de code ici qui, vous savez, contacte GPT et toutes ces choses, mais je veux juste vous montrer quelque chose. Oh, oui, je dois aussi retourner ceci. J'ai oublié. D'accord. Donc, ma question, la chose de la question est, et puis nous dirions, euh, je suis à l'intérieur d'une VM en ce moment, donc, euh, c'est vraiment lent et gênant. Euh, d'accord. Comme ceci. Nous disons imprimer la réponse comme ceci. Donc, je vais juste expliquer cela au fur et à mesure. Je vais l'exécuter plusieurs fois pour que vous ayez une idée. Donc, nous commençons le débogage. Nous allons casser ici. Maintenant, je vais passer par-dessus ceci. Que voudriez-vous demander à Chad DPT ? Euh, quel est le, j'aurais dû, c'est pourquoi il est important de faire le backslashn ici car vous voyez que ça tape sur la même ligne. C'est un peu ennuyeux. Je vais le réexécuter. Je vais passer par-dessus ceci. Que voudriez-vous demander à Chad GPT ? Quel est la meilleure race de chat au monde ? Et puis vous voyez que ma question est quelle est la meilleure race de chat au monde assignée à elle. Ensuite, nous appelons ask chatb chat GBT et nous passons ceci, quelle est la meilleure race de chat au monde à l'intérieur, ce qui est ma question. Donc, lorsque nous entrons dans la fonction, nous voyons que l'invite a maintenant la valeur quelle est la meilleure race de chat au monde comme ceci, puis vous savez, du code se produit, etc. Et puis chat GBT trouve une réponse. Mais dans la réponse, j'ai simplement remis l'invite. Et puis j'ai inventé, vous savez, la réponse est XYZ car nous n'avons pas vraiment demandé à Chad GPT. Et puis la réponse sera retournée comme ceci. Et nous pouvons voir, nous pouvons voir quelle est la valeur de retour. Et puis il n'y a pas encore de variable de réponse ici. Mais lorsque nous avançons, la réponse est assignée à l'invite. Ensuite, la réponse de chat GPD. Donc, si nous passons par-dessus ceci, il va imprimer et puis le code se terminera. Donc, invite quelle est la meilleure race de chat au monde ? Réponse de GPD XYZ. Et probablement, nous n'avons probablement pas nécessairement besoin de cela juste pour la lisibilité. Donc, je vais l'exécuter une fois de plus, puis nous pouvons terminer la leçon. Donc, je débogue, j'entre dans ceci. Que voudriez-vous demander à chat dbt ? Euh, oh non, quelle race de pastèque est la meilleure et nous voyons que cette question, quelle race de pastèque est la meilleure, euh, elle est passée à chat GPT, euh, vous savez, faites semblant que nous avons utilisé notre invite pour demander à Chad GPT la question, l'invite reçoit ceci, la réponse, nous obtiendrons, vous savez, ceci de Chad GPT, la réponse est ceci, puis est retournée. Nous voyons que le retour est ceci, la réponse de GPD est XYZ, puis nous voyons qu'elle est assignée à la réponse, puis la réponse sera imprimée, la réponse de GPD est XY XYZ. Donc, ce sont les fonctions. Euh, nous verrons, nous verrons beaucoup de cela lorsque nous entrerons dans le code, l'analyste de socket IA que nous fabriquons. J'espère que cela a du sens. Euh, il est vraiment très important de comprendre cela, juste en général. Euh, c'est essentiel pour tout type de développement. Donc, si vous avez des questions, allez sur, vous savez, la communauté du cyber-range ou, vous savez, la communauté où que vous soyez, posez des questions aux membres de la communauté, utilisez chat dbt pour vous aider à comprendre, aidez-vous à expliquer les choses, donnez-vous peut-être quelques exemples supplémentaires. Euh, oui, nous vous verrons dans la prochaine leçon. Bienvenue. Euh, dans cette leçon, je vais parler des modules intégrés. C'est essentiellement, euh, quelque chose inclus dans Python que vous pouvez importer, euh, dans votre code, euh, et l'utiliser simplement pour faire certaines choses. Donc, par exemple, euh, pour le faire, vous utilisez simplement la commande import, puis le nom du module que vous souhaitez importer. Et il y en a beaucoup, d'ailleurs. Euh, vous n'avez pas besoin de tout mémoriser. Même à la volée, je ne peux penser qu'à deux ou trois pour une raison quelconque, mais il y en a beaucoup. Et c'est juste du code supplémentaire que vous pouvez importer pour faire des choses. Et je vais vous montrer comment, euh, créer un module personnalisé, euh, local dans la prochaine vidéo, mais juste pour avoir une idée intuitive de ce qu'ils sont et comment les utiliser. Donc, par exemple, vous pouvez faire différentes choses avec cela. Euh, vous pouvez, vous pouvez, euh, mettre en pause le flux du code, par exemple. Donc, par exemple, euh, je vais dire, je vais juste imprimer un tas de messages aléatoires. Euh, je ne sais pas, bonjour. Quelque chose comme ça. Et si je fais ça, vous savez, je ne vais pas le déboguer, je vais juste l'exécuter. Exécuter sans débogage. Et vous verrez qu'il imprime juste bonjour à l'écran, n'est-ce pas ? Mais avec le module time, par exemple, vous pouvez dire des choses comme time. par exemple, puis le nombre de secondes pendant lesquelles vous voulez que le programme s'arrête. Donc, par exemple, copiez ceci et faites-le plusieurs fois ici. Je vais faire 1 seconde, peut-être dormir pendant 3 secondes, 2 secondes. Oui, 1 seconde pour celle-ci. Et puis, je ne sais pas, 5 secondes. Non, 3 secondes. D'accord. Et puis si j'exécute ceci, euh, il va s'exécuter. Je ne débogue pas, n'est-ce pas ? Et vous pouvez voir qu'il imprime. Et puis vous pouvez voir qu'il fait une pause pendant quelques secondes et il imprime encore trois pauses un peu. Euh, parce que j'utilise le module sleep pour, euh, mettre en pause le flux du code. Euh, si cela a du sens. C'est juste quelque chose que vous pouvez faire. Le point de cette leçon est que vous pouvez importer des choses dans votre code, puis vous pouvez faire, euh, des fonctionnalités supplémentaires sans écrire le code vous-même, si cela a du sens. Donc, si je supprime ceci en fait, euh, vous voyez que, euh, cela devient une erreur de syntaxe ou une sorte d'erreur et si j'essaie de l'exécuter, euh, cela ne fonctionnera pas, vous savez, cela ne fonctionnera pas. Il dira que time n'est pas défini. Avez-vous, avez-vous oublié d'importer time ? Et vous pouvez, euh, survoler ceci avec votre souris et vous pouvez dire correction rapide, puis vous pouvez dire, euh, ajouter, ajouter l'importation de time, puis cela les corrige toutes. Et il y en a d'autres aussi. Il y a, euh, random believe. Donc, si j'ai une liste de, vous savez, les meilleurs animaux, je vais devoir utiliser GPT pour faire ça. Mais chat, chien, renard, bras, hibou. Je crois que vous pouvez faire, euh, comme le meilleur. Je pense que vous pouvez faire random, puis oh, choix. D'accord. Et puis vous passez la collection des choses parmi lesquelles vous voulez choisir comme ceci. Et puis, euh, je vais juste, en fait, je vais juste faire ce seul meilleur animal. Cela a plus de sens. Et puis je vais juste l'imprimer. Ce n'est pas ce que j'ai fait. Donc, donc je vais casser ceci et nous allons déboguer. Et nous pouvons voir, euh, ce random, qui est ceci. C'est un module. Donc, si nous passons par-dessus ceci, nous voyons nos meilleurs animaux. Chat, chien, renard, barre. Et puis je crois que ceci va juste choisir un animal au hasard parmi ici. Je crois que random choice, euh, chien. Chien a reçu un seul meilleur animal. Et puis il va imprimer chien. Et vous pouvez, vous pouvez faire des randoms pour, euh, choisir des nombres aléatoires aussi. Comme si vous voulez, euh, choisir un nombre aléatoire pour quelque chose. Et juste pour vous montrer que c'est aléatoire, je vais imprimer le même code plusieurs fois. Et il va probablement choisir un animal différent ou, vous savez, il va choisir un animal au hasard. Donc, je vais juste exécuter ceci sans débogage. Oh, ma faute. J'étais censé imprimer ces choses en fait. Attendez. Faites ceci. Oh, et puis je vais juste exécuter ceci sans débogage comme ceci. Et puis oh, c'est tellement intéressant. Chat, renard, ferme. Oh, oui. Oui, c'est relativement assez aléatoire. Je pensais que c'était moins aléatoire, mais laissez-moi faire ceci plusieurs fois. Oui. Et vous voyez comment c'est irrégulier dans l'ordre, euh, dans lequel il montre les différents animaux car il les choisit au hasard, si cela a du sens. Mais oui, c'est à peu près tout ce que je voulais montrer dans celui-ci. Je voulais juste vous faire prendre conscience de l'existence des modules. Et il y en a, nous allons utiliser beaucoup, juste une tonne de modules, puis créer les nôtres également. Et il y a même, euh, il y a un module open AI pour, euh, traiter avec chat GBT et, euh, il y a littéralement des modules pour tout et il suffit de s'habituer à les utiliser. Euh, ils étendent simplement le type de code que vous pouvez faire et vous permettent de faire différentes choses. Mais lorsque nous commencerons à construire l'agent, euh, vous verrez des exemples de différents modules, et au moins vous saurez ce que vous regardez au lieu que ce soit juste du code aléatoire. Euh, mais oui, nous vous verrons dans la prochaine vidéo où nous créerons notre propre module personnalisé, puis l'utiliserons un peu. Alors, attendez-vous à cela. Cool. Bienvenue et nous allons créer notre propre module personnalisé, euh, dans cette leçon. Donc, effacez ceci et laissez-moi réfléchir, je vais faire quelque chose de vraiment, vraiment simple pour commencer. Donc, ceci est main, ceci est comme notre principal, euh, vous savez, notre code Python principal, je suppose. Donc, dans le dossier code, allez-y et créez un nouveau fichier. Nous l'appellerons keys.py. keys signifie mots de passe. Oh mon dieu. keys.py et puis à l'intérieur de keys.py, nous allons créer une variable ici, tout en majuscules, mon mot de passe, et puis lorsque vous mettez tout en majuscules en Python, cela signifie que cette valeur n'est pas censée changer. Nous l'appelons un, je pense que c'est comme, ne me citez pas sur ça, je pense que cela signifie comme un, euh, laissez-moi chercher ce que signifient toutes les majuscules en Python. Je veux dire comme variable statique, mais, euh, je pense que c'est correct. Oh oui, ce n'est pas censé changer. Oui, je pense que c'est ce que j'ai dit. Donc, ce n'est pas censé changer. Donc, c'est juste une variable, n'est-ce pas ? Mais c'est comme un mot de passe, n'est-ce pas ? Cyber lab 1 23 par exemple. Juste pour exemple. Et puis, donc nous avons créé un module appelé keys. Donc, nous pouvons dire, euh, import ease comme ceci. Donc, et puis nous pouvons dire, euh, imprimer ease.mon mot de passe. Vous voyez que cela sort. Et puis si nous exécutons ceci, je vais juste, oui, je vais le déboguer. Donc, si nous exécutons ceci, puis que nous disons entrer dedans, cela imprime simplement le mot de passe comme ceci. Même s'il n'y a pas de CyberLab 123 ici, mais à l'intérieur de keys, c'est ici. Et puis nous avons importé le module keys et puis nous avons pu imprimer ceci. Et cela ne doit pas être capitalisé, soit dit en passant, mais c'est une convention lorsque vous définissez une variable, elle n'est pas censée changer. Donc, si vous pouvez dire, vous savez, euh, je vais changer ce petit mot de passe et je vais faire mon VM, je veux juste vous montrer que cela n'a pas vraiment d'importance, vous savez, si c'est en majuscules ou non. C'est juste une convention. Mon mot de passe de machine virtuelle. Nous appellerons celui-ci comme lab user, vous savez, quelques caractères. Et nous allons l'enregistrer. Et si nous revenons ici, nous pouvons imprimer keys.mon mot de passe gmail. Peut imprimer keys.mon mot de passe VM. Donc, et je vais juste exécuter ceci sans, je vais le déboguer, déboguer. Et puis nous pouvons voir qu'il imprime cyberlab 123 et ceci imprime lab user bla bla bla. Euh, et quelque chose que vous pouvez faire dans VS Code, vous pouvez faire glisser cette fenêtre vers le bord pour que vous puissiez voir les deux. Cela peut être pratique. Euh, si vous voulez voir ce qu'il y a dans votre module ou si vous voulez voir plus d'un fichier à la fois. Donc, par exemple, laissez-moi effacer ceci. Et vous pouvez en fait, euh, je vais renommer ceci. Euh, non, je vais laisser le même nom. Donc, je vais enregistrer ceci, ceci. Et puis vous pouvez mettre plus de choses ici qui ne sont pas juste des variables, n'est-ce pas ? Vous pouvez y mettre une fonction entière. Donc, je vais dire définition, euh, je vais appeler ceci, multiplication, et puis number one two, et puis je vais juste dire, euh, product égale number one fois number two, puis nous retournerons product. Donc, j'ai oublié ceci. Euh, je vais renommer ceci keys en fait en math. Je vais le renommer en new math car il existe déjà une fonction math. Donc, je vais appeler ceci, euh, new math, quelque chose comme ceci. Et puis vous pouvez importer new math comme ceci. Et puis je peux dire, euh, mon nombre égale et je peux appeler new math. C'est ainsi que vous accédez à la fonction à l'intérieur et vous diriez, euh, num one égale, euh, tout le monde sait ce qui n'est pas peut-être pas, je ne sais pas, euh, 2 * 3 est donc number one, je vais le définir comme 2 et puis number two, je vais définir number two comme 4, comme ceci. Et je vais faire ceci plusieurs fois. Donc, je vais copier ceci plusieurs fois. Un et trois, cinq et six. J'ai réalisé que je n'avais pas mis d'espaces ici. Cela n'a pas d'importance, mais juste pour la lisibilité. Donc, je vais casser ceci ici. Je vais l'enregistrer et je vais commencer le débogage, ça casse ici. Et puis si vous entrez dans ceci, vous pouvez voir que le code va en fait vers l'autre module et vous pouvez le voir faire des choses. Donc, et vous pouvez voir que la variable locale number one est égale à deux, ce qui est ceci. Number two est égal à quatre. Ceci a été multiplié et product est égal à 8. Et puis 8 va être retourné. Nous pouvons voir, je vais rendre ceci, je vais rendre ceci un peu plus petit pour que nous puissions voir. Désolé. Et nous pouvons voir que 8 a été retourné. Et puis si nous avançons, nous voyons que mon nombre est maintenant égal à 8. Si nous entrons dans celui-ci, new math, n'est-ce pas ? Multiplication. New math multiplication. Et puis il ajoute. Il va, vous savez, faire son truc. Multiplier les nombres. Product est égal à 1 * 3, ce qui est trois. Retournez-les. Nous pouvons voir que trois a été retourné ici. Et puis mon nombre est toujours égal à 8. Donc, si nous entrons dans ceci, euh, il est maintenant égal à trois. Et puis, vous savez, je vais juste continuer le code. Donc, et puis il se termine. Nous n'avons rien imprimé dans celui-ci. Nous avons simplement inspecté dans la mémoire. Donc, la raison entière de ceci est que cela va nettoyer votre code et le rendre plus modulaire. Je suppose que c'est pourquoi ils s'appellent modules. Mais dans la vie réelle, euh, vous finirez par avoir beaucoup de fonctions différentes et les fonctions auront des fonctionnalités différentes et cela finira par être beaucoup. Donc, il est plus logique de mettre du code spécifique dans leurs propres, euh, dans leurs propres modules, puis d'appeler simplement les modules dans votre fichier Python principal, je suppose. Donc, c'est plus facile à lire et plus facile à digérer et à regarder, et c'est plus facile de changer les choses. Donc, ce sont les modules. Euh, nous allons utiliser à la fois les modules intégrés comme, par exemple, time ou pas time, oui, time et puis math. Il existe en fait un module appelé math. Euh, il est intégré. Donc, par exemple, si nous disons imprimer comme math, euh, je pense que nous pouvons juste dire comme math.py, n'est-ce pas ? Et il va juste imprimer pi par exemple comme ceci. Il a imprimé pi. Et puis il y a aussi math square root qui est la racine carrée de 9. 3 * 3 font neuf, n'est-ce pas ? Donc, cela devrait imprimer trois. Donc, euh, il y a beaucoup de modules intégrés comme celui-ci, une tonne d'entre eux, et puis nous allons les utiliser, euh, dans le code de l'analyste de socket IA où nous construisons cette chose, mais nous allons également créer beaucoup de nos propres modules personnalisés. Donc, je voulais juste vous les exposer juste pour vous donner une idée, donc lorsque nous arriverons à cela et que nous commencerons à les gérer, au moins vous aurez une certaine compréhension, une compréhension de cela. Mais oui, ce sont les modules, les modules intégrés, puis les modules personnalisés/locaux également. Donc, oui, nous vous verrons dans la prochaine leçon. Cool. Bienvenue. Bienvenue dans la leçon sur la gestion des erreurs. Je veux juste vous montrer ce qui est possible. Vous n'avez pas à mémoriser toute la syntaxe et tout le reste, mais je veux juste vous donner une idée de ce que c'est et pourquoi vous pourriez l'utiliser. Donc, euh, en gros, la gestion des erreurs est un moyen qui vous permet de gérer gracieusement quelque chose lorsqu'une erreur se produit, euh, en Python ou dans n'importe quel langage de programmation. Donc, par exemple, si vous vous souvenez, nous pouvons faire des choses comme ceci. Euh, nous pouvons dire, euh, mon nombre mon [renifle] nombre égale, euh, 10, n'est-ce pas ? Ceci est comme un entier ou un nombre. Mais si nous faisons quelque chose comme ceci, mon nombre égale 10 et puis votre nombre égale 20. Nous ne pouvons pas faire, euh, nouveau nombre égale mon nombre plus votre nombre car mon nombre, ceci est une chaîne. Votre nombre est un entier, et vous ne pouvez pas ajouter un nombre à une chaîne. Cela n'a pas de sens pour Python. Donc, par exemple, si nous, oops. Nous essayons de faire ceci. Je vais casser ceci et je vais juste avancer. Donc, nous obtenons, nous obtenons cette grosse chose rouge effrayante, euh, où c'est comme une exception qui s'est produite. Erreur de type, ne peut concaténer que des chaînes, pas des entiers. En gros, cela dit que vous ne pouvez pas additionner un nombre dans une chaîne car cela n'a pas de sens. Mais, vous savez, nous pouvons faire quelque chose comme ceci. Euh, voyez mon nombre, nous pouvons, nous pouvons le convertir. Par exemple, juste pour rappel, si nous exécutons juste ceci, je vais juste l'exécuter. Nous remarquons que cela fonctionne, n'est-ce pas ? Donc, afin de, euh, empêcher, je vais exécuter ceci à nouveau. Afin d'empêcher cette chose folle de se produire ou, euh, ces erreurs et d'avoir le programme qui plante, nous pouvons utiliser quelque chose appelé, euh, un bloc try accept, et cela nous donne une opportunité de, euh, attraper toutes les erreurs et de laisser le programme se terminer, euh, sans planter essentiellement. Donc, en gros, cela ressemble à ceci. nous utiliserons comme try et puis nous indentons ceci et puis nous dirons comme accept et puis vous pouvez mettre plus ici, mais je vous montrerai cela plus tard. Accept. Et puis c'est ce que vous voulez qu'il se passe, euh, si une erreur se produit ici. Donc, peut-être que nous voulons imprimer quelque chose à l'utilisateur, euh, un message d'erreur s'est produit. Euh, réessayez quelque chose et puis nous pouvons dire imprimer finish dire comme d'habitude, puis si nous exécutons, si nous exécutons ceci. Donc, nous voyons mon nombre, votre nombre, puis il va tenter de faire ces choses. Donc, et puis il n'a pas pu le faire car une erreur s'est produite car vous ne pouvez pas ajouter un nombre dans une chaîne. Donc, au lieu d'imprimer ceci, il est immédiatement entré dans le bloc accept. Et puis il va imprimer un message d'erreur s'est produit. Réessayez. Et puis le programme se termine sans, euh, planter. Euh, notre action ne s'est pas produite, mais le programme, euh, il n'a pas planté comme ceci. Une erreur, il a juste dit qu'une erreur s'est produite au lieu de montrer cet écran rouge fou. Euh, donc si vous voulez afficher exactement quelle était l'erreur, nous pouvons dire quelque chose comme ceci. Donc, nous pouvons dire except exception as, et puis ceci, ceci est juste une variable aléatoire. Donc, nous pouvons dire, euh, je veux juste vous montrer que vous pouvez mettre n'importe quoi ici dans cette variable, et puis cette chose stockera les informations d'exception. Donc, je vais utiliser une interpolation de chaîne ici et je vais dire, euh, une erreur s'est produite et je vais dire, euh, nouvelle ligne, donc, et puis je vais mettre la girafe. Cette girafe stocke les informations d'erreur. Donc, par exemple, et exécutez ceci. Je vais juste, euh, je vais le déboguer pour que nous puissions vraiment voir. Donc, étape, il va essayer de faire cette action impossible, échec. Maintenant, nous voyons que la girafe contient les informations d'erreur. Vous ne pouvez concaténer que des chaînes, pas des entiers, à des chaînes. Donc, et puis vous voyez qu'il imprime et puis le programme se termine comme ceci. Donc, cela peut être, euh, assez utile de certaines manières. Euh, par exemple, euh, disons qu'au lieu de coder en dur, euh, ces nombres ici, nous pouvons dire quelque chose comme, euh, je vais, euh, faire ceci. Nous pouvons dire que cela va devenir un peu compliqué. Euh, mais nous pouvons faire une boucle infinie, tant que vrai. Et puis nous allons indenter ces choses et les mettre, les mettre à l'intérieur de la boucle comme ceci. Et puis pour mon nombre, nous pouvons dire, euh, nous allons dire mon nombre. Cela va devenir un peu compliqué, mais je vais avancer et vous pourrez comprendre la logique derrière cela. Donc, mon nombre égale entrée, s'il vous plaît, entrez un nombre comme ceci, puis, euh, nous allons, nombre, mon nombre, ou nous allons convertir ceci en int. Donc, car lorsque vous faites ceci, ce sera toujours une chaîne. Ceci sera toujours une chaîne. Donc, nous devons essayer de le convertir en int si nous voulons l'ajouter à votre nombre, qui est également un entier. Et puis nous allons l'imprimer ou nous allons dire, vous savez, j'utiliserai une chaîne F. Vous plutôt. Oui. Oui. Ici, nous allons l'imprimer. Nos, oops, nos nombres combinés, juste quelque chose de très simple. Et puis, euh, nous devons, eh bien, je vais vous montrer quelque chose. Je vais juste exécuter ceci tel quel maintenant ou non. D'accord. Ou et puis quand nous aurons fini, nous utiliserons break. Et break est un moyen de vous forcer à sortir de la boucle infinie, n'est-ce pas ? Mais si la personne entre quelque chose ici qui n'est pas un nombre, cela tentera de le convertir en nombre. Donc, par exemple, si elle entre chat, cela tentera de le transformer en nombre. Cela échouera. Cela affichera l'erreur à l'utilisateur. Et puis parce que nous sommes dans une boucle infinie, cela demandera à nouveau à l'utilisateur son nombre. Et cela continuera jusqu'à ce qu'elle entre quelque chose qui est correct. Comme cette ligne passera, le nombre sera imprimé, puis la boucle sera interrompue. Donc, je vais juste, euh, exécuter ceci et vous verrez exactement ce que je veux dire. C'est comme ce modèle est utilisé assez souvent. Euh, il est utilisé assez souvent en programmation. Donc, votre nombre est 20. Nous l'avons codé en dur. Je vais le retirer un peu, puis nous allons entrer dans cette boucle infinie, puis il va essayer, puis il va demander notre nombre. S'il vous plaît, n'entrez pas de nombre. Je vais entrer, je vais entrer 10. Je vais faire quelque chose de correct juste pour que vous puissiez le voir. Nous entrons 10. Il crée le nouveau nombre en ajoutant 10 à 20, ce qui fait 30. il l'imprime et puis il va s'interrompre, ce qui interrompt la boucle et il sortira automatiquement de la boucle comme ceci, puis le programme se termine. Donc, essayons de l'exécuter à nouveau. Euh, mais nous allons entrer quelque chose qui n'est pas un nombre. Donc, je vais, je vais entrer le mot chat. Ce n'est pas un nombre. Donc, nous essayons de passer par-dessus ceci, cela échoue et va dans le bloc d'exception, et cela imprime une erreur à l'écran. Littéral invalide. Vous ne pouvez pas convertir chat en int, puis il retourne dans la boucle à nouveau. Il accepte, puis parce que tout cela est à l'intérieur de la boucle infinie, il continuera pour toujours jusqu'à ce que nous puissions passer ces choses et puis casser et puis sortir. Donc, par exemple, je vais juste, euh, étape, étape. S'il vous plaît, entrez un nombre, chien. Il essaie de convertir chien en entier. Il accepte ou échoue, imprime l'échec, puis continue pour toujours comme ceci. S'il vous plaît, entrez un nombre, puis finalement, si j'entre, disons 88 par exemple, c'est un nombre, donc cela passe, maintenant il va l'imprimer, puis il va s'interrompre, donc il sortira de la boucle comme ceci, oui, c'est, c'est utilisé, ce modèle est utilisé assez souvent, je l'utilise aussi, je ne veux pas aller trop loin dans les détails, mais en gros, et je veux dire une dernière chose, vous n'avez pas à mémoriser ceci, juste, je suppose, comprenez ce que je dis et reconnaissez-le. Il existe de nombreux types d'exceptions différents et le plus générique est appelé exception. Donc, par exemple, euh, je vais voir, quelle est la meilleure façon de faire cela. Euh, d'accord, par exemple, je vais effacer ceci et puis, euh, nous pouvons dire, voyons, nous pouvons dire, je vais juste, d'accord, je vais juste imprimer, disons, 10 / 0 pour exemple, puis je vais exécuter ceci, puis ceci, c'est une exception, division par zéro, c'est, c'est comme une exception spéciale, c'est comme une exception très spécifique par rapport à une exception générique. Donc, par exemple, si nous disons, euh, nous pouvons dire, essayez, oops, essayez, imprimer, oops, imprimer 10 / 0, j'ai du mal. Et puis nous pouvons dire, sauf les erreurs de division par zéro spécifiquement comme, et puis je vais, avant nous avions girafe ici, euh, mais la notation normale pour cela est, je crois, e, je crois que c'est la chose normale à faire. Ensuite, nous pouvons dire, euh, nous pouvons juste imprimer e, par exemple. Et puis si je, je vais déboguer ceci et puis il va essayer de faire ceci. Il a heurté une erreur de division par zéro. Donc, il est allé directement dans ce bloc et puis il va imprimer l'erreur, division par zéro. Et puis je pense que nous pouvons faire quelque chose comme ceci, un générique. Euh, en fait, laissez-moi faire ceci plus tard. Et puis je vais essayer de faire une autre opération illégale ici. Je vais imprimer un chien + 10 par exemple. Et puis je vais essayer de, je vais déboguer ceci en fait. Désolé. Laissez-moi, laissez-moi mettre ceci en premier. Laissez-moi redémarrer ceci. Donc, il va essayer d'imprimer chien + 10. Et puis en fait, il n'y a pas, euh, il n'y a en fait, nous n'attrapons pas ce type d'erreur spécifique. Et ce type d'erreur en fait, il s'appelle erreur de type. Étrangement, nous n'attrapons que les erreurs de division par zéro. Donc, je veux juste, je veux vous montrer le fait que vous pouvez attraper des erreurs très spécifiques ou vous pouvez juste attraper une erreur générale. Donc, par exemple, ce sera un peu confus, mais juste, euh, soyez patient avec moi. Nous pouvons, nous pouvons mettre, euh, une exception différente. Donc, par exemple, nous pouvons accepter, ceci est comme une exception générique, comme toute erreur, toute erreur générique ou qui n'est pas attrapée ci-dessus, tombera dans cette catégorie. Donc, par exemple, nous déboguons ceci. Et puis il va essayer de faire chien + 10, ce qui ne peut pas être fait. Donc, une erreur s'est produite. Donc, maintenant Python va commencer à vérifier les différentes exceptions que nous avons fournies. Donc, il vérifie une erreur de division par zéro, comme ceci. Cela ne correspond pas car ce n'est pas une erreur de division par zéro. Mais juste une simple exception acceptera toute erreur, quelle qu'elle soit, qui cause une exception ou une erreur, cela sera déclenché, etc. Mais si nous voulons attraper spécifiquement ce type d'erreur, nous pouvons dire, par exemple, accepter, euh, oh, j'ai oublié comment s'appelait l'erreur. Laissez-moi, laissez-moi juste exécuter ce code à nouveau pour voir ce que c'est. Je vais juste exécuter ceci pour pouvoir copier le type d'erreur. Euh, oh, c'est une erreur de type. C'est vrai. Erreur de type. D'accord. Donc, si nous voulons attraper ce type d'erreur spécifique, le nom est type error, comme vous pouvez le voir ci-dessous. Donc, nous pouvons dire, euh, accepter type error as e aussi. Et puis le, le but de ceci est que nous pouvons, nous pouvons faire, euh, quelque chose de spécifique si une erreur spécifique se produit ou nous pouvons dire quelque chose de spécifique à l'utilisateur, comme, vous savez, vous ne pouvez pas ajouter ou concaténer ces choses. Et puis cette erreur de division par zéro, nous pouvons dire, si nous voulons, nous pouvons dire, euh, n'avez-vous pas appris à l'école primaire que vous ne pouvez pas diviser par zéro ? Cela nous donne une chance de faire quelque chose de spécifique pour chaque type d'erreur. Et puis pour ce générique, comme, et c'est un scénario où, en tant que programmeur, nous ne savons pas vraiment ce qui pourrait mal tourner, mais juste au cas où cela se produirait, nous allons l'attraper ici. Donc, nous pouvons dire, euh, une erreur inconnue s'est produite. Donc, si vous avez vu ces erreurs dans Windows ou quoi que ce soit, cela signifie généralement que quelque chose d'inattendu s'est produit que le développeur n'avait même pas anticipé, mais il l'a quand même attrapé avec une exception générique. Donc, nous pouvons faire ceci comme ceci. Ensuite, nous pouvons, euh, exécuter ceci. Donc, je vais essayer de penser à quelque chose pour déclencher ceci. Oh, j'ai une bonne idée. D'accord. Donc, je vais essayer de faire ceci, chien + 10, cela crée une erreur. Donc, il commence à vérifier les différentes exceptions qui correspondent. Erreur de type correspond. D'accord. Donc, il va imprimer ces choses. Vous ne pouvez pas, vous savez, il va imprimer notre message personnalisé, puis il va imprimer l'objet d'erreur. Donc, une autre erreur que nous pouvons faire est que je vais importer le module JSON, puis nous allons essayer de charger du JSON invalide. Donc, euh, je vais juste dire, euh, mon objet égale JSON.load JSON.loads loads, baleine bleue. Ce n'est pas un objet JSON, donc cela devrait planter. Donc, nous allons exécuter ceci. [renifle] Ensuite, nous allons avancer et il va essayer de charger ceci dans un JSON. Il accepte immédiatement, il a lancé une erreur. Donc, maintenant, il va commencer à chercher quelle erreur il correspond. Il n'a trouvé aucune ici ou ici. Donc, il est juste allé ici. Euh, c'est comme le générique. Et puis nous allons dire qu'une erreur inconnue s'est produite. Et puis, acceptation de la valeur ligne 1. Il ne, il ne dit pas vraiment grand-chose en fait. Laissez-moi regarder à l'intérieur de cette erreur, à l'intérieur de cette variable E, car je ne me souviens pas de ce qu'il y a dedans. Exception est E. Donc, nous allons regarder à l'intérieur. Euh, oh. Oui, ce n'est même pas beaucoup de choses qui sont là-dedans. D'accord. Donc, si nous voulons attraper cette erreur spécifique, je vais, euh, faire planter le programme exprès et ensuite voir quelle erreur il lance. Comme ceci. Je vais juste commencer à déboguer ceci. Oh, il va, il va s'exécuter. D'accord. D'accord. Il va lancer une erreur ici. Donc, si j'avance, c'est l'exception qui a lancé l'erreur de décodeur JSON. Donc, nous pouvons copier ceci et nous allons terminer le programme et ensuite je vais accepter une nouvelle. Donc, je vais dire, euh, accepter l'erreur de décodeur JSON comme E. Ensuite, je vais dire, euh, imprimer votre chaîne JSON n'était pas valide. Et puis peut-être que je veux imprimer l'erreur réelle aussi. Qu'est-ce qui ne va pas avec cette erreur de décodage JSON ? Je me demande si je dois faire, c'est intéressant. J'ai dû retirer ceci de cette bibliothèque. Euh, oh. D'accord, bien. Donc, je vais déplacer ceci ici. Ce sont comme trois options illégales jusqu'à présent. Nous allons essayer de charger du JSON invalide, essayer de, vous savez, ajouter chien + 10, puis essayer de diviser par zéro. Et puis je vais vous montrer ce que l'objet JSON est censé être, un valide, juste pour que vous sachiez, mon JSON valide, mon objet valide JSON loads. Ce serait comme un valide. Nous pouvons dire, euh, oops, nous pouvons dire nom, nom, animal, nom, deux-points, baleine bleue. Donc, nous allons exécuter ceci à nouveau. Exécuter, démarrer le débogage. Je vais faire un autre exemple après celui-ci juste pour, j'espère que cela aide, et puis c'est une action valide, ou du moins elle devrait l'être. Oh, ce n'était pas le cas. Qu'ai-je fait ? Nom de l'animal, baleine bleue. Pourquoi est-ce que ce n'est pas valide ? Attendez. Laissez-moi, laissez-moi. C'est un, je vais laisser ça. C'est comme une bonne leçon, je suppose. Donc, je vais dire, [renifle] je vais juste dire, oui, qu'est-ce qui ne va pas avec ça ? Oh, je suppose que j'ai inversé les guillemets. Je ne savais pas que c'était un problème. Donc, je vais juste copier ceci. Oh, oui, peut-être. Oh, je suppose que je l'ai fait. Je suppose que je le savais. Donc, je vais coller ceci ici. Et je vais juste l'exécuter à nouveau. Le, la guillemet à l'extérieur, je suppose, est censé être un guillemet simple, je suppose. Donc, mon objet JSON valide, celui-ci est réel. Cette syntaxe est correcte. Mais ceci, euh, n'est pas, ce n'est pas une chaîne JSON. Donc, il ne peut pas être chargé en JSON. Donc, une erreur s'est produite et il va commencer à vérifier les différents blocs d'erreur pour voir lequel correspond. Et puis a trouvé que JSON, ceci est la même erreur qui s'est produite ici ou qui s'est produite. Donc, maintenant, il va imprimer ces choses. Votre chaîne JSON n'était pas valide. euh, attendu, quoi que ce soit, attendu valeur, bla bla, je ne sais pas, euh, c'est un très mauvais message, mais au moins nous avons pu faire un message personnalisé basé sur l'erreur qui s'est produite, donc peut-être que l'utilisateur peut savoir, n'est-ce pas, et puis je vais essayer de faire une chose de plus, euh, je vais créer un dictionnaire ici, un dict, dictionnaire, euh, et puis nous allons juste, euh, nommer Josh, hauteur 183. C'est un dictionnaire valide, n'est-ce pas ? Et il a, vous savez, il a les clés, les paires clé-valeur de clé nom, valeur hauteur, ou désolé, clé nom, valeur Josh, clé hauteur, valeur 183. C'est 6 pieds si quelqu'un se demandait. Et puis c'est tout ce que nous avons, nom et hauteur. Donc, nous allons aller ici et [s'éclaircit la gorge] nous allons essayer d'imprimer, nous allons imprimer, mon dictionnaire, nom, puis nous allons imprimer mon dictionnaire, euh, oui, âge. Donc, nom est à l'intérieur, mais âge n'est pas à l'intérieur. Donc, cela devrait aussi lancer une erreur. Donc, nous allons déboguer ceci à nouveau. Et vous voyez mon dictionnaire ici, nom Josh, hauteur 183. Donc, nous allons entrer ici. Nous allons essayer d'imprimer mon dictionnaire, nom. Et cela devrait imprimer quoi ? Imprime Josh. Et puis nous allons essayer d'imprimer mon dictionnaire, âge. Il n'y a pas de clé ici appelée âge. Donc, naturellement, cela lance une erreur et puis il va commencer à vérifier si nous avons géré cette erreur spécifique, et nous ne l'avons pas fait. Donc, il va juste dans le bloc d'exception, comme le bloc de gestion d'erreurs générique dit qu'une erreur inconnue s'est produite, puis il imprime juste âge, je suppose. Donc, si nous voulons gérer cela correctement, euh, nous devons voir, euh, quel est le type d'erreur réel. Donc, par exemple, nous allons prendre ceci et puis nous pouvons juste faire ceci comme ceci et nous commençons le débogage, cassons ici et puis lorsqu'il essaie d'accéder à cette clé d'âge qui n'existe pas, il nous dira le type d'erreur, une exception s'est produite, erreur de clé. D'accord. Donc, nous pouvons copier ceci, nous terminons le programme et puis je vais supprimer celui-ci et puis nous pouvons ajouter un nouveau bloc d'exception ici. N'importe où. Euh, nous pouvons dire, sauf erreur de clé comme E, puis nous pouvons imprimer, il n'y a pas de clé, je pense que ceci, je pense que ceci stocke l'âge, je pense, mais je vais juste dire, vous avez essayé d'accéder à la valeur d'une clé qui n'existe pas, et puis je vais imprimer E. Imprimer E. Donc, donc si nous essayons de l'exécuter à nouveau, aller à exécuter, puis il va essayer de faire, euh, certaines de ces actions. La plupart d'entre elles sont légales. Oh, d'accord. Donc, il va imprimer mon dictionnaire, nom, et il imprime Josh. Il va imprimer âge. Il échoue. Il va vérifier, avons-nous une exception qui gérera spécifiquement cela ? Et nous le faisons car c'était une erreur de clé. Et puis nous pouvons imprimer à l'utilisateur, vous avez essayé d'accéder à la valeur d'une clé qui n'existe pas. Et puis il montre le nom de la clé, essentiellement. Donc, j'espère que cela a du sens. Euh, vous n'avez pas à, pour être honnête avec vous, je ne mémorise pas cette syntaxe car elle est un peu différente pour chaque langage de programmation et j'ai dû, euh, rechercher ceci ou demander à chat GPD avant de faire cette leçon car je ne me souviens pas, c'est légèrement différent à chaque fois. Euh, donc sachez dans votre tête, [renifle] qu'il est possible qu'une erreur se produise dans votre code Python et qu'il soit possible de gérer gracieusement l'erreur et de permettre au programme de se terminer sans planter, si cela a du sens. Donc, je vais juste dire, vous savez, imprimer fin ici, n'est-ce pas ? Et puis si nous exécutons juste ceci, cela s'exécutera jusqu'au bout. Cela nous fait savoir qu'il y a une erreur, mais le programme, le programme est toujours terminé, n'est-ce pas ? Il est toujours terminé. Donc, cela vous donne juste une chance de, euh, gérer les choses sans terminer brusquement le programme et des choses comme ça, ou cela vous donnera une chance de demander à plusieurs reprises à l'utilisateur une entrée avec cette boucle infinie jusqu'à ce qu'il obtienne quelque chose qu'il puisse utiliser. Donc, oui, c'est la gestion des erreurs en Python. Bien sûr, il y a un peu plus de choses que vous pouvez faire avec cela, euh, comme finally, imprimer par exemple. Ceci imprime toujours. Euh, je vais juste l'exécuter sans débogage. Juste un FYI, je crois. Oui, vous avez essayé d'accéder à une chose qui n'existe pas, qui est ici. Et puis ce bloc finally, cette chose imprime toujours. Ceci fait partie du bloc try accept. Euh, mais oui, c'est le bloc try except, la gestion des erreurs en Python. Euh, j'espère que cela a suffisamment de sens. Si ce n'est pas le cas ou si vous avez des questions, euh, bien sûr, vous savez, utilisez chat GPT, mais vous pouvez toujours utiliser une communauté et me taguer là-bas et nous vous verrons dans la prochaine leçon. Bienvenue. Jusqu'à présent, nous avons couvert à peu près toutes les bases. Et puis à partir d'ici, nous allons commencer à construire des choses plus compliquées qui sont directement liées à l'agent de cybersécurité/analyste AAI que nous allons construire. Et pour suivre à partir de ce point, euh, vous aurez besoin de deux choses. Euh, la première chose est que vous aurez besoin d'un ouvert.

Clé API IA, qui est ceci ici. Ceci est utilisé pour communiquer avec le programme ChatGPT par programme avec Python. Nous avons besoin de cela car nous devons pouvoir communiquer avec des modèles comme à l'arrière-plan pour faire de la chasse aux menaces et autres. Et la deuxième chose dont vous avez besoin est l'accès au cyber-terrain. Et cela va sembler très commercial, mais tenez bon. J'expliquerai pourquoi c'est le cas. J'expliquerai ce qu'est le cyber-terrain et pourquoi vous avez besoin d'y accéder.

Fondamentalement, le cyber-terrain est un environnement de production évolutif en direct. Il y a des centaines de machines virtuelles d'utilisateurs et littéralement des dizaines de millions de journaux organiques car il est constamment attaqué par des acteurs malveillants aléatoires et des bots sur Internet. Sans oublier qu'il y a déjà un millier d'utilisateurs qui s'y entraînent, créent des ressources et font leur propre gestion des vulnérabilités et chasse aux menaces. Cela génère une tonne de journaux organiques et de données télémétriques que nous allons utiliser pour construire notre analyste IA de SOC. Et tous ces journaux sont stockés dans ce qu'on appelle un espace de travail d'analyse de journaux. Et nous allons interroger cet espace de travail en direct avec Python, puis utiliser ces journaux pour effectuer notre chasse aux menaces.

Ce cours a été conçu pour les personnes qui sont déjà sur le cyber-terrain. Je le publie juste au public. Vous pouvez donc le regarder et toujours suivre et en tirer quelque chose. Mais il est fortement recommandé de rejoindre le cyber-terrain car il y a beaucoup d'autres bonnes choses aussi. J'expliquerai ce que c'est juste pour que vous sachiez pour quoi vous payez si vous le rejoignez. Mais le cyber-terrain, c'est juste un environnement de production évolutif complet comme je l'ai dit, il a beaucoup de machines virtuelles. Il y a un SOC d'entreprise complet, une configuration d'opérations de sécurité. Pour notre SIEM, nous utilisons Microsoft Sentinel. Pour notre plateforme de gestion des vulnérabilités, nous utilisons Tenable, la version entièrement sous licence d'entreprise. Nous utilisons Defender pour Endpoint pour notre détection et réponse d'endpoints. Et il y a aussi des cours étape par étape, des cours vidéo qui montrent comment utiliser tous ces outils et effectuer diverses opérations de sécurité. Et nous avons des appels hebdomadaires en direct avec moi. Et il y a des opportunités de stage également pour quiconque le souhaite. Vous pouvez obtenir une expérience SOC vérifiable sur votre CV et nous la signerons lorsque l'entreprise nous contactera pour une référence pour vous. Et comme je l'ai dit, je pense que je l'ai déjà dit, il y a déjà mille membres. Il y a un maximum théorique d'environ 1 800 membres avant que je doive le faire évoluer à nouveau. Il y a donc encore de la place pour que les gens rejoignent. Mais j'imagine que lorsque je commencerai à publier beaucoup de contenu IA, il se remplira à nouveau et je devrai le faire évoluer. Et je suis presque certain qu'il n'y a rien de tel sur Internet actuellement car c'est un peu une responsabilité pour nous de le gérer et le prix est très bas pour ce qui est inclus. C'est juste parce que nous voulions que ce soit accessible mondialement. Mais oui, c'est ce qu'est le cyber-terrain. N'hésitez pas à poser des questions ci-dessous dans les commentaires et nous essaierons d'y répondre. Mais encore une fois, vous avez besoin d'une clé API d'OpenAI. Nous vous expliquerons comment faire. Et ensuite, vous devez rejoindre le cyber-terrain pour avoir accès à tous ces journaux organiques et au trafic d'attaques.

Donc, si vous êtes déjà sur le cyber-terrain et que vous n'avez pas encore suivi le cours sur les opérations de sécurité, je vous recommande vivement de le faire. Ce cours vous apprend comment effectuer des opérations de sécurité manuellement et comment interroger les journaux et utiliser KQL et toutes les choses que nous allons automatiser avec notre agent IA. Donc, oui, suivez absolument ce cours si vous ne l'avez pas encore fait et que vous êtes déjà sur le cyber-terrain. Et si vous ne l'êtes pas et que vous êtes sérieux pour suivre, allez-y et je mettrai un lien dans la description ou quelque part à l'écran. Vous pouvez y jeter un coup d'œil et rejoindre de cette façon. Et oui, c'est l'environnement pour lequel le cours a été conçu. Et nous vous verrons dans la prochaine leçon.

Bienvenue de retour. Dans cette vidéo, nous allons installer la bibliothèque OpenAI. C'est ainsi qu'elle s'appelle. Et je veux juste faire une démonstration de la façon de le faire et expliquer ce que sont les bibliothèques et pourquoi elles sont utiles.

Alors, d'abord, ouvrez VS Code, puis ouvrez le dossier de code sur votre bureau. Ce n'est pas grave s'il n'y a rien dedans ou d'autres choses. Ça n'a pas d'importance. Mais le mien est déjà ouvert, donc je vais le fermer et je vais faire un récapitulatif de ce à quoi cela ressemble. Nous pouvons simplement cliquer sur ces deux. Nous pouvons dire ouvrir le dossier ici ou nous pouvons aller dans fichier et ouvrir le dossier. Cela fait la même chose. Alors allez sur mon bureau ou sur le bureau ici, puis code, puis sélectionnez le dossier.

Et il y aura un lien en bas dans la description ou dans cette vidéo si vous regardez à l'intérieur de la communauté scolaire et ce lien ouvrira cette chose. C'est juste du code de base pour la prochaine leçon que nous allons faire. Alors copiez ce code ici, puis retournez à VS Code et nous créerons un nouveau fichier ici. Je l'ai appelé comment ? Main openai. Ça n'a pas d'importance comment vous l'appelez, mais je vais juste l'appeler main openai.py comme ceci. Et puis collez simplement le code ici comme ceci. Et si vous essayez de l'exécuter tel quel, bien sûr, beaucoup de choses l'empêcheront de fonctionner, mais essayez de l'exécuter et vous verrez probablement cette erreur comme module nommé open ai et cette chose sera soulignée et vous pourrez alors survoler votre souris dessus et dire comme une correction rapide. Ok, ce n'est pas ici. Ok.

Pour que cela fonctionne, nous devons installer la bibliothèque, la bibliothèque open ai. Et une bibliothèque, si vous vous souvenez des leçons précédentes, vous pouvez créer un module local, puis vous pouvez l'importer dans votre code d'une manière qui ressemble à ceci. Mais il existe de nombreuses bibliothèques qu'une grande entreprise a créées ou une organisation ou un autre groupe ou quelqu'un l'a créé et cela contient beaucoup de code qui vous facilite l'utilisation, mais vous devez d'abord le télécharger.

Pour ce faire, dans ce cas, nous pouvons utiliser ce qu'on appelle pip. J'oublie exactement ce que cela signifie, mais je pense que c'est comme un installateur python. Je ne me souviens pas, mais pour installer cette bibliothèque, nous pouvons simplement taper pip espace install espace, puis open ai comme ceci. Et cela ira et je peux vous pouvez annuler ceci si vous le souhaitez. Je vais juste le fermer. mais cela ira et installera la bibliothèque open ai sur votre machine, puis après cela, vous pourrez réellement utiliser ce code. Nous allons donc laisser cela se terminer et cette erreur devrait disparaître une fois que c'est fait. Donc, donc, et puis ce soulignement a disparu. Je vais fermer ce fichier et l'ouvrir à nouveau. L'un des Ok, il est devenu vert. Oui. Donc, cela devrait être bon maintenant. Et puis, lorsque vous êtes à ce stade, votre bibliothèque open ai est installée. Vous pouvez donc l'utiliser. Nous pouvons donc le jouer à nouveau. Et cela échouera de toute façon car nous n'avons pas la clé API ici. Mais au moins, au moins, il dit au moins, il ne se plaint pas que la bibliothèque manque comme la nouvelle la nouvelle erreur. Laissez-moi voir ce que cela dit. Clé API incorrecte fournie. Oui, bien sûr. Parce qu'il n'y a pas de clé API ici.

Donc, dans la prochaine vidéo, nous allons travailler pour comprendre comment créer un compte OpenAI, puis obtenir notre clé API, puis financer le compte, puis nous pourrons réellement commencer à faire des appels à l'API ChatGPT ou à l'API OpenAI, ce qui est assez excitant car une fois que vous pouvez utiliser des API, vous pouvez pratiquement faire toutes sortes de choses et cela ouvre vraiment le monde en termes de codage. Alors, oui, attendez-vous à cela et nous vous verrons dans la prochaine leçon. Et au fait, vous n'avez à installer cela qu'une seule fois. Il l'installe localement sur votre ordinateur, puis après l'avoir installé, vous pouvez simplement l'utiliser pour toujours jusqu'à ce que vous ayez à le mettre à jour. Mais oui, nous vous verrons dans la prochaine leçon.

Bienvenue de retour. Dans cette vidéo, nous allons configurer votre compte OpenAI, puis obtenir votre clé API, puis nous allons financer le compte car cela coûte de l'argent. nous utilisons essentiellement ChatGPT et c'est différent si vous avez un compte ChatGPT et que vous utilisez activement ChatGPT dans le navigateur Web, c'est différent de l'API, vous pouvez avoir ces deux choses mutuellement exclusives. Nous allons donc créer un compte OpenAI, puis obtenir notre clé API.

Ce code, je mettrai un lien dans la description. Que vous regardiez ceci dans l'école ou sur YouTube, il devrait y avoir un lien quelque part pour obtenir ce code, mais au pire, vous pouvez le taper. Ce n'est pas si grave, mais je mettrai un lien vers le code aussi. Mais en tout cas, allez sur Google et recherchez comme open a créer un compte API, quelque chose comme ça. Et puis il devrait y avoir comme une plateforme de connexion openai.com, quelque chose qui ressemble à ceci de toute façon. Et puis vous vous connecterez simplement comme vous le souhaitez avec votre Google ou une adresse e-mail ou quelque chose comme ça. Et puis à l'intérieur du code, j'ai mis quelques liens à l'intérieur. Ceci est comment créer votre clé API. Donc, vous pouvez faire un clic droit dessus ou comment vous faites cela sur Mac. Et puis vous pouvez créer une nouvelle clé secrète. Et puis vous n'avez pas à la nommer. Vous devrez peut-être sélectionner un projet si vous n'en avez pas déjà un. Mais cliquez simplement sur créer une clé et vous ne pourrez voir cette clé qu'une seule fois. Après avoir fermé cette fenêtre, elle disparaîtra et vous ne pourrez plus la voir. Je vais donc la copier. Dites fait. Retournez à mon code, puis collez-la ici dans la chaîne. Collez-la. Ok. Et puis enregistrez.

Intéressant. Quoi qu'il en soit, retournez ici et si vous perdez votre clé ou quelque chose comme ça, voyez comment vous ne pouvez plus voir la clé. Elle a juste disparu. Vous devez donc, je ne pense pas que vous puissiez la voir. Vous ne pouvez plus la voir. Vous devez donc la supprimer si vous oubliez ce qu'elle est et en créer une nouvelle, n'est-ce pas ? Et ceci est essentiellement un mot de passe. Vous voulez donc vraiment protéger cela. Après avoir publié cette vidéo, je vais supprimer cette clé, n'est-ce pas ? Parce que c'est la même chose que de donner aux gens l'accès à votre ChatGPT essentiellement.

Nous avons ceci et j'essaierai d'exécuter ce code. Il ne fonctionnera pas parce que je n'ai pas financé le compte. Donc, par exemple, je vais juste regarder ceci. Je vais donc le casser ici et je vais dire démarrer le débogueur Python. Je vais zoomer un peu. L'écran est un peu bruyant ou trop plein. Et puis vous pouvez lire l'erreur qui dit comme message vous avez dépassé votre quota actuel, veuillez vérifier votre plan et vos détails de facturation pour plus d'informations, bla bla bla trop de requêtes. Et cela vous donne beaucoup de liens et de choses. Cela signifie simplement que nous n'avons pas d'argent sur le compte. La clé API fonctionne comme vous pouvez le voir. Eh bien, cela a fonctionné assez pour pouvoir communiquer avec l'API d'OpenAI, mais nous avons besoin de plus d'argent.

Nous pouvons donc arrêter ce code, puis nous retournons ici. Et puis, vous pouvez simplement aller à la facturation ici. Ou je crois que vous pouvez cliquer dessus et cela ira directement à la facturation. Et puis vous pouvez ajouter des détails de paiement. Et puis vous pouvez ajouter votre numéro de carte et des choses ici. C'est sûr. C'est comme un produit SaaS, un produit cher. Je vais donc y aller et le faire et je serai de retour.

Oh, je suis de retour. Et sur l'écran suivant, il vous demande d'entrer votre montant. Il va donc essentiellement financer votre compte. Et vous pouvez lire tout cela. Voulez-vous configurer la recharge automatique ? Donc, si votre API, vous savez, si vous utilisez les 5 $, voulez-vous qu'il la rembourse ? Et puis il y a d'autres options en bas comme lorsque le solde de crédit descend en dessous de ce qui va se passer, ramener le solde à cela et vous pouvez faire toutes ces choses. Vous savez, faites ce que vous voulez. J'ai déjà trois comptes API, donc je n'ai pas besoin de faire tout cela. Je crée juste ceci pour cette vidéo. Je vais donc juste dire cinq dollars et ne pas le laisser rembourser, puis je confirmerai le paiement. Paiement réussi. Et maintenant, vous pouvez voir votre limite de crédit, vous avez cinq dollars d'utilisation de l'API. Vous pouvez donc utiliser l'API beaucoup jusqu'à ce que cela atteigne zéro. Cela peut aller jusqu'à quelques centimes négatifs, puis cela cessera de fonctionner à nouveau. Et vous pouvez aller à, je pense que vous pouvez aller à l'utilisation, puis vous pouvez voir combien vous utilisez et combien vous dépensez ou quoi que ce soit. Et puis vous pouvez regarder à l'intérieur des limites également. Il y a d'autres choses ici. Mais en tout cas, vous pouvez regarder tout cela, mais maintenant l'API, cela devrait fonctionner. Et j'expliquerai tout cela dans la prochaine vidéo. Nous allons approfondir cela et faire beaucoup avec cela. Et je l'expliquerai, mais essentiellement, cela envoie juste une invite à ChatGPT et cela imprime la réponse. Donc, vous pouvez laisser cette invite ici si vous le souhaitez. Je vais effacer, vous pouvez effacer votre console en tapant clear, puis c'est littéralement juste utiliser ChatGPT et vous pouvez si vous voulez faire une invite différente. Mais je vais juste exécuter cela sans débogage pour l'instant juste pour l'observer fonctionner et nous verrons ce qu'il trouve. Donnez-moi une recette de gâteau très courte. Et nous utilisons le modèle GPD5, qui est littéralement sorti hier, je pense. Et voici ce qu'il a trouvé. Vous pouvez le lire. La belle chose à propos des LLM et de l'IA, et le vôtre sera très certainement différent. Et si vous exécutez ceci à nouveau, il sera très certainement différent car la façon dont il est actuellement configuré, il ne se souvient pas des choses précédentes dont nous avons parlé. Chaque fois que nous exécutons ce programme, il envoie une nouvelle conversation. C'est comme une conversation toute nouvelle. Et voyez, il a trouvé quelque chose de différent cette fois. Et cette fois, et en fait, il nous a donné des instructions sur la façon de le cuire et tout ça. Mais si vous êtes capable d'obtenir une réponse comme celle-ci, cela signifie que votre système est configuré. Votre compte est financé et votre API et tout fonctionne.

Alors, je vais juste vérifier l'utilisation pour voir si quelque chose a changé. Oh, c'est déjà fait. Un total de 34 tokens que nous avons déjà utilisés. Et nous parlerons des tokens et de tout cela éventuellement. Mais je ne pense pas pouvoir encore voir le solde. Cela n'a probablement même pas coûté un centime pour être honnête. Oui, il reste 5 $. Il n'a peut-être pas encore été mis à jour, mais en tout cas, si vous arrivez à ce point où vous pouvez obtenir les recettes de gâteau ou quoi que ce soit que vous mettez dans cette invite, nous sommes prêts. Et si cela ne fonctionne pas, allez sur le forum où vous regardez ceci, probablement dans le cyber-terrain, si vous faites cela, puis publiez dans la communauté et taguez-moi. Quelqu'un vous aidera probablement avant que je ne le fasse. Mais nous voulons nous assurer que cela fonctionne avant de passer à la suite. Mais oui, nous vous verrons dans la prochaine leçon.

Bienvenue de retour. Dans cette vidéo, nous allons utiliser un peu ChatGPT avec Python. Je veux juste vous donner une idée de quelques choses différentes. Nous allons utiliser le même fichier que dans la dernière vidéo. Nous pouvons donc simplement le télécharger à nouveau ou vous assurer que vous l'avez ouvert, puis vous assurer que vous avez votre clé API et tout le reste. Et puis assurez-vous que votre compte est financé. Et si vous oubliez où obtenir la clé API, elle est ici. Et puis pour la facturation, pour vous assurer que votre compte est financé, allez simplement sur ce lien, puis facturation. Et assurez-vous qu'il y a une sorte d'argent ici, au moins un peu, n'est-ce pas ? Cool.

Et puis, je vais régler le modèle sur GPT4. Si vous avez utilisé ChatGPT sur le Web, vous saurez que avant de pouvoir régler la version du modèle ici, comme si vous voulez utiliser quatre ou une autre version ou quelque chose comme ça, mais si vous utilisez l'API comme ceci, vous devez le faire ici. Donc, par exemple, je vais juste vous montrer quelque chose. Si vous allez ici et tapez des guillemets doubles ou tapez une citation, cela vous montrera tous les modèles disponibles entre guillemets pour que vous puissiez les utiliser. GPT4 est assez rapide. Je vais donc juste l'utiliser car il est suffisant pour nos besoins.

Alors, assurez-vous simplement que cela fonctionne. Nous allons donc l'enregistrer et nous allons simplement mettre une invite différente si vous le souhaitez. Quel est le meilleur pays, répondez en cinq mots ou moins ? Vous savez, juste pour vous assurer que cela fonctionne. Je vais donc juste exécuter cela sans débogage. Voyons ce qui sort, puis j'expliquerai tout. C'est subjectif et basé sur les préférences personnelles. Très réponse GPT. Ok.

Alors, je vais juste expliquer ces choses ligne par ligne, puis nous allons juste, je vais expliquer les choses, puis nous allons réorganiser cela d'une manière plus optimale en fonction de ce que nous avons appris dans les leçons précédentes juste pour solidifier ces concepts dans votre tête. Alors, je vais casser ceci, puis je vais commencer à déboguer. Et au fait, vous pouvez toujours coller du code dans ChatGPT et demander ce qu'il fait, le ChatGPT Web réel. Il a tendance à être assez utile, mais c'est juste le module pour OpenAI, ChatGPT. Il y a beaucoup de code là-dedans que je ne sais pas ce qu'il fait, mais c'est de la magie pour moi pour être honnête, mais cela nous permet d'interagir avec l'API OpenAI et d'utiliser ChatGPT avec Python.

Et cette ligne de code, vous pouvez simplement penser à cela comme un objet spécial ou oui, pensez-y comme un objet spécial qui prend votre clé API, alias votre mot de passe, puis la chose qu'il renvoie est juste pour moi dans ma tête, cette chose est juste une variable spéciale qui nous permet d'interagir avec ChatGPT. C'est beaucoup plus que cela. Mais pour être honnête avec vous et être transparent, je ne suis pas super intelligent et je suis en fait, cela contient quoi que ce soit. Mais pour moi, c'est juste une variable magique qui nous permet d'interagir avec ChatGPT ci-dessous, comme vous pouvez le voir.

Alors, si nous passons par ceci, et si nous déboguons, si vous cliquez dessus, vous pouvez réellement voir ce qu'il y a à l'intérieur de cette variable spéciale. Ce client OpenAI est ici. Et vous pouvez voir que c'est juste un tas de choses. Et vous savez, je ne sais pas ce que fait la plupart de ces choses techniques, mais je sais ce que fait certaines d'entre elles, mais pour nos besoins, nous n'avons pas besoin de le faire pour l'instant. C'est juste une variable qui nous permet d'interagir avec GPT.

Et puis ceci, bien sûr, c'est juste une chaîne de caractères comme vous l'avez appris dans la leçon précédente, juste des guillemets avec des caractères arbitraires dedans. Elle est assignée à cette variable. Nous avons juste appelé cette variable prompt. Nous aurions pu appeler cette variable girafe ou zèbre ou quoi que ce soit. Alors, nous allons passer par là. Il est logique de ne pas passer par là, mais nous allons continuer le code. Il est logique de l'appeler prompt parce que c'est ce que c'est, n'est-ce pas ? Cool.

Et puis cette chose, vous remarquerez un seul signe égal ici, comme si tout cela est juste une fonction spéciale qui pose une question à ChatGPT, puis elle nous renverra la réponse qui sera stockée dans cette variable. Tout cela est une fonction. Elle prend, elle prend plus de deux arguments, mais actuellement nous lui passons deux arguments. L'un d'eux est juste une chaîne de caractères représentant le modèle, nous disons à GPT quel modèle nous voulons utiliser, puis le second est un tableau de messages. J'en parlerai plus tard. Mais c'est juste un tableau qui contient notre invite, ce que nous voulons demander à ChatGPT. Et si nous passons par ceci et que nous le dépassons, il renverra quelque chose.

Alors, nous avons cette réponse maintenant et cela contient notre réponse quelque part. Alors, si nous regardons dans les variables à gauche, c'est ce qui a été renvoyé par ChatGPT, l'API. Alors, si nous l'étendons, vous pouvez voir qu'il y a beaucoup de choses ici, comme le modèle qui a été utilisé. C'est probablement, je suppose, l'horodatage, une sorte de date, une sorte de temps qui indique qu'il est créé. Et il y a juste un tas de choses ici dont je ne sais pas ce que la plupart d'entre elles sont pour être honnête, mais je sais ce que certaines d'entre elles sont, mais nous pouvons regarder dans les choix par exemple, puis c'est ce que cette chose est, réponse choix est une liste. Donc, choix, c'est dans une, c'est une liste avec zéro ou plutôt un seul objet dedans. Et puis à l'intérieur de cet unique objet, il y a quelque chose appelé messages comme ceci, ou plutôt message, et il y a quelque chose appelé message. Désolé, il y a quelque chose appelé message qui est ici, puis content qui est ici. Et c'est notre réponse réelle que ChatGPT nous a donnée, la subjectivité aux préférences personnelles des individus. Nous ne l'avons même pas encore vu imprimé à l'écran. Cette fois, il est toujours là.

Alors, si nous passons par ceci, il va l'imprimer. Donc, essentiellement, cette ligne ici a pris la chose à l'intérieur de la réponse, qui est ici dans les choix, dans le premier élément de cette liste. Donc, choix, le premier élément de la liste, puis à l'intérieur du message, à l'intérieur du message, il y a content, content, et il a pris cette chaîne et l'a assignée à cette variable, puis maintenant il va simplement imprimer cette variable. Alors, si nous passons, il l'imprime, puis le code se termine.

Alors, je veux juste expliquer quelques choses et réarranger un peu et rendre le programme un peu meilleur. Alors, par exemple, vous pourriez remarquer que, eh bien, je ne sais pas si vous l'avez remarqué ou non. C'est très difficile à remarquer, mais cette chose de messages, ces crochets à l'extérieur signifient qu'elle accepte une liste de choses, mais il n'y a qu'un seul élément dans la liste, un seul, c'est ce qu'on appelle un objet message, je suppose, pour ChatGPT, mais si vous regardez de près, vous remarquerez que c'est en fait un dictionnaire.

Alors, par exemple, je vais enlever ceci. Je vais le couper plutôt. Désolé. Je vais le couper. Et puis nous pouvons dire comme, je vais juste dire comme dictionnaire parce que c'est ce que c'est. Je vais juste appeler ceci une variable aléatoire appelée dictionnaire. Et puis nous pouvons faire quelque chose comme ceci. Et puis vous remarquerez que c'est en fait comme clé valeur clé valeur comme ceci. Alors, nous pouvons l'arranger d'une manière qui a peut-être plus de sens et qui est plus facile à comprendre comme ceci, juste pour que vous puissiez voir ce que c'est en fait. C'est comme clé valeur clé valeur dictionnaire. Et puis nous pourrions simplement prendre ceci, par exemple, et le passer ici comme ceci. Comme ceci. Et puis j'expliquerai le rôle utilisateur et le contenu de l'invite un peu plus tard. Mais au lieu de coder en dur l'invite comme ceci dans le code, nous pouvons utiliser input. Si vous vous souvenez des leçons précédentes, nous pouvons dire comme, je ne sais pas ce que ChatGPT demande normalement. Laissez-moi regarder. Oh, demandez n'importe quoi. Ok, juste assez. N'importe quoi. Et puis je vais dire une nouvelle ligne comme ceci. Et puis je vais juste exécuter ce code tel quel. Je vais juste l'exécuter une fois sans débogage juste pour qu'il s'exécute comme un programme normal. Et puis nous pouvons pratiquer son utilisation.

C'est donc littéralement juste ChatGPT. Nous l'utilisons juste en Python dans la ligne de commande. Alors, je bois quelque chose. Alors, quelles sont les macronutriments totaux ? Oops. Cela devrait être un mot. Quoi qu'il en soit. Pour un latte Starbucks grande. Oh, je vais mal l'épeler. C'est bon. Latte avec de la cannelle. Ne vous moquez pas de moi. Miel. Et un shot supplémentaire. Je l'ai eu à Shodome, Japon, si cela a de l'importance. Et il pleut dehors. Je vais dire pour le rendre intéressant, s'il vous plaît répondez. Non, je ne veux pas faire ça. C'est assez. Alors, je vais juste dire entrer comme ceci. Et puis le programme devrait juste s'exécuter et tout faire. Alors, nous verrons ce que ChatGPT trouve. Et il a répondu et il a été déversé à l'écran. Les informations nutritionnelles. Oh oui. Les informations nutritionnelles peuvent varier légèrement. Bla bla bla. Donc, il me dit les calories et toutes les choses. Le shot d'espresso supplémentaire. En tout cas, vous avez l'idée. Nous avons un ChatGPT fonctionnel et puis le programme se termine simplement.

Alors, nous pouvons, si vous voulez parler un peu de choses. Alors, laissez-moi annuler certaines de ces choses et les remettre comme elles étaient à l'origine. Cool. Donc, c'est plus ou moins notre code original. Alors, vous remarquerez cette chose de messages où il y a un rôle utilisateur, puis un contenu d'invite. Et ces crochets à la fin signifient qu'il essaie d'accepter une liste de messages, mais nous ne passons qu'un seul message ici. Donc, nous pouvons faire plus d'un message et il y a cette chose appelée rôle, et vous pouvez spécifier qu'il peut y en avoir plus que cela, mais vous pouvez spécifier soit utilisateur, soit système. Et si vous spécifiez un rôle système, cela donne à ChatGPT plus de contexte sur la façon dont vous voulez qu'il se comporte.

Alors, par exemple, je vais prendre ceci, puis peut-être, voyons, faisons mon propre objet JSON plein de, c'est une liste de dictionnaires si cela a du sens. Alors, tenez bon un instant. Alors, je vais dire comme, une invite complète, tout ce que j'ai dit n'a probablement pas eu de sens pour quiconque m'écoute, mais cela aura du sens, j'espère, après que vous ayez vu ce que je fais. Et au fait, j'ai appris tout cela juste en utilisant ChatGPT et Google, en demandant de plus en plus à ChatGPT, et il y a aussi de la documentation pour cela. Mais en tout cas, alors je vais juste l'appeler invite complète et je vais remplacer tout cela par cela. Alors, je vais créer une liste comme ceci. Et puis je vais ordonner, je vais formater ceci comme ceci pour que ce soit plus facile à lire. Et puis il y aura juste deux messages ici.

Alors, le premier message sera comme le message système. Alors, je vais couper ceci en fait et je vais juste le remplacer et séparer par une virgule, puis je vais le coller une fois de plus. Et puis en fait, je vais changer le premier en rôle système, puis le contenu. C'est là que vous dites à ChatGPT comment se comporter. Alors, par exemple, si vous avez déjà vu ces vidéos YouTube où c'est comme, c'était la meilleure invite pour ChatGPT pour apprendre les mathématiques. Prétendez que vous êtes comme un tuteur de mathématiques et tout ça, vous savez, cela lui donne du contexte sur ce que vous essayiez d'accomplir. Alors, c'est là que vous spécifiez comment vous voulez que ChatGPT se comporte. Vous créerez un message avec le rôle système, puis le contenu à l'intérieur pour le contenu, vous mettrez comment vous voulez qu'il se comporte. Alors, je vais dire comme, en termes de notre analyste IA de SOC, nous allons être comme, vous êtes un analyste IA de SOC, bla bla bla. Mais pour cela, je vais juste dire comme, répondez comme si vous étiez un scientifique de fusées de renommée mondiale. Et puis l'invite utilisateur sera juste ce que nous demandons, n'est-ce pas ? Cela sera mis ici. Et puis cette chose d'invite complète, c'est une liste. Alors, je vais juste passer ceci ici. Si cela a du sens. Cela pourrait être plus facile à lire. Comme ceci. C'est juste une autre façon d'organiser les choses pour les rendre potentiellement plus faciles à lire. Et j'essaie juste de vous montrer ce qui est possible. Ce n'est pas comme ça qu'il faut faire. J'essaie juste d'articuler que c'est une liste de dictionnaires qui sont en fait des messages pour GPT. Et l'un d'eux peut être un message système, comme pour la façon dont vous voulez que GPT se comporte. Et puis d'autres, comme votre invite réelle en tant qu'utilisateur. Cela donne juste au modèle le contexte sur la façon dont vous voulez qu'il réponde.

Alors, je vais juste casser ceci comme ceci. Je vais le casser ici et je vais commencer à déboguer. Et au fait, bien sûr, lorsque vous êtes bloqué, allez sur les forums, puis pour la catégorie, choisissez comme IA plus cybersécurité et posez toutes vos questions là-bas. Oh, en fait, je voulais obtenir notre propre entrée. Alors, je vais arrêter ceci. Je vais dire entrée, demandez n'importe quoi. Ok. Maintenant, je vais, maintenant je vais, oops. Maintenant, je vais déboguer ceci. Ok. Alors, je vais passer par ceci. Il dit demandez n'importe quoi ici. Je vais demander, s'il vous plaît, venez avec une recette similaire pour le Starbucks. Starbucks crème brûlée. Je ne sais pas comment épeler ceci. Brûlée. Je ne sais pas. Quoi qu'il en soit. Je veux dire crème brûlée. C'est embarrassant. Quoi qu'il en soit. Latte au Japon. Faites de votre mieux. Je m'en fiche. Alors, et puis maintenant notre invite a été stockée ici. Nous pouvons voir notre chaîne d'invite ici. Et ceci est notre invite complète. C'est une liste, mais c'est une liste de dictionnaires. Et ce sont des messages pour le modèle ChatGPT. Alors, si nous passons par ceci comme ceci. Maintenant, ici, nous voyons l'invite complète et nous voyons que c'est une liste et le premier élément est le message du rôle système, répondez comme si vous étiez un scientifique de fusées de premier plan, puis le second, c'est notre invite que nous venons de taper pour le Starbucks comme crème brûlée. Je l'ai mal épelé, mais quoi qu'il en soit. En tout cas, maintenant c'est la fonction où elle va réellement demander à ChatGPT notre question et elle fournira le contexte où nous voulions qu'elle réponde comme si c'était un scientifique de fusées de premier plan. Tout cela est à l'intérieur de cette chose d'invite complète. Et au fait, la façon dont ceci est organisé, c'est juste, cela peut être comme ceci. Dans les leçons précédentes, la fonction était organisée plus comme ceci. C'est en ligne comme ceci. Cela a tendance à être plus facile à lire s'il est séparé sur plusieurs lignes lorsqu'il commence à devenir trop long. Alors, je peux le faire comme ceci aussi où ceci est la création est une fonction. C'est le premier paramètre ou argument que nous passons. C'est le deuxième argument. Ceci est non négociable. C'est ce qu'il y a à l'intérieur de la fonction réelle. C'est la chose que nous lui donnons. Ceci est non négociable. Il doit dire messages. C'est la chose à l'intérieur de la fonction réelle que nous ne pouvons pas voir. Mais c'est la chose que nous lui passons. Alors, si nous passons par ceci, la chose. Ok. Juste ignorer ceci. C'est parce que j'ai changé les lignes un peu au milieu du débogage. C'est pourquoi. Ne vous inquiétez pas. Ok. Maintenant, GPT demande à GPT. Alors, nous verrons ce qu'il trouve. Je suis désolé. C'est hors de contrôle parce que j'ai bricolé les lignes. Et puis si nous terminons ceci, cela devrait l'imprimer à l'écran.

Alors, je lui ai demandé de répondre comme si c'était comme un scientifique de fusées de premier plan ou quoi que ce soit. Alors, il dit, en tant que scientifique de fusées, je dois admettre que la création de boissons n'est pas mon expertise habituelle. Bla bla bla. Et puis il donne les instructions. Je ne sais pas pourquoi les instructions, si c'est comme cela qu'un scientifique de fusées répondrait, mais il a reconnu que nous avions l'invite système pour répondre comme s'il était un scientifique de fusées. Utilisez une torche de cuisine, bla bla bla. Ok. Alors, peut-être que vous pouvez avoir une idée. Et il y a plus que vous pouvez faire avec ceci. Ceci est l'invite complète qui est envoyée à GPT. Et vous pouvez envoyer plus de deux messages à la fois. Alors, par exemple, si je copie ceci et que je le colle, puis que je vais juste inventer une autre invite. Je ne sais pas ce qui va se passer si je fais cela pour être honnête. Je vais juste ignorer tout cela, puis je vais envoyer une autre invite. Mon gâteau préféré est banane quelque chose. C'est absurde, n'est-ce pas ? Alors, je vais, il doit y avoir une virgule ici. Alors, encore une fois, c'est une liste. C'est une liste d'objets dictionnaire. Et ce sont les invites système donnant à GPT le contexte et ce sont les invites utilisateur, ce que nous disons à ChatGPT, notre question entre guillemets. Et je ne sais pas ce qui va se passer, vous savez, si je fais cela, mais nous pouvons essayer et voir.

Alors, je vais juste exécuter ceci, peut-être, laissez-moi faire ceci pour que nous puissions avoir une sorte de séparation. Alors, je vais juste exécuter ceci sans débogage. Il ne me posera aucune question car il va juste construire l'invite manuellement comme nous l'avons codée en dur. Il va demander à GTP. Il va extraire la réponse, puis il va l'imprimer. Alors, nous allons juste l'exécuter. Il dit en effet la vitesse moyenne du zèbre est d'environ 65 km/h. Ceci est naturellement développé dans la nature. Cependant, bien que ce soit un fait intéressant, en tant que scientifique de fusées, je me concentre davantage sur les vitesses de différentes magnitudes, en particulier pour atteindre la vitesse pour échapper au pôle gravitationnel de la Terre. Il semble ne pas avoir reconnu ce que j'ai dit à propos de la banane. Je pense que c'est peut-être parce qu'il utilise cela comme contexte peut-être et qu'il se concentre ensuite sur cela.

Alors, si nous voulons apprendre, je suppose, apprendre comment fonctionne GPT parce que je n'ai même pas encore une idée de ce que signifie passer plusieurs invites ici. Je pense que c'est la même chose que d'avoir une conversation avec GPT ici lorsque vous continuez à passer des conversations précédentes. Alors, je vais juste envoyer ceci à GPT par exemple. Je vais supprimer la clé API et puis je vais dire comme, laissez-moi supprimer ceci. Vous devriez prendre l'habitude de ne pas envoyer votre clé API à ChatGPT. Et je vais juste demander comme, Oops. Oh mon dieu. Je vais dire pourquoi l'API ChatGPT n'a-t-elle pas reconnu que j'aime les bananes, le gâteau à la banane. Nous verrons ce qu'il trouve. Il n'a pas reconnu que vous aimez la banane à cause du fonctionnement du tableau de messages de l'API et de la façon dont vous avez formulé votre dernière invite. C'est probablement pourquoi. Lorsque vous avez dit cela, vous ne lui donnez pas une conversation où le modèle est invité à répondre aux deux informations. Au lieu de cela, le message système définit le personnage, qui est ceci. Le dernier message, les zèbres sont rapides, est ce que le modèle traite principalement comme la question actuelle. La question précédente, mon gâteau préféré est la banane, est le contexte dans l'historique de la conversation. Mais comme vous n'avez rien demandé à ce sujet ni connecté au message du zèbre, le modèle n'a aucune raison de l'évoquer. Il se concentre sur le dernier tour, qui est ceci. C'est à peu près ce que je pensais.

Alors, essentiellement, c'est le personnage, comment il est censé agir. Ceci est le contexte de notre conversation précédente que nous avons eue entre guillemets. Et puis ceci est l'invite actuelle à laquelle GPT est censé répondre. Cela a du sens. Et nous pouvons lire plus de cela. L'API ne reconnaît pas automatiquement tous les faits antérieurs, sauf s'ils sont pertinents pour répondre à la question actuelle. Donc, il donne des exemples si nous voulons le forcer à le reconnaître. Alors, peut-être que je peux dire comme, peut-être que je peux dire les zèbres sont rapides. Attendez. Peut-être, je ne sais pas. Je ne sais pas si cela va importer, mais j'essaierai de dire, quel fruit pensez-vous qu'il est bon de leur donner ? Et puis peut-être que je peux l'appâter pour qu'il mentionne la banane. Je ne sais pas si cela va fonctionner, mais c'est une bonne expérience basée sur les connaissances que nous venons d'apprendre de GPT.

Alors, je vais juste essayer d'exécuter ceci que nous pourrions avoir sous la main. Oui. Alors, je vais juste essayer de l'exécuter et de voir ce qui se passe. Je vais juste l'exécuter sans débogage. J'apprends, j'ai littéralement appris quelque chose. J'ai supposé que c'était comme ça que ça marchait, mais je n'ai jamais pris la peine de vérifier. Alors, les zèbres étant des herbivores ont un régime à base d'herbes. Cependant, certains fruits pourraient être acceptables s'ils sont facilement disponibles. Il ne l'a pas, je n'ai pas pu l'appâter pour qu'il parle de la banane. Ce sont probablement deux choses dissemblables. Mais en tout cas, j'espère que cela a du sens. Et puis vous pouvez expérimenter un peu avec cela. Un bon projet serait de savoir comment, lorsque vous utilisez ChatGPT, vous pouvez continuer à parler avec lui. Et il gardera une trace de la conversation, je crois. Alors, une façon dont nous pourrions essayer de créer un programme qui se comporte réellement comme ChatGPT, qui continue d'ajouter les messages précédents à l'invite complète à chaque fois que vous appelez GPT, puis il aura du contexte pour eux. Ce serait un projet assez cool. Mais vous n'avez pas à le faire. C'est juste quelque chose qui m'est venu à l'esprit. Mais j'espère que cela a du sens. Si vous avez des questions à ce sujet, n'hésitez pas à utiliser ChatGPT pour demander, mais allez certainement sur les forums, posez des questions et tout le reste, et assurez-vous de comprendre à un niveau élevé ce qui se passe. Vous n'avez pas à mémoriser tout le code syntaxique pour cela et tout ça, mais reconnaissez simplement le fait que nous utilisons une bibliothèque OpenAI. Cela nous permet de parler avec ChatGPT. Ok, c'est une variable spéciale. Nous lui passons notre clé API, qui est notre mot de passe. Et puis si la clé API est correcte, nous pouvons utiliser une variable spéciale pour parler avec ChatGPT comme nous le faisons ici. Et puis pensez à chaque fois que vous communiquez avec ChatGPT, vous devez lui dire quel modèle vous voulez utiliser. Et puis sachez que vous pouvez changer le modèle comme ceci. Et aussi lorsque vous communiquez avec ChatGPT, il s'attendra à une liste ou à un tableau, mais une liste de messages et ils doivent être formatés comme ceci. Parce que si vous envoyez juste une invite comme si vous envoyez juste une chaîne de caractères plate comme ceci, ce sera comme si c'était mal formé.

Alors, je vais juste vous montrer à quoi cela ressemble maintenant. Il dit erreur, code d'erreur 400, tableau d'objets attendu mais une chaîne de caractères a été reçue à la place. Il s'attendait donc à un tableau d'objets comme ceci et il a reçu une chaîne de caractères à la place. Alors, je peux dire, oh un tableau d'objets, hein ? Alors, je vais juste vous donner un tableau vide plein d'objets vides comme ceci, puis nous verrons ce qu'il dit. Il devrait planter avec ceci aussi. Mais nous allons juste expérimenter, juste pour avoir une idée. C'est littéralement un tableau d'objets. Il est juste vide. Mais maintenant, il se plaint. Code d'erreur 400, paramètres requis manquants. Type de paramètre de requête invalide, messages zéro, rôle, code, paramètre requis manquant. Oh, donc il manque ce paramètre du paramètre de rôle. Alors, je me dis, oh, peut-être que je vais juste l'ajouter ici. Voici. Et puis avec une chaîne vide par exemple. Et je vais juste l'envoyer tel quel, c'est sûr. va avoir une autre erreur probablement. Mais voyons juste ce qui se passe. Il se plaint encore. Valeur invalide. Alors, c'est une valeur invalide. Je pense qu'il s'attend à avoir comme système, utilisateur ou quelque chose comme ça. Alors, par exemple, nous savons déjà comment résoudre cela car c'est comme ça qu'il faut faire. Mais vous pouvez toujours, je vous montre juste des choses aléatoires. Vous pouvez prendre ceci, puis aller à ChatGPT comme ceci. Si vous obtenez une erreur, alors vous pouvez revenir ici et vous pouvez prendre cette erreur. Il vaut mieux tout prendre, mais je pense qu'il va comprendre si j'en prends autant. Et je vais le copier. Oh mon dieu. J'espère que cela a été copié. J'ai l'impression que non. Oh, ça l'a été. Ok. Et puis je vais juste l'envoyer à GPT. Il va probablement être capable de le comprendre. Ok. Alors, ce sont les champs apparemment que GPT est, bienvenue pour y aller. Alors, soit système, utilisateur, assistant, fonction, outil, développeur. Je ne sais pas. Je sais ce que fait l'outil, mais je ne sais pas ce que font ces autres choses. Alors, peut-être que je peux passer assistant, je suppose. Comme ceci. Mais il va se plaindre maintenant qu'il n'y a pas de contenu ou pas d'invite, je suppose. Alors, si nous exécutons ceci, oui, encore une valeur invalide pour le contenu, une chaîne attendue a été nulle. Il ne l'a pas fait en fait, il n'y a pas de contenu de toute façon. C'est parce qu'il manque ceci.

Alors, essentiellement, le point que j'essaie de faire, c'est que ChatGPT, lorsque vous lui envoyez quelque chose, il s'attend à une liste et il s'attend à un certain dictionnaire avec certaines clés et valeurs dedans. Il doit juste les avoir pour fonctionner correctement. Alors, je suppose qu'apparemment assistant est un rôle valide et puis nous devons juste, c'est comme le contenu est

Notre invite actuelle, nous la lui posons. Donc, euh, la meilleure réponse est le meilleur gâteau. Je ne sais pas si c'est correct, mais nous allons exécuter cela. Je vais juste exécuter cela et ensuite nous terminerons la leçon. Ceci n'est pas utilisé, soit dit en passant, du tout. Et puis il a répondu correctement. La réponse à cette question dépend largement des préférences personnelles, bla bla bla bla. Donc, je vais juste supprimer tout cela et je vais l'exécuter une dernière fois. Nous allons en faire une de plus puisque nous sommes allés jusqu'au bout. Donc, je vais passer l'invite complète ici à nouveau, qui est ceci. Et nous allons juste parcourir le code une fois de plus. Euh, je vais faire quelque chose de réel. Réponse. Réponds comme si tu étais une fille travaillant dans la rue de Kabuki et qui est douée pour faire des gâteaux, et ensuite nous allons juste adopter un rôle d'utilisateur normal et ensuite le contenu. C'est notre invite que nous allons réellement poser à Chad DBT. Donc, je dirai, euh, quel est le meilleur gâteau à Tokyo ? Non, je dirai le meilleur sushi. D'accord, je vais juste. Et cette fois, je vais le déboguer juste pour que nous puissions avoir une dernière impression finale. Donc, notre client est créé, notre clé API et ensuite je vais vous montrer, en fait non, je vais vous montrer encore une chose après cela. Notre invite est en cours de construction et ensuite nous voyons notre invite ici, construite, système ro, c'est le contexte de la manière dont nous voulons nous comporter, c'est notre invite et ensuite nous allons demander à GPT avec le modèle GPT4 et notre invite complète ici, et ensuite nous obtiendrons la réponse. Et puis elle a répondu en anglais parfait. Bien que je passe la majeure partie de mon temps à cuisiner et à perfectionner des gâteaux, j'ai une affection pour les sushis à mon avis. Sukiyabashi Jiro. Oh oui, c'est vraiment même moi je sais ce que c'est. C'est vraiment cher. Euh, cependant, en tant qu'artiste pâtissier, mon expertise réside davantage dans les pâtisseries. Voulez-vous des suggestions sur où trouver les meilleurs gâteaux ? C'est tellement drôle. Euh, oui, c'est vraiment intéressant. Et d'ailleurs, c'est la dernière chose que je voulais vous montrer. C'est notre clé API, n'est-ce pas ? N'est-ce pas. Comme notre mot de passe. Et si je change une chose ici, comme au lieu de ce trois, peut-être que je mets un deux et que j'exécute cela. Je vais juste l'exécuter sans débogage. Sans aucun doute. Cet objet va être invalide et il va planter parce que la clé API est incorrecte. Et il dit le message d'erreur, clé API incorrecte fournie. Vous pouvez trouver votre clé API ici. Et puis vous, vous savez, vous devez en générer une nouvelle, euh, si vous ne vous souvenez pas de votre autre. Mais, euh, je l'ai juste rétablie. Et oui, c'est comme, euh, j'ai oublié comment s'appelait cette leçon, mais juste interagir avec et utiliser chat chat GPT. J'espère que vous avez une bonne idée, comme une meilleure idée de la façon dont chat GPT fonctionne et juste, je ne sais pas, une meilleure intuition. Mais oui, faites-moi savoir sur les forums si vous avez des questions et nous nous verrons dans la prochaine vidéo. Bienvenue de retour. Euh, dans cette vidéo, nous allons parler de, euh, forcer, euh, chat GPT à sortir en format JSON. Donc, ce que je veux dire par là, c'est par exemple, euh, c'est l'anglais. Décrivez un chat principal succinctement et il sort juste cette phrase normale en anglais avec, comme, les propriétés du chat et, comme, son apparence et ensuite si je dis de le décrire en JSON, il sortira quelque chose qui ressemble à ceci. C'est comme des données structurées qui sont facilement analysables par un ordinateur. C'est comme, c'est la différence. Et si nous allons, comme, à l'API par exemple, euh, il y a en quelque sorte deux façons de le faire. Euh, je vais supprimer cela pour l'instant. Comme cette ligne, ce type d'objet JSON ainsi que, comme, cette virgule. Je vais juste le couper, comme, contrôle X. Et ensuite je dirai, comme, par exemple, décrivez une ananas succinctement, euh, en JSON. Comme, je lui dirai de le faire en JSON au lieu de, vous savez, je vais juste, je vais juste le mettre dans l'invite, n'est-ce pas ? C'est une façon de faire. Donc, si j'exécute cela et ensuite je vais juste, euh, je vais juste exécuter sans débogage. Laissez-le juste s'exécuter. Et ensuite vous remarquerez qu'il le décrit effectivement en JSON, mais vous verrez qu'il met ceci, comme, ceci est techniquement une chaîne de caractères devant et une chaîne de caractères derrière. Ceci est comme, ceci est du markdown. Et ce, comme, tick tick tick JSON puis tick tick tick. C'est ce qui rend, comme, ce carré gris comme ceci. C'est pour ça que c'est comme ça. Donc, par exemple, si je, si je copie ceci par exemple et ensuite j'ouvre notepad et que je le colle. Je le colle. Vous verrez qu'il, voici la réponse en JSON et il, il met des chaînes de caractères et, comme, tout ce truc devant et derrière. Et ceci, ceci est le JSON parfait à l'intérieur, mais il a effectivement mis un tas de choses avant, ce qui n'est pas du JSON. Et si nous essayons de, cela aura du sens plus tard, mais si j'essaie de charger directement ceci dans un objet JSON, euh, cela fera planter l'interpréteur, cela fera planter le programme. Donc, afin d'éviter cela, comme, d'éviter strictement qu'il fasse cela, comme, mettre ces ticks devant ou tout autre type de, comme, texte précédent, nous pouvons ajouter cette chose. Je vais, comme, annuler ceci. Nous pouvons ajouter cette chose en retour, cette virgule, et ensuite nous pouvons passer ce type de format de réponse, objet JSON, comme ceci. Et cela, comme, cela le forcera à être en JSON, comme, JSON parfait à chaque fois. Donc, je dirai, "Décrivez une ananas en Je vais juste dire, d'accord, je vais vous montrer quelque chose. Je vais juste dire, décrivez une ananas sans rien dire sur le JSON, et nous exécuterons ceci. Je veux juste habituer les gens à voir, comme, des erreurs et à les lire et à les gérer. Donc, en gros, une erreur s'est produite, n'est-ce pas ? Vous pourriez voir l'erreur ici en haut ou vous pourriez la voir ici en bas. Donc, par exemple, laissez-moi voir. Laissez-moi exécuter ceci une fois de plus. Je vais exécuter ceci, comme, sans débogage. Je pense que si j'exécute sans débogage, cela s'affichera en bas. C'est plus facile à copier. Oui. Donc, il y a une erreur et il a essentiellement dit, euh, erreur 400, erreur. Les messages doivent contenir le mot JSON sous une forme quelconque pour utiliser le type de format de réponse, objet JSON. Donc, en gros, ce que cela dit, c'est que si nous utilisons ceci, nous devons dire le mot JSON dans notre invite quelque part. Nous devons soit juste dire JSON, soit juste lui dire de, comme, sortir en format JSON, quelque chose comme ceci. Donc, par exemple, si encore une fois je veux juste rappeler aux gens, vous pouvez copier des choses comme ceci et ensuite vous pouvez juste aller sur chat GPT et ensuite juste le coller sans aucun contexte et il vous dira généralement, comme, il vous dira généralement ce que vous avez à faire. Assurez-vous que votre demande inclut JSON dans le message. Donc, en gros, tout cela signifie encore une fois, décrivez l'ananas, euh, s'il vous plaît, sortez-le en format JSON, comme ceci. Et ensuite, si nous exécutons ceci, je vais juste exécuter sans débogage. Et ensuite vous pouvez voir ce, comme, format JSON parfait qui a été, euh, sorti, comme ceci. Objet parfait. Il n'y a rien avant, rien après. C'est juste un bel, euh, bel objet représentant un ananas. Mais il y a toujours un problème avec ceci. Par exemple, vous voyez que c'est un objet JSON et vous vous souvenez de la leçon, comme, nous devrions pouvoir faire, comme, quelque chose comme je vais, comme, faire de ceci un commentaire. Donc, nous devrions pouvoir faire quelque chose comme ceci, euh, réponse nom et cela devrait imprimer ananas, vous savez, cela devrait parce que c'est un objet JSON. C'est juste un grand dictionnaire, comme, clé valeur, clé valeur, et si nous, si nous faisons ceci, cela devrait pouvoir extraire la valeur et cela devrait juste imprimer ananas, n'est-ce pas ? Donc, nous allons exécuter ceci, euh, je vais exécuter et déboguer ceci une fois de plus. Comme ceci. Et ensuite, si nous passons par-dessus ceci, nous allons obtenir notre réponse. Donc, ceci, ceci est en fait intéressant. C'est un autre point que je voulais, comme, vous montrer. Vous voyez que le, le JSON non seulement ce n'est pas un véritable, bien, d'accord, il n'y a pas de nom ici, premièrement, c'est comme le premier problème, euh, ce qui est quelque chose que je voulais aborder ensuite car avant le, le précédent, euh, le précédent objet qui a été retourné par GPT, le premier élément ou la première, comme, propriété était nom, nom scientifique, catégorie, mais maintenant nous avons fruit, nom scientifique et ensuite je ne sais pas ce qu'il y a après, je ne peux pas le voir, apparence, il n'y a pas de catégorie et il n'y a rien qui s'appelle nom, premièrement. C'est comme le premier problème. Euh, donc cela va certainement planter de toute façon. Ça plante. Donc, le premier problème que nous devons résoudre est que si nous disons juste quelque chose comme ceci à GPT, comme, décrivez un ananas, sortez-le en format JSON, il va inventer son propre schéma, plutôt, il va inventer la façon dont il va inventer la structure des données. Comme, la première fois qu'il a décidé de cette structure, comme, il aura la propriété nom, nom scientifique, catégorie, et ensuite la deuxième fois que nous l'avons exécuté, il avait, comme, une catégorie fruit, nom scientifique. Il n'avait pas de nom et la structure est comme, un peu partout. Donc, nous pouvons en fait, comme, lui dire le format dans lequel nous voulons, comme, sortir, euh, que nous voulons. Nous pouvons lui dire, désolé, nous pouvons lui dire le format dans lequel nous voulons qu'il réponde. Donc, nous pouvons soit juste, comme, inventer quelque chose, comme, si nous savons, comme, comment nous voulons l'utiliser. Donc, nous pouvons dire, comme, euh, s'il vous plaît, sortez en format JSON et nous pouvons dire quelque chose comme ceci. Nous pouvons juste, comme, inventer notre propre objet JSON, comme ceci, nous pouvons dire, comme, nom et, vous savez, chaîne de caractères, catégorie, chaîne de caractères, euh, nous pouvons dire peut-être couleurs parce qu'il y a peut-être plusieurs couleurs et nous pouvons dire, comme, tableau, tableau et liste, c'est essentiellement la même chose à toutes fins utiles pour ce que nous faisons parce que peut-être que le, peut-être que l'ananas vient en plus d'une couleur, peut-être qu'il y a, comme, un rouge, comme, je ne sais pas, et ensuite nous pouvons dire, comme, euh, lieux, comme, où, où il pousse, n'est-ce pas, et ceci, ce sera une chaîne de caractères, donc avec ceci, nous pouvons, nous pouvons, comme, formater, nous pouvons forcer GPT à, comme, utiliser ce schéma à chaque fois, donc nous savons, euh, le format dans lequel il sera lorsqu'il sortira, n'est-ce pas ? Sinon, nous devons, comme, deviner et ce n'est pas très utile s'il retourne, comme, un format différent à chaque fois, n'est-ce pas ? Nous ne pouvons pas, c'est difficile à utiliser. Donc, si nous faisons ceci, nous pouvons forcer GPT à, comme, le sortir dans ce format. Et cela n'a pas à être comme ceci. Cela n'a pas à être exactement comme ceci. Nous pouvons le dire de, comme, plusieurs façons différentes. Et GPT est assez intelligent. Nous pouvons juste dire, comme, s'il vous plaît, sortez-le en format JSON. Incluez uniquement les champs nom, catégorie, couleurs et emplacement. Et il sera assez intelligent pour, comme, comprendre quoi faire, ce que je vais vous montrer dans une seconde. Donc, par exemple, nous allons juste, comme, exécuter ceci. Je vais exécuter ceci sans débogage. Euh, je vais juste observer la sortie. Et au lieu de ce long Oh, qu'est-il arrivé à ceci ? Oh, d'accord. Oh, laissez-moi, laissez-moi, laissez-moi corriger ceci. Désolé. D'accord, je vais exécuter sans débogage. Je veux juste l'imprimer à l'écran. Et vous pouvez voir qu'il a imprimé, euh, nom ananas catégorie fruit couleurs jaune vert marron emplacement régions tropicales. Juste assez, n'est-ce pas ? Donc, nous pouvons aussi le faire différemment. Nous pouvons dire, comme, euh, s'il vous plaît, incluez uniquement ces champs, ces propriétés. Je ne recommande pas de faire cette façon, soit dit en passant, euh, nom, attendez, catégorie, couleurs, emplacement. Je recommande de faire l'objet JSON réel, euh, parce que je ne, je ne veux pas qu'il choisisse, comme, aléatoirement, comme, des tableaux pour certaines choses. C'est juste mieux de, comme, faire l'objet entier vous-même pour qu'il sache. Mais vous pouvez le faire de toute façon. Je vais juste l'exécuter et juste, nous pouvons observer la différence s'il y en a. Vous pouvez voir nom ananas catégorie fruit couleurs jaune vert marron jaune marron vert juste assez emplacement régions tropicales. C'est assez, c'était presque la même chose. C'est presque exactement la même chose et ça a bien fonctionné. Mais quand même, je recommande juste, euh, d'utiliser, comme, un proper, comme, format comme ceci. Donc, il n'y a pas d'erreur. Et vous pouvez toujours, comme, aller sur chat GPT par exemple. Je peux dire, comme, décrivez-moi un ou je ne sais pas, désolé, donnez-moi un schéma en format JSON qui décrit un ananas. J'ai mis des fautes de frappe ici, mais c'est bon. Et il devrait, il fera quelque chose comme ceci. C'est peut-être trop long. S'il vous plaît, rendez cela beaucoup, beaucoup plus court juste pour nos intentions. Oh, ceci, ceci est suffisant. Euh, schéma uniquement, s'il vous plaît. Comme ceci. Donc, ceci est, ceci est un, ceci est un schéma pour décrire un ananas. Donc, si nous copions ceci par exemple et ensuite allons à GPT, nous pouvons juste, comme, utiliser cette chose que GPT nous a donnée si vous voulez, ou vous pouvez faire la vôtre juste si c'est gênant de faire le schéma vous-même. Cela ressemble un peu à mon schéma, mais, euh, GPT le comprendra de toute façon. Donc, si nous, je vais en fait le déboguer cette fois. Et ceci est vraiment long. Donc, je vais le réduire et je vais déboguer ceci. Et rappelez-vous, essayez juste de comprendre, comme, ce qui se passe et utilisez GPT et utilisez le forum. Euh, vous n'avez pas à faire quoi que ce soit de trop fou. Juste, comme, juste soyez comme, d'accord, oui, ça a du sens. Ce niveau est, comme, suffisant. Donc, il a répondu. Nous pouvons voir que nous allons extraire la réponse et nous pouvons la voir. Nous allons l'imprimer et ensuite ceci, ceci est le schéma que nous lui avons donné. Euh, exactement. Ce devrait être de toute façon. Comparons-le pour être sûr. Oui. Donc, le type est un objet et ensuite ce sont toutes les propriétés qu'il devrait avoir. Donc, il devrait avoir nom, nom scientifique, couleur, goût, nutrition. Nom, nom scientifique, couleur, goût, nutrition. Et ensuite nutrition est un objet en soi et cela a calories, vitamine C, fibres, calories, vitamine C, fibres. Et c'est, c'est bien et cela sera probablement, euh, parfait, euh, à chaque fois. Euh, ce format sera parfait à chaque fois que nous le ferons. Donc, donc nous pouvons faire ceci. Et ensuite nous voyons que, ensuite nous allons essayer de, par exemple, nous allons essayer d'imprimer ananas parce que rappelez-vous, c'est juste un grand dictionnaire. C'est une clé. C'est une valeur. C'est une clé. C'est une valeur. Clé valeur, etc. Donc, pour accéder à ananas, nous dirions juste, comme, vous savez, cette chose s'appelle réponse. Et ensuite nous faisons quelque chose. Ce n'est pas ce que j'ai fait. Vous ferez comme ceci, comme ceci. Et en théorie, cela devrait, cela devrait prendre le nom d'ici. Et ensuite cela devrait imprimer ananas, comme ceci. Et ensuite la même chose avec cette réponse. Et cela devrait imprimer, peu importe ce qu'est ananas, peu importe le nom scientifique. Donc, nous prenons ceci, mettons-le ici, comme ceci. Donc, je vais interrompre ici et je vais redémarrer le programme. Le schéma devrait toujours être intact. Comme, il devrait retourner le même format de, comme, ananas, comme, le même format JSON à chaque fois. Donc, regardez et il semble l'avoir, il semble l'avoir fait parce que nous avons nom ananas nom scientifique an ana ananas peu importe. Donc, techniquement, cela devrait imprimer et vous remarquez qu'il plante et c'est parce que, comme, la chose qui est retournée par chat gpt est en fait, c'est en fait pas un dictionnaire, ce n'est pas un objet du tout, c'est juste une longue chaîne de caractères, ça ressemble juste à du JSON, mais en fait, c'est juste une longue chaîne de caractères. Et si vous vous souvenez, une chaîne de caractères est juste comme, n'importe quoi. C'est comme n'importe quel caractère entouré de guillemets. C'est juste que la chaîne de caractères qui a été retournée par chat dbt, elle est au format JSON. Elle ressemble à du JSON. Donc, nous pouvons en fait utiliser ceci et nous pouvons le corriger, euh, avec le module ou la bibliothèque JSON. Je pense que c'est le terme correct pour module. Donc, en gros, le module JSON, euh, nous permet de prendre une chaîne de caractères et si elle est correctement formatée, nous pouvons la transformer en un objet dictionnaire ou, comme, un objet JSON approprié. Donc, pour ce faire, nous allons aller en haut et ensuite nous allons importer JSON. Oh mon dieu, je suis dans une VM et c'est vraiment, la souris est vraiment foutue si vous vous demandez pourquoi je continue à faire des erreurs. Donc, nous dirons importer JSON, comme ceci. Comme ceci. Donc, nous pouvons utiliser ceci, euh, c'est notre réponse. Donc, nous pouvons dire, euh, je vais juste le nommer, comme, réponse, vous savez, dictionnaire et ensuite pour charger cette chaîne de caractères dans un objet JSON, nous utiliserons la bibliothèque JSON que nous avons importée et ensuite nous utiliserons la fonction loads et ensuite ce que nous passerons, réponse, ici. Donc, et ensuite je vais juste l'interrompre ici et ensuite nous allons déboguer ceci. Donc, en gros, en fait, je vais l'interrompre ici. Donc, c'est la réponse de chat dbt. Nous allons extraire la réponse. Donc, à l'intérieur de réponse maintenant, vous voyez ceci, comme, en gros, c'est juste une longue chaîne de caractères qui ressemble à, c'est un objet JSON, mais c'est, c'est en fait une chaîne de caractères. Donc, si nous collons ceci dans textedit, cela ressemble à ceci. C'est comme, il y a un guillemet devant et des trucs comme ça ou il y a, de toute façon, c'est une, c'est une chaîne de caractères, mais cette ligne de code va en fait prendre cette réponse et ensuite la charger dans un objet JSON. Donc, si nous faisons ceci, vous voyez ici, nous avons réponse et ensuite maintenant nous avons réponse dictionnaire et c'est un objet JSON approprié. Donc, si nous l'étendons, nous pouvons voir correctement, comme, nom ananas nom scientifique cette chose couleur goût nutrition etc. Donc, maintenant, euh, bien, cela va planter de toute façon parce que j'utilise toujours réponse, euh, j'ai besoin d'utiliser, comme, réponse dictionnaire ici au lieu de réponse. Donc, nous allons le regarder planter. Donc, nous allons arrêter ceci et ensuite au lieu de réponse, nous utiliserons réponse dictionnaire car ce dictionnaire de réponse est ce qui va réellement contenir l'objet que nous pouvons analyser et utiliser comme ceci. Donc, je vais exécuter ceci une fois de plus. Exécuter, démarrer le débogage. Et nous allons passer par-dessus ceci. Passer par-dessus ceci. Il charge l'objet et ensuite maintenant nous devrions pouvoir voir qu'il imprime ananas, imprime anus komosus et ensuite il se termine, comme ceci. Cool. Et ensuite, en revenant à la chose dont nous avons parlé au tout début, euh, si vous vous souvenez, nous avons ajouté ceci ici et ceci, ceci force chat GBT à, euh, sortir tout en, comme, JSON parfait. Donc, si nous supprimons ceci, comme ceci, et que nous essayons de l'exécuter, cela pourrait fonctionner, cela pourrait ne pas fonctionner. Je ne pense pas que cela va fonctionner. Euh, parce que si vous supprimez cette chose, cela supprime, comme, la capacité JSON parfaite, je suppose. Euh, donc nous allons, nous allons, nous allons voir ce qui se passe. Donc, si nous démarrons le débogage et ensuite maintenant nous avons notre réponse. Donc, nous allons passer par-dessus ceci. Euh, nous avons la réponse. Oh, en fait, ceci, ceci semble correct. Et ensuite, si, euh, cela pourrait être, cela parfois c'est effectivement correct. Donc, si nous passons par-dessus ceci, comme ceci, cela a effectivement fonctionné pour être honnête. Parfois, le problème est, comme, parfois cela ne fonctionne pas et parfois cela fonctionne effectivement. Euh, cette fois, cela a effectivement sorti en JSON parfait. Je pense que c'est parce que, euh, j'ai fourni ce schéma, donc il sait, comme, exactement quoi faire. Mais je pense que si je ne fournis pas ceci, nous allons, euh, expérimenter. Euh, c'est un peu intéressant. Je vais juste, comme, laisser ceci dans la vidéo. Donc, je vais juste, je vais juste changer notre invite. Décrivez un ananas. S'il vous plaît, sortez-le en format JSON. Je ne fournirai pas de schéma. Euh, je vais juste, comme, exécuter ceci et voir ce qui se passe parce que je pense que si vous faites ceci, cela ne sera pas en, comme, JSON parfait. Il va, comme, essayer de sortir en, comme, markdown et nous allons mettre, comme, les trois ticks devant le JSON ou quelque chose comme ça, mais nous allons, nous allons voir. Je ne suis pas sûr. Oui, il l'a fait ici. Donc, si nous essayons de charger ceci, cela va planter, euh, parce que la chose qu'il, la chose qu'il a fournie n'est pas du JSON parfait. Voyez, il y a, comme, un, euh, trois marques de tick au début et ensuite je pense qu'il y a, comme, trois marques de tick et ensuite le mot JSON à la fin. Et vous pouvez, vous pouvez en quelque sorte, comme, le nettoyer parfois. Euh, par exemple, j'espère que ce n'est pas trop confus, mais, euh, je vais vous montrer quelque chose. Réponse, vous pouvez dire, comme, euh, remplacer et ensuite ceci, ceci est une, ceci est une fonction. Et lorsque vous l'attachez à une chaîne de caractères, cela va, comme, cela va prendre tout ce que vous mettez dans le premier argument et ensuite le remplacer par ce qui est dans le deuxième argument. Donc, j'ai essentiellement dit, comme, cherchez toute instance de ce backtick et ensuite remplacez-la par rien. Cela signifie juste effacez-les. Et ensuite remplacez aussi, cela va devenir confus, mais je vais juste vous le montrer de toute façon. Et ensuite remplacez JSON par, euh, rien aussi parce que si vous vous souvenez, il a mis, comme, j'espère, j'espère que je l'ai toujours ouvert, comme, il avait quelque chose comme ceci au début, c'était comme JSON et il avait, comme, trois ticks et ensuite à la fin, il avait, comme, trois ticks. Donc, je suis essentiellement [éternue] en disant, comme, manuellement, comme, supprimez ces ticks et supprimez manuellement JSON. Donc, par exemple, je vous montre juste des trucs aléatoires. D'accord, soyez patient avec moi. Donc, nous allons passer par-dessus ceci pour obtenir notre réponse. Et vous voyez, il y a trois backticks au début de la réponse. Et ensuite, tout à la fin, il y a aussi trois backticks. Et le devant a aussi le mot JSON. Ceci, comme, ruine le format JSON parfait. Mais cette ligne de code va en fait, comme, prendre les backticks et les remplacer par rien, ce qui signifie les effacer. Prenez le mot JSON, remplacez-le par rien, ce qui signifie les effacer. Donc, si nous passons par-dessus ceci, ces ticks et JSON devraient être supprimés. Comme ceci. Voyez comment ils ont disparu. Et ensuite les backticks à la fin ont disparu. Et ensuite, je ne sais pas si cela chargera du JSON. Cela le fera si cela chargera correctement. Euh, oh, ça l'a fait. Donc, c'est comme une façon de, comme, vous savez, nettoyer manuellement la réponse si vous n'utilisez pas, euh, cette chose. C'est comme une façon de nettoyer manuellement la réponse et ensuite ça marche. Cela imprimera probablement les choses. Ça l'a fait. Euh, mais c'est, c'est mieux de, comme, au niveau de l'API, forcer la réponse à être en JSON. Si vous pouvez la forcer à être en JSON et que vous pouvez fournir le schéma, vous saurez, comme, exactement ce que GPT va retourner et cela retournera, comme, un JSON parfait à chaque fois. Donc, oui, j'espère que cela a du sens. Euh, vous pouvez vous amuser avec ceci, comme, essayer de, comme, peut-être décrire un objet sur votre bureau et essayer de, comme, imprimer les propriétés pour cela. Comme, je vais juste faire, comme, une de plus, euh, avant de quitter. Je vais juste choisir quelque chose sur mon bureau. Donc, donnez-moi une seconde. Laissez-moi supprimer ceci. Et qu'est-ce qu'il y a sur mon bureau ? Oh, je suis actuellement dans le Mato Coup au Japon. Donc, je vais dire, comme, s'il vous plaît, décrivez Matu Japon. C'est juste une région vraiment, comme, agréable à Tokyo. Euh, [éternue] s'il vous plaît, sortez en format JSON. Et ensuite je peux aller à GPT. Si je veux avoir un schéma pour cela, je vais juste dire, comme, s'il vous plaît, trouvez un schéma JSON pour décrire un, n'importe quel district au Japon. Je vais, je vais dire ceci et je vais dire schéma uniquement en JSON, s'il vous plaît. Quelques fautes de frappe mais c'est bon. GPT essaie toujours de faire tellement de choses supplémentaires. Bon sang. S'il vous plaît, rendez-le, comme, dix fois plus petit à chaque fois. Et plus court, allez. D'accord, juste assez. Et d'ailleurs, comme, je ne, peu importe. Je ne me sens pas vraiment, je ne sais pas ce que c'est pour être honnête et je n'écrirais pas le schéma comme ça, mais apparemment c'est probablement, comme, la bonne façon de le faire, mais je ne sais pas, mais je suis certain que chat dbt comprendra ce que je veux dire par là. Donc, utilisez ce schéma. Je, d'accord, je vais coller ceci ici, comme ceci. Comme ceci. Et ensuite je devrais pouvoir, comme, vous savez, je peux, je peux, je sais quelles sont les sorties, comme, le nom du district, préfecture, population, superficie, etc. Donc, je peux faire quelque chose comme ceci. Euh, je vais juste utiliser l'interpolation de chaîne ici, comme ceci. Et faites ceci. Ne vous inquiétez pas des erreurs. Nous allons corriger cela dans un moment. Donc, combien ? Un, deux, trois, quatre, cinq, six. Donc, je, je peux faire quelque chose comme ceci. Euh, laissez-moi dézoomer un peu. District. District. Je peux dire que la prochaine chose est préfecture, population, superficie, latitude, longitude, et j'aime, comme, aligner, oups. J'aime, comme, aligner les sorties, comme ceci. Comme ceci. Comme ceci. Et parce que nous savons, comme, euh, nous savons quelle sera la sortie, comme, le schéma parce que nous forçons GPT à l'utiliser. Donc, nous pouvons, comme, de manière préventive, comme, faire des choses comme ceci. Soyez patient avec moi. Je pense que si vous savez ce que je vais faire déjà, vous savez, n'hésitez pas à le faire. Et ensuite nous mettons juste les noms des propriétés ici, comme, exactement entre guillemets. Laissez-moi juste mettre préventivement ceci. Oh, en fait, vous n'êtes pas censé utiliser de guillemets doubles. Bon sang. Vous n'êtes pas censé utiliser de guillemets doubles, comme, à l'intérieur de l'interpolation de chaîne, je pense. Donc, je pense que je devrais, comme, faire de ceux-ci des guillemets simples. Je pense que cela fonctionnera, mais cela vous avertira de ne pas le faire. Donc, laissez-moi faire quelque chose comme ceci. Et ceci, cela fonctionnera probablement sans planter même si nous faisons, comme, beaucoup de préfecture, population, superficie, latitude. D'accord. Donc, euh, je vais, oui, je vais, euh, interrompre ici. Je vais supprimer ceci et je vais juste, euh, démarrer le débogage de ceci. Je vais réduire cette invite et le schéma. C'est assez grand. Inku est vraiment fou. A une architecture folle. Donc, d'accord, nous allons passer par-dessus le contenu. Nous avons obtenu notre, nous avons obtenu notre message ici. Oh, quelqu'un a sonné à ma porte. Un instant. D'accord. Donc, ici, euh, c'est [éternue] va charger notre réponse JSON dans un objet dictionnaire approprié. Nous le voyons ici. Dictionnaire de réponse. Nous voyons nom du district, préfecture, population, superficie, latitude, longitude, etc. Et ensuite nous avons fourni le schéma, donc nous savions exactement, comme, quels seraient les noms des propriétés. Donc, cela devrait juste imprimer sans, comme, sans aucun problème, comme ceci. Et se terminer. Cool. Et ensuite, nous pouvons faire, nous pouvons faire, comme, une de plus. Euh, je ne vais pas, comme, changer l'invite beaucoup, mais je veux juste vous montrer, comme, parce que nous avons fourni le schéma, nous pouvons, nous pouvons passer, comme, différentes choses ici, comme, à chaque fois. Décrivez le Congo, par exemple. Et je, je vais juste exécuter ceci sans débogage parce que la femme de ménage essaie de nettoyer ma chambre. Je vais probablement en faire deux de plus juste pour, comme, marteler le fait. Voyez, il déverse toutes les choses. Et ensuite le même schéma. Nous pouvons garder le même code ici parce que nous, il est prévisible, comme, ce que GPT va retourner parce que non seulement nous avons utilisé la propriété de type de format de réponse JSON. Nous lui avons dit de répondre en JSON et nous lui avons fourni un schéma. Donc, si nous faisons ceci, comme, à chaque fois, nous pouvons, comme, utiliser de manière répétée, comme, la même invite et tout et cela continuera à sortir, comme, la même chose, n'est-ce pas, pour, comme, n'importe quelle ville ou pays ou peu importe ce que nous mettons ici. Donc, je vais mettre, comme, Nishinari. Je vais en faire quelques-unes de plus juste pour, comme, marteler ce point. Nishinari Osaka et ensuite je vis généralement, je vis généralement ici et ensuite je vais en faire une dans, comme, je vais dire, comme, quelque chose d'obscur. Je vais dire, il Mons. Je pense que c'est la montagne lune ou quelque chose comme ça. Et je ne sais pas, comme, vous savez, ce qui va sortir. Cela pourrait planter. Préfecture Mars population zéro superficie très grande latitude. Et je vais dire, d'accord, s'il vous plaît, décrivez, euh, cette dernière. Je, je ne sais pas ce qui va se passer parce que ce n'est pas, comme, vous savez, évidemment, je vais juste exécuter ceci sans débogage, mais nous, si cela, si cela ne plante pas, je serai, comme, relativement surpris. Oh, peut-être qu'il y a une ville appelée banane. D'accord. Que diriez-vous de, comme, homme éléphant, garçon, singe, euh, gâteau, débogage ? Cela pourrait planter, mais je ne sais pas. C'est tellement intéressant. Euh, ça n'a pas planté, euh, parce que nous avons codé en dur le schéma ici et nous lui avons dit de répondre en format JSON. Donc, il l'a juste, il l'a juste fait de son mieux, mais il s'est juste confondu et a tout mis à zéro. Mais il a toujours, il a toujours retourné un objet qui avait toutes ces propriétés. Donc, par exemple, je vais juste faire, comme, cette dernière chose et ensuite nous allons terminer. Je vais juste mettre, comme, quelque chose d'obscur ici. Euh, qu'est-ce qui est obscur ? Euh, je ne sais pas. Cheesecake saveur uranium 238, quelque chose comme ça. Je ne sais pas. Et je vais déboguer ceci et ensuite nous regarderons la réponse et ensuite nous, nous terminerons ceci. Je, je suis juste en train de marteler le fait que vous pouvez, comme, forcer GPT à répondre, comme, d'une certaine manière avec, comme, un certain schéma sans planter votre programme. Donc, si nous regardons ceci, euh, dictionnaire de réponse, population 238. Oh, il fait des blagues ici. Dessert uranium 238. Il fait des blagues. Il vient de faire une blague. Il a juste fait de son mieux pour s'adapter au format de réponse que j'ai demandé et il a fourré un tas de, comme, trucs de blagues ici. Et ensuite il, il l'a quand même fait et le programme n'a pas planté parce qu'il a adhéré aux règles que nous lui avons fournies. Donc, j'espère que cela a du sens. C'est devenu un peu abstrait à la fin, mais encore une fois, j'essayais juste de vous montrer, vous savez, que vous pouvez le forcer à répondre d'une certaine manière. Et dans le monde réel, cela aura plus de sens et nous l'utiliserons pour, comme, formater nos résultats de chasse aux menaces. Mais oui, j'espère que cela a du sens. Et si ce n'est pas le cas, allez sur les forums, posez des questions, taguez-moi, utilisez chat dbt, et nous nous verrons dans la prochaine leçon. Cool. Bienvenue de retour. Euh, c'est une leçon vraiment intéressante. Euh, ce sera un peu difficile, alors faites de votre mieux pour faire attention et préparez-vous à poser des questions sur les forums si vous en avez besoin. Euh, j'ai eu du mal à trouver un titre réel pour cette leçon. Je pense que je vais l'appeler quelque chose comme, euh, donner un sens à l'entrée ambiguë de l'utilisateur ou ou quelque chose comme ça. Euh, comme, nous voulons essentiellement, nous voulons prendre une entrée de l'utilisateur et ensuite la distiller pour savoir exactement ce qu'ils voulaient dire, leur vraie intention, et ensuite utiliser cela pour prendre une sorte de décision dans notre code. Et vous verrez, comme, exactement ce que je veux dire dans une seconde. Et vous avez besoin de deux fichiers avec ceci, un, bien sûr, vous pouvez, comme, tout taper si vous le souhaitez. Et je le recommande un peu, juste pour la mémoire musculaire, mais je vais inclure ceci, comme, qu'est-ce que c'est ? Ce node tools main.py py et ce tools main.py. Euh, donc obtenez-les simplement à partir du lien ou du, oui, du lien ci-dessous et ajoutez-les à votre dossier, puis ouvrez votre dossier dans VS Code. Mais en gros, je vais juste expliquer, euh, ce que fait ce programme et ensuite nous allons, c'est un programme sans utiliser open AI ou sans utiliser d'IA du tout. Et je vais vous montrer, comme, je vais utiliser ce programme, euh, pour vous montrer pourquoi ce que nous essayons de faire est utile, comme, pourquoi ce mécanisme d'outils ou le sélecteur de fonction open AI, j'oublie comment il s'appelle, mais de toute façon, vous aurez une idée du problème avec ce code et ensuite nous allons le résoudre à l'intérieur de tools.mmain. py si cela a du sens. Donc, en gros, ce que fait ce programme, je vais juste l'expliquer et ensuite je vais l'exécuter. Nous avons, comme, une liste d'aliments malsains. Et d'ailleurs, ne vous attardez pas sur, comme, comme, les bonbons peuvent être sains. Comme, juste, vous savez, soyez patient avec moi sur ceci. Donc, nous avons, comme, une liste d'aliments malsains. Et ensuite nous avons, comme, une liste d'aliments sains. Et en gros, nous demandons à l'utilisateur, comme, quel est votre aliment préféré ? Et ensuite, en fonction de sa réponse, nous décidons, euh, vous savez, nous prenons juste la décision que la personne est saine ou que la personne est, euh, ou plutôt que la personne est malsaine ou que la personne est saine en fonction de son aliment préféré. Donc, si l'aliment préféré de quelqu'un est les donuts, n'est-ce pas, nous pouvons, en fonction de ce code de toute façon, nous pouvons supposer que la personne n'est pas en bonne santé et ensuite plus tard, plus tard dans le code, si la personne est en bonne santé, nous la félicitons et si la personne n'est pas en bonne santé, nous, vous savez, nous la réprimandons, n'est-ce pas ? Euh, mais si nous ne pouvons pas prendre la décision, comme, nous ne savons pas, comme, nous allons juste dire que nous ne savons pas, n'est-ce pas ? Donc, nous allons juste exécuter ce programme. Euh, je vais l'interrompre ici après avoir obtenu l'entrée de l'utilisateur. Donc, je vais dire exécuter, démarrer le débogage et vous verrez, comme, pourquoi c'est problématique. Donc, quel est votre aliment préféré ? Je vais dire, comme, légumes, n'est-ce pas ? Je vais dire légumes et ensuite nous allons passer par-dessus ceci et cela dit, comme, la réponse est légumes parce que nous l'avons tapé. Donc, nous regardons, si réponse est dans aliments malsains, nous allons dire qu'ils ne sont pas en bonne santé. Donc, les légumes ne sont pas ici. Donc, si nous essayons de passer, cela va le sauter. Donc, nous allons vérifier, est-ce que réponse est dans aliments sains ? Il semble que légumes soit ici. Donc, comme, personne est saine est assigné à vrai. Et ensuite il dit, si personne est saine égale vrai. Ils font ou je suppose que c'est le cas. Donc, il imprime, bon travail. Continuez comme ça. Et ensuite le programme se termine, comme ceci. Et ensuite, de même, euh, je vais exécuter ceci une fois de plus, par exemple. Et je vais l'exécuter sans débogage cette fois. Je vais juste laisser la sortie s'afficher. Ou peut-être que je devrais, je devrais le déboguer en fait, donc les gens peuvent avoir une idée. Donc, je, je vais le déboguer. Donc, il demande, quel est votre aliment préféré ? Je vais dire, comme, donuts cette fois. Je vais dire donuts. Je vais dire entrer. Et ensuite la personne, la personne n'est pas en bonne santé, n'est-ce pas ? Il a été assigné, personne n'est saine est faux. Si personne n'est saine, vrai. Ils ne le sont pas. Il saute. Si personne n'est saine égale faux, c'est parce qu'ils ne sont pas en bonne santé parce qu'ils mangent des donuts. Et ensuite il imprime à l'écran, vous devez faire de meilleurs choix. Et ensuite terminer. Donc, euh, que faire si nous voulons, comme, entrer un aliment qui est, vous savez, qui est malsain, n'est-ce pas ? Mais il n'est pas dans ces listes, n'est-ce pas ? Donc, je vais exécuter ceci à nouveau. Je vais le déboguer et je vais dire, comme, qu'est-ce qui n'est pas sain ? Euh, comme Twinkie, peut-être. Je vais dire Twinkie, Twinky, Twinkies. Donc, il va vérifier, est-ce que Twinkies n'est pas sain, n'est-ce pas ? Tout le monde le sait. Donc, nous allons, mais nous allons regarder dans aliments malsains. Est-ce que c'est, euh, ici ? Et ce n'est pas en fait. Euh, est-ce que c'est dans aliments sains ? Ce n'est pas. Et donc, il va par défaut à personne n'est saine égale à none parce que, comme, nous ne savons pas. Nous ne pouvions pas discerner s'ils sont vrais, s'ils sont, comme, s'ils sont sains ou non, n'est-ce pas ? Donc, personne n'est saine égale à none. Euh, personne n'est saine égale à vrai. Ce n'est pas vrai. Personne n'est saine égale à faux. Ce n'est pas vrai non plus. Donc, il par défaut à, je ne sais pas. Il imprime, je ne sais pas. Et ensuite le programme se termine. Donc, comme, une façon facile, une façon vraiment facile de résoudre ceci, nous pouvons juste dire, comme, d'accord, comme, vous savez, les Twinkies ne sont pas sains. Twinkies, n'est-ce pas ? Nous pouvons simplement l'ajouter à la liste d'aliments malsains. Donc, nous allons, euh, exécuter ceci à nouveau. Nous allons le déboguer. Donc, quel est votre aliment préféré ? Je vais dire Twinkies. Et ensuite, est-ce que réponse est dans aliments malsains ? C'est ici. Donc, naturellement, ils sont assignés, personne n'est saine égale à faux. Il faut montrer que ce sont, comme, réellement, comme, séparés. Euh, donc ce qui descend ici est, personne n'est saine égale à vrai ? Ce n'est pas parce que c'est faux. Oh, j'ai, j'ai foiré ceci. Oh mon dieu. C'est bon. Est-ce que personne n'est saine est, est ce que personne n'est saine égale à faux ? C'est vrai. Donc, cela imprimera. Vous devez faire de meilleurs choix. Et ensuite le programme se termine. Mais que faire si, vous savez, nous déboguons ceci à nouveau ? Et ensuite que faire si nous voulons dire quelque chose comme, euh, qu'est-ce qui est, comme, qu'est-ce d'autre qui est malsain, n'est-ce pas ? Comme, un gâteau géant, par exemple, ou un gâteau rouge géant, par exemple, n'est-ce pas ? Vous pouvez voir, comme, où cela va. Comme, le gâteau rouge géant n'est pas dans cette liste, n'est-ce pas ? Donc, vous savez, il ne sait pas comment répondre. Donc, il le définit juste à, comme, none parce qu'il ne sait pas s'ils sont sains ou non en fonction de nos paramètres. Donc, encore une fois, il va imprimer, je ne sais pas. Donc, oui, bien sûr, nous pouvons résoudre ceci en ajoutant, comme, vous savez, gâteau rouge géant, mais vous pouvez comprendre où cela va. Il y a essentiellement un nombre infini de choses qui sont malsaines et un nombre infini de choses qui sont saines, comme, effectivement infinies. Donc, vous avez besoin d'une sorte de, comme, cognition, pas d'une liste codée en dur, mais vous avez besoin d'une sorte de, comme, cognition pour faire la distinction ou faire, est-ce le bon mot, pour prendre la décision de savoir si quelque chose est sain ou non. Et c'est là que, comme, Chad GBT, euh, et Open AI et je suppose les LLM en général entrent en jeu pour aider avec ceci. Donc, nous avons terminé avec ceci. Pas, pas de fonction tools.mmain ici. Donc, nous allons juste dire, bien, nous pouvons le sauvegarder. Ça n'a pas vraiment d'importance. Donc, nous allons passer à, je vais fermer ceci. Fermer ceci. Donc, ensuite, nous allons passer à tools.main et ensuite je vais expliquer, comme, comment cela fonctionne. Je suppose que je vais juste exécuter le programme d'abord et ensuite vous pourrez voir ce qui se passe. Euh, et je vais, je vais l'exécuter sans le déboguer. Je vais juste le laisser s'exécuter et ensuite j'expliquerai tout à la fin. Donc, je vais juste effacer cette sortie ici en bas et ensuite je vais juste dire exécuter sans débogage. Et ensuite, quel est votre aliment préféré ? Un putain de gâteau rouge géant rempli de Twinkie et, euh, de Ding-Dongs, par exemple. Évidemment, nous ne, ce ne sera dans aucune liste nulle part, n'est-ce pas ? Donc, nous allons juste, comme, exécuter ceci et ensuite notre programme s'exécute. Il retourne. Oh, je devrais, comme, euh, arrêter d'imprimer ces deux. Je vais, comme, commenter ces deux-là, mais il dit, "Oh non, ce gâteau est une crise cardiaque qui attend d'arriver. Sérieusement, arrêtez de manger de la malbouffe. Mangez de la vraie nourriture avant que vos artères ne se rebellent." D'accord, donc je vais, euh, exécuter ceci une fois de plus et je vais dire, comme, un aliment sain pour une fois. Donc, je vais dire, comme, démarrer, euh, exécuter sans débogage. Quel est votre aliment préféré ? Euh, un saumon de l'Atlantique géant frais et chaud, mal orthographié, euh, avec du citron et une portion de riz brun bien sûr. Ça a l'air assez sain. Donc, nous avons une réponse. Bon travail. C'est un repas génial. Saumon frais, bla bla bla. C'est, c'est sain, n'est-ce pas ? Donc, en gros, euh, nous devons utiliser, comme, vous savez, la façon dont notre code est configuré, n'est-ce pas ? Il va essentiellement déterminer si la personne est saine ou non et s'ils sont, s'ils sont sains, ils imprimeront bon travail et, comme, note à l'utilisateur, comme, ce message aléatoire et s'ils ne sont pas sains, il imprimera oh non et ensuite note à l'utilisateur, d'accord ? Donc, en gros, j'ai oublié comment s'appelle cette chose en fait, je pense qu'elle s'appelle, comme, des fonctions open AI ou quelque chose comme ça et la façon dont je l'utilise ici n'est pas, je ne pense pas que ce soit la façon prévue de l'utiliser, mais en gros, euh, si vous vous souvenez, tout ceci, c'est ce que nous avons utilisé pour poser des questions à chat GPD, ou plutôt le point de terminaison GPT d'Open AAI où nous spécifions, comme, le modèle et ensuite nous spécifions, comme, l'invite, comme, le message. Euh, mais maintenant nous passons, comme, deux choses spéciales. Euh, une, une chose [éternue] est des outils. Cette variable d'outils est non négociable, mais nous devons lui passer, comme, un objet spécial et ensuite un choix d'outil, que j'expliquerai un peu. Euh, nous pouvons dire, comme, auto ou requis ou peut-être autre chose. Mais ce choix d'outils d'évaluation du style de vie, je vais l'étendre et expliquer ce que c'est. Donc, les outils que nous passons, ceci, cela passe essentiellement beaucoup de contexte à chat GPT. Et cela doit être dans ce format. Donc, ne vous inquiétez pas d'être, comme, oh, ce format est, comme, déroutant. Je dois le mémoriser. Comme, vous n'avez pas à le mémoriser. J'ai juste appris cela probablement de Google ou de leur documentation API et je l'ai juste, comme, adapté à ce que je voulais faire. Donc, ne vous attardez pas trop là-dessus, mais je vais juste l'expliquer un peu. Euh, donc le type est fonction. Euh, prenez juste cela au pied de la lettre. Vous pouvez l'ignorer en quelque sorte. Et ensuite, c'est la fonction réelle et le nom. Nous n'utilisons pas le nom, mais la description est ce qui est important. Euh, je lui donne le contexte de ce que j'essaie de faire. Comme, une recommandation de style de vie. Comme, cela retournera une recommandation de style de vie pour l'utilisateur en fonction de son aliment préféré. Si l'aliment préféré d'un utilisateur est sucré ou malsain, encouragez-le à manger sainement. Si l'aliment préféré de l'utilisateur est sain, encouragez-le à continuer. Soyez extrêmement direct. Par exemple, si son aliment préféré est le Crisco, vous pourriez lui recommander de faire des changements sérieux. Cette invite est, comme, vraiment mauvaise, mais vous comprenez, comme, l'essentiel. Comme, nous allons évaluer ce que l'utilisateur, comme, mange, comme, quel est son aliment préféré, puis nous allons faire des recommandations basées sur son aliment préféré, et ensuite ces paramètres, euh, c'est essentiellement ce que, euh, GPT nous retournera, et cela aura beaucoup de sens plus tard, mais en gros, euh, il va, lorsqu'il inspectera leurs invites, il prendra cela en considération, puis il prendra, comme, certaines décisions dans son grand cerveau IA, puis il nous retournera ceci. Donc, par exemple, personne n'est saine. C'est un booléen. Donc, il retournera personne n'est saine, vrai ou faux en fonction de ceci. Et la description de cette personne est saine est une valeur booléenne pour déterminer si la personne est saine en fonction de ses aliments préférés. Supposez qu'ils consomment cette chose régulièrement, qu'ils l'ont entrée. C'est, comme, plus de contexte pour GPT. Et ensuite cette autre chose, note à l'utilisateur, c'est une chaîne de caractères qu'il va retourner. Recommandation à l'utilisateur. Euh, par exemple, bon travail, continuez comme ça, ou arrêtez de manger de la malbouffe. Donc, en gros, nous allons alimenter l'invite dans chat GBT. Nous allons lui donner ce contexte, puis nous allons lui dire, vous devez nous retourner ces deux choses. Et ensuite nous lui disons, euh, il est requis de retourner les deux choses. Donc, c'est comme le style de vie, les outils d'évaluation du style de vie que GPT utilisera pour, comme, prendre une décision ou c'est un contexte supplémentaire pour lui, nous pouvons dire. Donc, c'est, comme, à peu près la même chose. Euh, je vais juste interrompre ceci et l'exécuter à nouveau. Donc, je vais démarrer le débogage juste pour que vous puissiez, comme, parcourir et observer. Je sais que c'est, comme, un peu déroutant. Euh, mais c'est juste comme ça que ça marche. Donc, quel est votre aliment préféré ? Je vais dire, comme, euh, vous savez, qu'est-ce qui est quelque chose de stupide ? Euh, je vais dire poudre de protéines blueprint par Brian Johnson. Ne meurs pas marque, par exemple. Entrer. Et ensuite nous avons notre invite ici. Poudre blueprint. La poudre de protéines blueprint par Brian Johnson est comme, ne meurs pas. Donc, cela va demander à Chad GBT et cela va passer, c'est un modèle que nous voulons utiliser. C'est notre invite. Et ensuite, il va passer tout cet objet d'outils d'évaluation du style de vie dans le paramètre d'outils. Et ensuite le choix de l'outil est requis. Donc, il doit choisir, euh, il doit choisir, oh mon dieu, je ne sais pas en fait. Oh, il doit choisir quelque chose. Je pense que c'est ce que c'est. Il doit, comme, nous retourner quelque chose. Il ne peut pas dire qu'il n'y a, comme, rien, n'est-ce pas ? Donc, il doit, comme, faire de son mieux pour choisir, euh, quelque chose d'ici et, comme, il doit utiliser les outils. Donc, nous allons continuer avec ceci. Donc, et cela demande à GBT maintenant. Et donc, nous allons

Extraire la réponse. Et ensuite, nous allons extraire ou convertir la réponse en un objet dictionnaire ou un objet JSON. Donc, si nous développons ceci, nous pouvons voir comme un dictionnaire de réponse. C'est comme l'objet JSON réel qui a été renvoyé. Il dit que la personne est en bonne santé égale vrai. Et ensuite, c'est le message personnalisé. Bon travail. Vous avez en fait privilégié les protéines de qualité comme Brian Johnson, bla bla bla. Mais nous allons laisser cela se terminer et je vais vous montrer d'autres choses. Donc, il a extrait cela et il a attribué deux variables, une note à l'utilisateur et ensuite la personne est en bonne santé et ensuite si la personne est en bonne santé, si cela est égal à vrai, il va imprimer ces choses, bon travail et ensuite c'est en bonne santé, bla bla bla et ensuite le programme se termine comme ça. Donc, je vais faire quelques-unes de ces choses. Je vais juste le laisser s'exécuter. Vous pouvez déboguer le vôtre si vous le souhaitez, si vous voulez vraiment l'inspecter. Euh, mais je vais juste exécuter cela quelques fois et ensuite je vais augmenter un peu les outils et augmenter notre code. Euh, juste pour quelques choses supplémentaires à vous montrer, pour vous montrer quelque chose et donner plus de contexte. Donner plus de contexte. Donc, je vais juste exécuter cela sans débogage. Et ensuite, je vais lui donner quelque chose de difficile. Une gigantesque salade César remplie de poitrine de poulet. mauvaise orthographe. Et euh avec 3x vinaigrette César et croûtons, peu importe, et du bacon et un tas de fromage. Cela pourrait aller dans un sens ou dans l'autre, mais probablement à cause de mon verbiage, cela ne va pas me plaire. Oh non, vous avez bourré une salade de poulet frit, de vinaigrette supplémentaire, bla bla bla. Il se moque un peu de moi pour avoir fait cela. Donc, je vais juste en faire une de plus. Je vais dire commencer le débogage et je vais dire je ne sais pas, quelque chose d'autre d'intéressant. Euh, 10 œufs crus. Donc, il n'aime pas ça. Euh, mais vous comprenez l'idée. Donc, nous pouvons l'augmenter un peu. Par exemple, si nous voulons retourner, euh, nous voulons retourner quelque chose d'autre, comme en ce moment, nous retournons juste si la personne est en bonne santé ou une note à l'utilisateur et une note à l'utilisateur qui est comme cette note qu'elle nous donne, arrêtez de manger des œufs crus, bla bla bla. Euh, nous pouvons l'augmenter et nous pouvons faire plus. Ou alors, je vais juste copier ceci et ensuite je vais le coller et je vais dire, euh, je vais appeler ceci auto-justification par exemple et ensuite pour ceci et ensuite je vais dire quelque chose comme, euh, c'est la raison de votre choix si vous avez décidé que l'utilisateur n'était pas en bonne santé ou en bonne santé en fonction de sa nourriture préférée. Vous devez expliquer pourquoi ici. Donc, auto-justification, ils ont appelé cela. Donc, par exemple, je vais faire défiler vers le bas. raison, nous pouvons dire dictionnaire de réponse donc et ensuite je vais le mettre en pause ici afin que nous puissions réellement voir, euh, ce dictionnaire de réponse est ce qui est renvoyé par chat GBT, euh, basé sur cette fonction d'outils, comme nous lui avons dit ce qui doit être renvoyé, oh, je dois aussi mettre ceci ici, donc je vais dire que c'est requis, donc il doit dire quelque chose, il doit le renvoyer. Donc, je vais juste commencer à déboguer ceci. Quelle est votre nourriture préférée ? Euh, je vais dire, euh, brownies végétaliens. Brownies faits, oh mon dieu. faits avec de la poudre de cacao et du jus d'ananas, peu importe, comme édulcorant. Donc, et ensuite il va demander à GPT. Donc, cela prendra quelques secondes. Laissez-le faire cela et développez ceci. Je vais regarder cela pour que vous puissiez vraiment le voir. Donc, c'est la réponse que nous avons obtenue de GPT. C'est comme un objet assez grand. Donc, si nous regardons ici, choix de réponse et ensuite le zéroième élément. Donc, si nous allons dans choix de réponse et ensuite le zéroième élément et ensuite appels d'outils de message, nous allons dans appels d'outils de message et ensuite le zéroième élément ici, comme ça. Euh, c'est je pense que la réponse devrait être ici. Oh, ça devrait être une fonction. Oh, donc cette chose, ces appels d'outils, tout cela à l'intérieur sera attribué à cette variable de réponse. Donc, si nous passons par-dessus cela et ensuite nous avons notre variable de réponse. Donc, si je monte ici et ensuite arguments de fonction de réponse. Donc, arguments de fonction de réponse et ensuite ceci, c'est la chose, euh, que GPT a renvoyée. Il a renvoyé comme une chaîne JSON. C'est une chaîne mais c'est du JSON. Euh, où nous pouvons voir que la personnalité est vraie et nous pouvons voir une note à l'utilisateur et ensuite nous pouvons voir comme la justification devrait être ici aussi. Euh, mais c'est vraiment long. Donc, je vais juste, euh, passer par-dessus cela. Et ensuite, nous pouvons voir notre dictionnaire de réponse. Et ensuite, nous voyons comme la personne est en bonne santé, vrai. Nous voyons une note à l'utilisateur, ce que nous allons dire à l'utilisateur. Et ensuite, c'est la justification. Euh, nous pouvons la voir ici. C'est un peu, vous savez, difficile à lire. C'est assez long. Euh, laissez-moi voir si je peux faire ça parce que j'ai oublié de l'imprimer à l'écran. Donc, je vais juste le coller. C'est la justification de pourquoi GPT, euh, a décidé que c'était sain. La poudre de cacao fournit des antioxydants. L'ananas est un édulcorant. Une grosse amélioration par rapport au sucre transformé. Bla bla bla. C'est sa justification. Donc, nous pouvons juste imprimer cela comme d'habitude. Euh, je n'ai pas vraiment utilisé la justification. Je l'ai juste attribuée. Donc, et ensuite nous pouvons peut-être l'augmenter. Euh, moi, euh, [renifle] faire quelque chose comme ça. Laissez-moi ajouter quelques, euh, sauts de ligne ou peu importe pour que ce soit plus facile à lire. Et ensuite, peut-être que je ferai quelque chose ici. Imprimer la raison. Je pense que j'ai attribué la justification. Je l'ai fait. J'ai attribué la justification à la variable raison, donc je vais juste, je vais utiliser une chaîne f ici juste pour que je puisse, euh, peut-être faire un saut de ligne avant ou quelque chose. Cela va ressembler, euh, non, c'est probablement bon. Ok. Donc, je vais juste en faire une autre juste pour le plaisir. Donc, nous allons exécuter cela. Donc, je vais juste exécuter cela sans débogage une fois. Vous pouvez déboguer le vôtre si vous le souhaitez. Donc, quelle est votre nourriture préférée ? Je vais dire une pizza avec, euh, une croûte faite de poitrine de poulet et qu'est-ce que c'est, du fromage ? Parmesan rendu croustillant. Double cuisson. euh, sauce faible en sodium, euh, sodium et mozzarella fraîche. Je ne sais pas comment épeler mozzarella, mais peu importe. Mozzarella fraîche. Je vais dire ceci, cela pourrait aller dans un sens ou dans l'autre. Vous ne savez pas, n'est-ce pas ? Boum. Bon travail. Beau travail. Cette pizza est comme, peu importe. C'est bon pour vous et riche en protéines, faible en glucides inutiles. Et ensuite, c'est comme la justification qu'il a donnée. Donc, peut-être que je devrais, euh, dire barre oblique inverse et justification. Et ensuite, je vais, euh, faire une de ces choses. En fait, je n'en ai pas besoin. C'est comme du code redondant parce que nous allons imprimer la note à l'utilisateur de toute façon. Donc, je vais dire imprimer, euh, je vais dire note à l'utilisateur, puis je vais dire note à l'utilisateur, comme ça, et ensuite je vais peut-être en faire une de plus et ensuite je vais, je vais casser celle-ci et nous allons la parcourir. Quelle est votre nourriture préférée ? Euh, qu'est-ce qu'il y a dans ma chambre en ce moment ? Ok, j'ai cette chose que l'hôtel m'a donnée. Kakatan avec du fromage à la crème dans du fromage de Kakatan. Il est écrit ceci partout sur la boîte. Fromage, poivre noir. Euh, buraku pep parce que je suis au Japon. Fromage. Wow. Ok, c'est ma nourriture préférée. J'ai juste tapé ce qui était sur la boîte. Donc, euh, nous allons, je vais juste continuer cela et nous devrions nous arrêter ici. Oh, ça n'a pas. Ok, je vais continuer cela à nouveau. Et ensuite, il va extraire la réponse. Et ensuite, il va extraire ceci du dictionnaire. Donc, note à l'utilisateur, personne est en bonne santé. Euh, je peux déjà voir que c'est faux à gauche. Et la raison, euh, je vais juste laisser cela imprimer, je suppose. Oh, désolé, je n'ai pas fait ça. Laissez cela imprimer. Euh, la personne n'est pas en bonne santé. Donc, il a sauté ici. A dit oh non, note à l'utilisateur. Euh, c'est du fromage surchargé de snacks transformés et de saveurs intenses. Vous devriez essayer de le modérer avec des légumes et des fruits de temps en temps. Vos artères vous remercieront. Et ce fromage, il a vraiment un goût, c'est comme un cracker. C'est assez bizarre. Euh, ça a un goût [renifle] ok. Ça a un goût ok, mais Et la justification, euh, je ne sais pas. Kakatane, fromage à la crème avec du poivre noir supplémentaire est un snack riche en sodium et en graisses. C'est fortement transformé. Oh oui. Ok. J'aurais pu le deviner. Euh, mais oui, j'espère que cela a du sens. Euh, en fait, pendant que nous sommes ici, je vais juste ajouter une chose de plus ici. Euh, peut-être donc maintenant nous avons comme personne, nous allons lui faire retourner personne est en bonne santé, une note à l'utilisateur, auto-justification, et ensuite nous allons en ajouter une de plus, comme une suggestion alternative ou quelque chose comme ça. Donc, au lieu de cela, pourquoi n'avez-vous pas ceci ? Donc, je vais dire suggestion alternative. Donc, nous pouvons dire, suggérer, je ne sais pas, une chose alternative plus saine si l'utilisateur, euh, je ne sais pas, je ne sais pas. Ok, je vais dire suggérer une chose plus saine, peu importe si l'utilisateur, peu importe. Je vais mettre une mauvaise orthographe à dessein. La nourriture préférée de l'utilisateur est saine ou non. Et ensuite, je vais ajouter cela ici. Suggestion alternative, comme ça. Oups. Et ensuite, je vais descendre ici. Et ensuite, je vais juste copier cette suggestion alternative. Mon dieu. Suggestion alternative, comme ça. Et ensuite, je vais juste ajouter cela ici aussi. Nous allons dire imprimer, utiliser une chaîne f, alternative, alter. Oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh, oh

Je m'attendais à voir des lignes ou quelque chose comme ça. Colonnes temps généré. Je suppose qu'il y a des lignes quelque part. Oh, c'est ici. Non, dataframe KQ query. Je me demande pourquoi c'est là. C'est tellement intéressant. Oh. Oh, c'est le euh je pense que c'est ça. Valeurs underscore peut-être. Taille 380. C'est intéressant. Je ne sais pas pourquoi il n'y en a que autant de longues quand j'avais comme 100 enregistrements. Mais bon, vous avez une idée. Le but principal était juste de vous montrer que nous pouvons faire des requêtes KQL avec Python, puis nous pouvons retourner les données et nous pouvons les observer et faire quelque chose avec. Donc, je vais juste regarder dans une autre table au lieu de device lo on events. Je veux juste vous montrer que vous pouvez regarder dans d'autres tables aussi. Et il y a comme une tonne de tables. Donc, par exemple, laissez-moi regarder ce que nous devrions regarder, analyse du comportement des utilisateurs. Analyse des pairs d'utilisateurs. Je veux juste voir ce qu'il y a ici. Par exemple, analyse du comportement, prendre 50. Temps de traitement. Oh, c'est intéressant. Oh, d'accord. Connexion échouée. Oh, c'est tellement intéressant. Euh, d'accord. Donc, nous pouvons prendre ceci juste pour l'exemple. Instance, je veux faire deux choses de plus dans cette leçon. Donc, je vais copier ceci. Je veux juste interroger une autre table juste pour avoir une idée que c'est possible. Donc, je vais coller la requête ici et je vais juste la relancer et je vais juste la laisser se déverser sur l'écran pour que nous puissions l'observer et nous allons l'imprimer. Et puis nous voyons qu'elle s'imprime. Euh, il semble qu'elle ait tronqué comme le euh elle a résumé les lignes aussi car il y en a trop. Ils ont mis comme trois points parce que nous n'avons rien projeté. Donc, par exemple, c'est la requête ici. Donc, si nous voulons projeter seulement certains journaux, nous pouvons ou certaines lignes, nous pouvons dire comme euh projeter le temps généré, euh peut-être le type d'activité, le type d'action, le nom d'utilisateur. Ce sont comme les vrais noms d'utilisateur de la cyber-plage. Oh, peut-être que nous devrions utiliser le nom d'utilisateur principal et ensuite la source de l'événement, l'adresse IP source. C'est comme la vraie adresse IP du membre de la cyber-plage. Et c'est pourquoi euh je n'en ai pas parlé dans ce cours, mais euh si vous êtes membre de la cyber-plage, votre nom d'utilisateur principal ou votre nom d'utilisateur avec lequel vous vous connectez à la cyber-plage est un peu fou euh c'est comme une grille. C'est ce nombre fou parce que nous pouvons voir les journaux dans la cyber-plage et si cela dit comme, vous savez, Maggie aimerait comme Maggie Wilcox à l'intérieur de, vous savez, San Jose, peu importe, et l'adresse IP, cela complètement euh la personne, vous savez, euh donc c'est, vous savez, c'est pourquoi nous avons fait cela et si votre organisation peut voir des choses similaires aussi, donc vous savez, gardez cela à l'esprit, je suppose, et puis l'emplacement de l'adresse IP source et peut-être que c'est suffisant. Donc, nous allons exécuter cette requête juste pour voir à quoi elle ressemble. Le nom d'utilisateur principal est vide. Donc, je vais juste utiliser le nom d'utilisateur, je suppose. Et puis peut-être que je dirai comme où le type d'action ou je dirai où je vous donne juste une leçon KQL euh je suppose que nous pouvons dire où n'est pas vide le type d'action et puis et n'est pas vide euh quelle est l'autre chose que j'ai dite, le nom d'utilisateur. Donc, nous allons exécuter ceci. Et maintenant nous voyons, nous voyons une bonne quantité de journaux. Euh, peu importe. Donc, nous allons copier ceci. Je fais juste un exercice, n'est-ce pas ? Et nous allons coller ceci ici. Et je vais juste dire comme prendre 25 ou quelque chose comme ça. Et nous allons juste exécuter ceci à nouveau. Et cela va s'imprimer. Et puis nous voyons qu'il imprime le dataframe. Euh, a comme l'heure à laquelle c'est arrivé, l'activité, l'adresse IP. [s'éclaircit la gorge] C'est probablement le qu'est-ce que c'est ? Oh, l'emplacement. Il semble qu'il ait tronqué ou résumé et supprimé certaines des lignes aussi. Il y a probablement une raison pour laquelle il fait cela. Comme il veut imprimer très joliment et qu'il y a trop de lignes ou quelque chose comme ça. Je ne sais pas. Mais si nous voulons et nous le ferons à l'avenir, nous pouvons programmatiquement y accéder et en fait extraire, le transformer en une chaîne brute, puis nous l'enverrons à l'API GPT et ferons de la chasse aux menaces avec et tout le reste. Donc, le but de l'extraction de ces journaux est que nous en avons besoin pour, vous savez, faire de la chasse aux menaces et envoyer au modèle et tout ça. Donc, je voulais juste avoir cette leçon pour montrer qu'il est en fait possible d'interroger l'espace de travail d'analyse des journaux avec Python. Et j'espère que cela a du sens. Euh, si vous êtes bloqué ou si vous avez des questions ou quoi que ce soit, euh, vous savez, allez absolument sur le forum de la cyber-plage et publiez et taguez-moi et puis euh, vous savez, faites-nous savoir ce qui ne va pas. Sinon, nous vous verrons dans la prochaine leçon. Bienvenue. Euh, bienvenue dans la prochaine leçon. U celle-ci, nous allons en fait interroger davantage l'espace de travail d'analyse des journaux, mais nous allons le faire d'une manière plus structurée, en utilisant en fait une fonction et en choisissant les données que nous sélectionnons de la table d'une manière plus organisée, et j'espère que cela aura du sens au fur et à mesure. Mais euh, cette leçon sera vraiment importante car nous allons nous en baser sur elle. Nous allons nous en baser sur elle dans la prochaine leçon. Euh, en gros, nous allons travailler à optimiser notre requête car, en fin de compte, nous allons construire un agent d'analyste de SOC IA, comme un agent qui fait de la chasse aux menaces et en gros, plus nous envoyons de journaux à ChatGPT, plus cela coûte. Donc, nous voulons vraiment minimiser la quantité de journaux envoyés à ChatGPT. Donc, avec ceci, nous allons nous en baser un peu dessus et tout cela aura beaucoup de sens dans la prochaine leçon. Donc, je ne veux pas trop en parler, mais nous allons juste passer à celle-ci et je vais expliquer ce que tout cela est. Donc, en gros, euh, il y a beaucoup de tables différentes que nous pouvons interroger et rechercher des journaux dans Log Analytics. Donc, par exemple, si vous vous connectez à Azure, vous savez, portail. Connectez-vous avec votre nom d'utilisateur de la cyber-plage et allez à l'analyse des journaux. C'est notre dépôt de journaux. Prenez celui de la cyber-plage. Ensuite, allez dans journaux et fermez ceci. Et si cela dit mode simple, changez-le en mode KQL. Et puis faites du mode KQL la valeur par défaut. Je ne le fais pas. Et puis vous verrez qu'il y a des tables ici et qu'il y a beaucoup de tables différentes. Donc, différents types de données sont enregistrés dans différentes tables dans l'environnement. Donc, par exemple, euh, activité Azure, eh bien, activité Azure, c'est comme si vous créez une machine virtuelle ou créez n'importe quel type d'objet dans le portail Azure, cela sera enregistré dans l'activité Azure et les journaux de connexion, c'est comme euh quand vous, si quelqu'un se connecte à Azure, comme un membre de la cyber-plage ou quelque chose comme ça, cela enregistrera tout, comme si c'était un succès ou un échec, d'où ils venaient, etc. Il y a juste une tonne de journaux ici, n'est-ce pas ? Mais pour cet exercice, euh, je vais juste travailler avec ces journaux en particulier ou ces tables comme ceci, comme les événements de connexion de périphérique. Euh, c'est comme si quelqu'un essayait de se connecter à une machine virtuelle. C'est comme le groupe de sécurité réseau de la cyber-plage, alias le pare-feu, et ensuite l'activité Azure, juste des choses dans le portail, la création de machines virtuelles, la suppression de choses, et ensuite les journaux de connexion chaque fois que quelqu'un se connecte à Azure. Donc, c'est à peu près ce que sont ces choses. Et puis cette chose ici. Euh, c'est un dictionnaire appelé champs et puis par exemple, c'est le nom de la table et puis ce sont les champs que euh je veux interroger dans la table. Donc, par exemple, euh, et j'ai juste choisi ceux-ci à la main. Donc, je vais vous montrer ce que je veux dire. Donc, si je vais à, si je copie les événements de connexion de périphérique, puis que je vais à l'analyse des journaux et que je colle simplement les événements de connexion de périphérique, il y a comme, il y a trop de champs. Ce sont comme les colonnes ou les champs. Il y en a trop. Il y en a beaucoup et nous n'avons pas besoin de beaucoup d'entre eux, n'est-ce pas ? Et si nous collectons tous ceux-ci, cela crée juste beaucoup de jetons inutiles car nous n'avons pas besoin de collecter l'ID du locataire à chaque fois et d'envoyer une tonne d'ID de locataire à ChatGPT car cela n'aide pas à notre utilisation, je veux dire, cela pourrait aider, mais cela n'aide pas dans notre cas d'utilisation, la plupart du temps, cela n'aidera pas à trouver des menaces ou quoi que ce soit. Donc, vous pouvez aussi dire quelque chose comme euh obtenir le schéma comme ça et puis l'exécuter et puis vous pouvez voir les différents champs, alias les colonnes et vous voyez qu'il y en a beaucoup, il y en a comme 53, vous n'avez pas besoin de tous ceux-ci pour faire de la chasse aux menaces, donc j'ai juste choisi à la main ceux que je pensais être les plus utiles pour une chasse aux menaces simple, qui sont ceux-ci par exemple, nous allons aux événements de connexion de périphérique, nous pouvons utiliser le mot-clé project euh et puis simplement coller ceux-ci et puis au lieu de retourner toutes les comme 53 colonnes, il retournera juste comme, vous savez, ces six ou peu importe ce que nous avons mis 1 2 3 4 5 6. Oui, juste six. Et cela réduira considérablement notre utilisation de jetons, dont nous parlerons dans la prochaine leçon. Donc, en gros, ce que je veux dire, c'est que tout ce que nous avons à faire, la façon dont cette requête s'exécute, en fait, je vais juste, je vais juste l'exécuter et je vais vous la montrer. Donc, vous pouvez faire cela avec moi. Donc, allez-y et faites une pause ici et nous commencerons le débogage. Et puis vous remarquez que pour le nom de la table, je l'ai défini comme activité Azure, comme je l'ai pré-défini. Donc, nous allons juste passer par-dessus, nous pouvons voir les choses s'assigner ici, les variables, le nom de la table, activité Azure, et puis les champs, c'est un grand dictionnaire, rappelez-vous, donc clé-valeur, clé-valeur, clé-valeur, etc., et puis il y a 1 heure, nous allons créer notre client d'analyse des journaux, vous avez dû utiliser une connexion sur la ligne de commande à un moment donné pour que cela fonctionne. Et puis c'est juste la définition de la fonction. Donc, elle sera construite et puis nous passerons par-dessus. C'est une définition de fonction. euh, la fonction n'a pas été exécutée, mais l'interpréteur a juste reconnu son existence et maintenant c'est là que le code s'exécute réellement pour la première fois, ou plutôt, c'est là que le code commence réellement à s'exécuter. Donc, nous allons appeler la fonction query log analytics et nous allons passer le client d'analyse des journaux, qui est le client. Fermez ceci. Nous allons passer l'ID de l'espace de travail d'analyse des journaux, qui remplacera ceci. Nous allons passer le nom de la table, qui est l'activité Azure, qui sera mise ici. Et puis nous allons obtenir les champs. Donc, nous allons obtenir les champs que nous voulons utiliser. N'est-ce pas ? Donc, rappelez-vous, cette chose de champs, cette variable est en fait un dictionnaire et elle contient les différents champs que nous voulons projeter pour chaque table donnée. Donc, en gros, comment cela fonctionne, si vous vous souvenez de la façon dont vous accédez à une valeur dans un dictionnaire, vous prenez le nom de la variable et vous passez la clé ici. Dans notre cas, la clé est l'activité Azure. Donc, nous utilisons la variable champs et nous passons l'activité Azure pour la clé et cela retournera les champs spécifiquement pour l'activité Azure. Et je vais l'exécuter à nouveau d'une autre manière qui, espérons-le, sera plus claire. Et puis les heures précédentes sont ici. elle sera mise dans l'intervalle de temps en heures. Donc, si je dis étape dans maintenant, cela ira dans la fonction réelle. C'est la fonction et puis maintenant vous pouvez voir comme le client, c'est notre client qui nous permet d'interagir, l'ID de l'espace de travail d'analyse des journaux, le nom de la table, et puis les champs qui ont été extraits du dictionnaire et puis l'intervalle de temps, qui est juste comme devrait être 1 heure et puis maintenant il va créer une variable appelée requête KQL et en fait, c'est littéralement tout ce que c'est, donc il prend le nom de la table comme ceci et puis il projette les champs pertinents comme ceci. Donc, nous allons laisser cela se construire. La requête KQL est construite dans la fonction. Et puis si nous la regardons, c'est un peu étrange à regarder ici, mais si nous l'imprimons ci-dessous, c'est la requête KQL, n'est-ce pas ? Donc, si nous copions ceci juste pour l'exemple, vous n'avez pas à faire cela, mais laissez-moi aller ici et la coller. C'est la requête qui a été créée et c'est ce qui va s'exécuter en fait à l'intérieur de notre, à l'intérieur de Python. Donc, nous allons passer par-dessus. Il va obtenir la réponse et prendre l'élément des tables et puis ou c'est une liste et puis l'élément zéro. Donc, à l'intérieur de la réponse, puis les tables, puis l'élément zéro et il va le stocker dans table result. Donc, il va stocker comme ces choses dans table result. Donc, si nous passons par-dessus maintenant, nous avons une variable appelée table result et nous pouvons voir les choses à l'intérieur ont comme les colonnes, les types de colonnes, le schéma, et puis les lignes. Donc, si nous passons par-dessus, cela est retourné comme c'est là que la fonction a été appelée et puis table results a été retourné à results comme ceci. Donc, nous avons une nouvelle variable appelée results qui contient tous nos résultats de requête. Et nous allons dire si les lignes sont égales à zéro, cela signifie qu'elles sont vides. Donc, quittez simplement le programme. Ce n'est pas le cas. Donc, il saute ici et extrait les colonnes. Extrait les lignes. Donc, maintenant nous avons comme des colonnes, plutôt nous avons des colonnes ici, puis nous avons des lignes ici. Donc, dans le dataframe, il va construire un dataframe à nouveau. Si nous regardons le dataframe, c'est similaire à ce que nous regardions dans la vidéo précédente. Il a justeBasically toutes les choses, mais dans un format différent. Euh, je ne vais pas trop regarder ça. Mais cela convertit en fait le dataframe en une chaîne plate. Donc, si nous regardons à l'intérieur de cet enregistrement, c'est juste une énorme. Oh, ce sera difficile à voir. Voyons si je peux. Oui, si vous passez la souris dessus, vous pouvez voir que c'est juste une énorme chose de tous les enregistrements qui ont été retournés par la requête. C'est essentiellement juste ces choses qui ont été retournées, mais c'est juste dans un format de chaîne énorme. Ensuite, il va imprimer à l'écran comme ceci, ce sera difficile à lire. Peut-être que je peux faire tous les enregistrements et puis le code va se terminer. Donc, euh, en gros, cela [s'éclaircit la gorge] a juste fait la même chose que le code précédent dans la leçon précédente, sauf que c'était plus structuré. Nous avons en fait utilisé une fonction et y avons passé des choses. Donc, je vais en fait rendre cela un peu plus facile à lire. Donc, euh, au lieu de, laissez-moi voir ici, nous pouvons le rendre plus facile. Donc, je vais dire, par exemple, je vais effacer ceci après l'avoir rendu plus facile à lire. Donc, je vais juste en faire un nouveau. Résultats = query log analytics. C'est le nom de la fonction. Et puis le premier argument est un client. Donc, je vais faire ce client = log analytics client. Et puis la chose suivante est l'ID de l'espace de travail. Workspace ID. Log analytics workspace ID. C'est un peu plus facile à lire si vous mettez les choses en ligne comme ceci et puis quand vous passez la chose. Si vous l'assignez au nom réel de la variable qui se trouve dans la fonction. Je ne sais pas si j'ai dit cela correctement. C'est juste un peu plus facile à lire et à comprendre car c'est la définition de la fonction. Elle utilise comme client, ID de l'espace de travail, table, champs, intervalle de temps, et cela a plus de sens et c'est plus facile à lire si vous l'écrivez comme ceci. Table, tout cela, table, puis nom de table, qui est ici, nom de table, nom de table, et puis euh champs. Et puis pour donner plus de sens à cela, pour aider, je suppose, pour aider à donner plus de sens, je vais mettre une autre variable ici comme euh champs et colonnes, c'est la même chose, colonnes. Donc, je vais juste appeler ça, d'accord, je vais appeler ça champs, champs que nous voulons inclure, et puis rappelez-vous, nous obtenons ceux-ci en utilisant le dictionnaire de champs. Donc, par exemple, comme champs et puis vous savez, si nous, si nous passons par exemple les événements de connexion de périphérique comme ceci, si nous passons ces champs, événements de connexion de périphérique, cela retournera comme ces choses, n'est-ce pas, mais pour que nous puissions, comme, je suppose, une façon de le faire qui est un peu plus propre juste pour nos intentions et nos objectifs, si nous définissons le nom de la table, donc par exemple, si le nom de la table que nous voulons interroger est événements de connexion de périphérique. Nous pouvons simplement utiliser ceci et puis nous pouvons juste, au lieu de mettre une chaîne codée en dur ici, nous pouvons juste faire ceci car ce sont des événements de connexion de périphérique. Et puis si nous passons le nom de la table, cela extraira les champs que nous voulons spécifiques au nom de la table. Quand nous l'exécuterons, peut-être que cela aura plus de sens, mais je veux juste vous montrer une autre façon de faire les choses. Donc, champs = ceci et puis la dernière chose était euh intervalle de temps en heures = heures précédentes. Donc, et cela a tendance à être un peu plus facile à lire que ceci. Donc, je vais juste supprimer ceci. Donc, cette fois, nous allons en fait interroger euh au lieu des événements de connexion de périphérique, je vais interroger le CL d'analyse réseau Azure. C'est comme le pare-feu essentiellement. Donc, je vais juste mettre ceci ici et puis je vais déboguer ceci. Et au fait, c'est assez difficile, la fonction est un peu difficile à comprendre pour les gens. Donc, je recommande juste d'utiliser GPT pour vous aider à comprendre ce qui se passe. Et puis n'ayez absolument pas peur de poster sur le forum et de poser des questions si vous avez besoin d'aide pour comprendre quelque chose, car cela vaut la peine d'apprendre à comprendre et cela vaut la peine de donner un sens à cela et d'être capable de l'augmenter et de le modifier pour faire des choses comme vous le souhaitez. Donc, cela vaut la peine de comprendre et ne vous découragez pas si vous trouvez que c'est trop difficile. Donc, nous allons passer par-dessus ceci. Va assigner le nom de la table d'analyse des journaux, obtenir les champs. Ce sont juste les variables qui sont construites et les heures précédentes. Puis obtenir la définition de la fonction client. Et puis maintenant, c'est là que nous définissons quels champs nous voulons inclure dans notre requête. Et si vous vous souvenez, c'est un dictionnaire. Et puis nous allons extraire la valeur Azure Network Analytics CL de la clé. Donc, cette clé, nous allons extraire ceux-ci. C'est ce que fait ceci. Nous allons passer par-dessus et nous voyons les champs que nous voulons interroger ici à gauche. Ce sont tous les champs pour la table Azure Network Analytics, alias la table du groupe de sécurité réseau, alias le pare-feu. Et puis maintenant je vais entrer dans cette fonction. La requête KQL est en cours de construction, elle va être imprimée, ce qui est ici. C'est la chose que nous interrogeons. Donc, si nous, si nous copions ceci, nous pouvons le copier à nouveau, juste pour essayer de connecter ce qui se passe pour vous et nous le collons ici. C'est comme, c'est ce qui va sortir, le type de flux, l'IP publique, le port de destination, etc. C'est comme essentiellement le trafic du pare-feu. Donc, passez par-dessus ceci et laissez la requête s'exécuter. Elle va extraire les tables et puis retourner le résultat. Et puis le résultat va être retourné ici. Cette variable results, par-dessus ceci. Extrait les colonnes. Extrait les lignes. Construit le dataframe. Crée une chaîne géante d'enregistrements qui est ici. Nous allons l'utiliser pour la chasse aux menaces à un moment donné, nous allons imprimer ceux-ci et puis cela se terminera. Et c'est à peu près tout, c'est à peu près tout. Et je veux juste dire, euh, le but de cette leçon est juste de montrer que vous pouvez avoir une fonction et que vous pouvez manuellement créer une requête KQL structurée à l'intérieur en fonction de la table et des champs que vous voulez rechercher. Bien sûr, vous pouvez faire des choses plus compliquées. Euh, nous pouvons dire, par exemple, euh, type de flux, nous pouvons dire, par exemple, où le type de flux est égal à flux malveillant. Donc, si nous voulons seulement retourner comme le trafic malveillant. Donc, nous pourrions, nous pourrions prendre ceci, n'est-ce pas, puis le copier et puis aller au code et puis juste après le nom de la table, nous pouvons faire quelque chose comme ceci, comme ceci. Et puis cela fonctionnerait aussi. Euh, je vais exécuter ceci, n'est-ce pas ? Je vais juste, oui, je vais juste commencer à le déboguer, mais je vais juste le casser peut-être à la toute fin. Je vais me débarrasser de ces points d'arrêt. Je vais juste continuer ceci. Vous pouvez voir la requête ici et vous voyez euh toutes les choses qui ont été imprimées. C'est des enregistrements, beaucoup et vous remarquez qu'il n'a que le flux malveillant comme type de flux maintenant et c'est très cool et bien. Donc, nous allons terminer ceci, mais que se passe-t-il par exemple, vous savez, si nous ne voulons pas, au lieu d'interroger le pare-feu, peut-être que nous voulons interroger la table des journaux de connexion, par exemple, et nous collons ceci ici. Donc, si vous exécutez ceci, euh, voyez, je vais le casser ici juste avant que la requête ne se produise. Donc, nous voyons que notre requête a été imprimée ici. Donc, je vais prendre ceci, le copier et je vais le coller ici. C'est notre nouvelle requête. Et vous voyez, vous pourriez remarquer qu'il y a déjà un problème avec elle. Oh, donc si nous exécutons ceci, c'est comme si l'opérateur où échouait à résoudre la colonne ou l'expression scalaire, le nom sera comme type de flux s. Cela signifie juste que la table des journaux de connexion n'a pas de colonne de type de flux. Donc, cela ne fonctionnera pas, n'est-ce pas ? Euh, oui, c'est à peu près tout. Et pour prouver cela, vous pouvez dire journaux de connexion, obtenir le schéma. Désolé, mon nez est bouché ou quelque chose comme ça. Je ne sais pas ce qui se passe. Ensuite, pouvez-vous juste accélérer ceci, comme couper ceci ou Miho, qui que ce soit qui édite ceci. Et puis vous, si vous regardez à travers, c'est tout le schéma pour les journaux de connexion. Vous remarquerez qu'il n'y a pas de euh, il n'y a pas de flux malveillant en ordre alphabétique, n'est-ce pas ? Pas de flux malveillant. Donc, si nous revenons au code, cette chose est sur le point d'exécuter cette requête invalide. Donc, nous allons juste voir ce qui se passe, vous savez. Il dit qu'une erreur s'est produite et la même chose, échec de la réponse, échec de la résolution de la colonne type de flux s. C'est juste quelque chose auquel vous devez penser, cela, je ne veux pas dire que c'est facile, mais c'est possible de formuler la fonction de telle sorte qu'elle empêche ce genre de choses de se produire. Euh, mais je voulais juste, je suppose, vous le montrer. Et nous allons traiter cela à l'avenir, lorsque nous construirons notre agent, car nous aurons une fonction qui construira la requête KQL pour nous. Mais nous devons tenir compte des différentes colonnes dans différentes tables, si cela a du sens. Donc, je vais juste supprimer ceci pour l'instant. Et ce que je vous recommande, c'est de prendre note que nous n'avons utilisé que, vous savez, quatre tables ici. Il y a une tonne d'autres tables. Donc, je pourrais recommander, juste pour que vous puissiez construire une compréhension, de choisir une autre table en dehors de celles-ci. Donc, par exemple, si vous allez à l'analyse des journaux, allez dans tables, vous pouvez aller à sentinel, puis peut-être aller à événements de fichiers de périphérique, par exemple. C'est une table, n'est-ce pas, événements de fichiers de périphérique. Donc, vous pourriez, vous pourriez aller à, vous savez, euh, vous pourriez l'ajouter ici, événements de fichiers de périphérique, et puis vous pourriez vouloir regarder le schéma. Donc, par exemple, événements de fichiers de périphérique et juste prendre 10 pour l'exemple et juste voir ce qu'il y a et voir quelles colonnes ou champs vous sont utiles, comme utiles. Vous pouvez dire, temps généré, peut-être que c'est assez utile parce que vous voulez savoir quand quelque chose s'est produit. Qu'est-ce que c'est ? Projeter le temps généré. Le type d'action est probablement utile. Euh, champs supplémentaires, peut-être. Je ne sais pas. Le nom de l'appareil est utile. Peut-être que le nom du fichier est utile car c'est une table d'événements de fichiers. Euh, peut-être le chemin du dossier. Vous pourriez vous en soucier. Au fait, c'est comme cyber bunny. Ce sont juste des machines virtuelles littérales de membres de la cyber-plage, des fichiers que nous regardons ici. C'est drôle. Quoi qu'il en soit, peut-être que le processus initiateur, la ligne de commande est utile, par exemple, la ligne de commande, par exemple. Donc, je prendrais juste ceux-ci pour l'exemple, je les copiais et puis je créerais une autre virgule, puis une autre entrée de dictionnaire, une autre paire clé-valeur. Donc, événements de fichiers de périphérique, puis les clés, ou plutôt les colonnes qui m'intéressaient, comme ceci. Et puis maintenant, quand nous exécuterons ce code, il interrogera cette table, puis il recherchera les champs que nous voulons retourner pour cette table, et il les projettera et il nous les montrera ici. Donc, si je l'exécute à nouveau, par exemple, il a déjà construit la requête. Il l'a imprimée. C'est la requête qui va se produire. Donc, si nous copions ceci pour l'exemple, et en fait, la requête retourne pour la dernière heure, et elle va montrer quelque chose comme ceci, probablement montrer ceux-ci. Donc, si nous revenons et que nous laissons cela s'exécuter, et vous pouvez voir, euh, cela a probablement imprimé la même chose ou quelque chose de très, très similaire. Euh, mais je n'ai pas pris 10. Il a juste, je pense qu'il a imprimé un tas d'entre eux. Mais j'espère que cela a du sens et que vous avez une idée. Il y a une tonne de tables. Je veux juste vous le faire comprendre. Et il se trouve que j'ai juste, vous savez, choisi ces quatre plus le cinquième que j'ai ajouté à la fin. Mais oui, faites-moi savoir si vous avez des questions à ce sujet. Euh, je sais que cela devient un peu difficile, mais c'est, encore une fois, je pense qu'il est vraiment important d'apprendre ce qui se passe et de l'apprendre en général. C'est juste vraiment utile si vous êtes capable de comprendre ce type de chose. Mais oui, nous vous verrons dans la prochaine leçon, je crois, où nous commencerons à parler de jetons et d'optimisation. Donc, nous vous verrons là-bas. Bienvenue. Dans cette leçon, je vais parler des jetons et des coûts, puis nous ferons une démo pour montrer les différents coûts des différents modèles en termes de jetons. Mais j'espère que nous pourrons en avoir une idée. Euh, c'est vraiment, vraiment important car lorsque vous créez un agent ou que vous traitez avec l'IA en général ou des modèles de langage étendus, il est bon de comprendre que, vous savez, vous devriez optimiser votre invite, surtout si vous les utilisez beaucoup, il est bon d'optimiser vos invites autant que possible et d'optimiser le modèle car cela peut faire une énorme différence en termes de coûts. Donc, en gros, ne pensez pas que je suis radin pour faire cela. C'était juste pratique. Euh, en gros, les jetons. Euh, j'ai juste utilisé GPT pour faire une leçon rapide, mais qu'est-ce que les jetons ? Quand vous utilisez ChatGPT, tout votre texte, comme les entrées et les réponses du modèle, comme quand vous dites bonjour et qu'il dit bonjour en retour, il est décomposé en jetons plutôt qu'en caractères. Et un jeton, comme un seul jeton, représente environ quatre caractères dans la langue anglaise. Euh, je ne connais pas les détails techniques du calcul des jetons. Euh, je ne suis pas sûr que certaines personnes le fassent évidemment, mais nous avons des bibliothèques et des choses pour aider à calculer combien de jetons quelque chose représente, ce que vous verrez dans la démo à venir. Mais chaque fois que vous envoyez quelque chose à GPT, comme l'invite, comme vous tapez quelque chose et que vous l'envoyez. Et puis chaque fois que vous recevez une réponse, cela compte. Ce sont tous des jetons, n'est-ce pas ? Il y a des jetons d'invite et puis des jetons de réponse. Et je crois que tout cela, quand vous envoyez quelque chose et qu'il renvoie quelque chose, je crois que tout cela s'appelle la fenêtre, n'est-ce pas ? Donc, par exemple, si vous dites bonjour, c'est comme environ six jetons, puis la réponse, c'est environ sept jetons, et puis vous pouvez dire que cette conversation a utilisé 13 jetons. Et pourquoi c'est important, c'est comme ce que nous venons de dire, plus l'invite est longue, plus les jetons sont consommés, et plus les jetons sont consommés, plus la conversation coûte essentiellement. Donc, nous allons utiliser ces quatre modèles particuliers dans la démo à venir, très rapidement, et vous pourrez voir la différence entre eux. J'ai mis un lien pour cela dans le code source réel pour cette leçon, donc vous pouvez juste le récupérer là-bas ou vous pouvez juste le taper. Mais en gros, ChatGPT ou OpenAI spécifiquement a une tonne de modèles différents. Il y a juste beaucoup de modèles différents et les coûts pour eux sont différents et ils sont meilleurs à différentes choses. Donc, par exemple, vous pouvez voir comme euh Oh, c'est intéressant. Ils ont l'intelligence au lieu du raisonnement pour celui-ci. C'est intéressant. Mais vous pouvez voir comme GPT 4.1 est assez intelligent par rapport à GPT 4.1 Nano. Et puis G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G Gג

גגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגגג!

Je m'attendais à voir des lignes ou quelque chose comme ça. Colonnes temps généré. Je suppose qu'il y a des lignes quelque part. Oh, c'est ici. Non, dataframe KQ query. Je me demande pourquoi c'est là. C'est tellement intéressant. Oh. Oh, c'est le euh je pense que c'est ça. Valeurs underscore peut-être. Taille 380. C'est intéressant. Je ne sais pas pourquoi il n'y en a que autant de longues quand j'avais comme 100 enregistrements. Mais bon, vous avez une idée. Le but principal était juste de vous montrer que nous pouvons faire des requêtes KQL avec Python, puis nous pouvons retourner les données et nous pouvons les observer et faire quelque chose avec. Donc, je vais juste regarder dans une autre table au lieu de device lo on events. Je veux juste vous montrer que vous pouvez regarder dans d'autres tables aussi. Et il y a comme une tonne de tables. Donc, par exemple, laissez-moi regarder ce que nous devrions regarder, analyse du comportement des utilisateurs. Analyse des pairs d'utilisateurs. Je veux juste voir ce qu'il y a ici. Par exemple, analyse du comportement, prendre 50. Temps de traitement. Oh, c'est intéressant. Oh, d'accord. Connexion échouée. Oh, c'est tellement intéressant. Euh, d'accord. Donc, nous pouvons prendre ceci juste pour l'exemple. Instance, je veux faire deux choses de plus dans cette leçon. Donc, je vais copier ceci. Je veux juste interroger une autre table juste pour avoir une idée que c'est possible. Donc, je vais coller la requête ici et je vais juste la relancer et je vais juste la laisser se déverser sur l'écran pour que nous puissions l'observer et nous allons l'imprimer. Et puis nous voyons qu'elle s'imprime. Euh, il semble qu'elle ait tronqué comme le euh elle a résumé les lignes aussi car il y en a trop. Ils ont mis comme trois points parce que nous n'avons rien projeté. Donc, par exemple, c'est la requête ici. Donc, si nous voulons projeter seulement certains journaux, nous pouvons ou certaines lignes, nous pouvons dire comme euh projeter le temps généré, euh peut-être le type d'activité, le type d'action, le nom d'utilisateur. Ce sont comme les vrais noms d'utilisateur de la cyber-plage. Oh, peut-être que nous devrions utiliser le nom d'utilisateur principal et ensuite la source de l'événement, l'adresse IP source. C'est comme la vraie adresse IP du membre de la cyber-plage. Et c'est pourquoi euh je n'en ai pas parlé dans ce cours, mais euh si vous êtes membre de la cyber-plage, votre nom d'utilisateur principal ou votre nom d'utilisateur avec lequel vous vous connectez à la cyber-plage est un peu fou euh c'est comme une grille. C'est ce nombre fou parce que nous pouvons voir les journaux dans la cyber-plage et si cela dit comme, vous savez, Maggie aimerait comme Maggie Wilcox à l'intérieur de, vous savez, San Jose, peu importe, et l'adresse IP, cela complètement euh la personne, vous savez, euh donc c'est, vous savez, c'est pourquoi nous avons fait cela et si votre organisation peut voir des choses similaires aussi, donc vous savez, gardez cela à l'esprit, je suppose, et puis l'emplacement de l'adresse IP source et peut-être que c'est suffisant. Donc, nous allons exécuter cette requête juste pour voir à quoi elle ressemble. Le nom d'utilisateur principal est vide. Donc, je vais juste utiliser le nom d'utilisateur, je suppose. Et puis peut-être que je dirai comme où le type d'action ou je dirai où je vous donne juste une leçon KQL euh je suppose que nous pouvons dire où n'est pas vide le type d'action et puis et n'est pas vide euh quelle est l'autre chose que j'ai dite, le nom d'utilisateur. Donc, nous allons exécuter ceci. Et maintenant nous voyons, nous voyons une bonne quantité de journaux. Euh, peu importe. Donc, nous allons copier ceci. Je fais juste un exercice, n'est-ce pas ? Et nous allons coller ceci ici. Et je vais juste dire comme prendre 25 ou quelque chose comme ça. Et nous allons juste exécuter ceci à nouveau. Et cela va s'imprimer. Et puis nous voyons qu'il imprime le dataframe. Euh, a comme l'heure à laquelle c'est arrivé, l'activité, l'adresse IP. [s'éclaircit la gorge] C'est probablement le qu'est-ce que c'est ? Oh, l'emplacement. Il semble qu'il ait tronqué ou résumé et supprimé certaines des lignes aussi. Il y a probablement une raison pour laquelle il fait cela. Comme il veut imprimer très joliment et qu'il y a trop de lignes ou quelque chose comme ça. Je ne sais pas. Mais si nous voulons et nous le ferons à l'avenir, nous pouvons programmatiquement y accéder et en fait extraire, le transformer en une chaîne brute, puis nous l'enverrons à l'API GPT et ferons de la chasse aux menaces avec et tout le reste. Donc, le but de l'extraction de ces journaux est que nous en avons besoin pour, vous savez, faire de la chasse aux menaces et envoyer au modèle et tout ça. Donc, je voulais juste avoir cette leçon pour montrer qu'il est en fait possible d'interroger l'espace de travail d'analyse des journaux avec Python. Et j'espère que cela a du sens. Euh, si vous êtes bloqué ou si vous avez des questions ou quoi que ce soit, euh, vous savez, allez absolument sur le forum de la cyber-plage et publiez et taguez-moi et puis euh, vous savez, faites-nous savoir ce qui ne va pas. Sinon, nous vous verrons dans la prochaine leçon. Bienvenue. Euh, bienvenue dans la prochaine leçon. U celle-ci, nous allons en fait interroger davantage l'espace de travail d'analyse des journaux, mais nous allons le faire d'une manière plus structurée, en utilisant en fait une fonction et en choisissant les données que nous sélectionnons de la table d'une manière plus organisée, et j'espère que cela aura du sens au fur et à mesure. Mais euh, cette leçon sera vraiment importante car nous allons nous en baser sur elle. Nous allons nous en baser sur elle dans la prochaine leçon. Euh, en gros, nous allons travailler à optimiser notre requête car, en fin de compte, nous allons construire un agent d'analyste de SOC IA, comme un agent qui fait de la chasse aux menaces et en gros, plus nous envoyons de journaux à ChatGPT, plus cela coûte. Donc, nous voulons vraiment minimiser la quantité de journaux envoyés à ChatGPT. Donc, avec ceci, nous allons nous en baser un peu dessus et tout cela aura beaucoup de sens dans la prochaine leçon. Donc, je ne veux pas trop en parler, mais nous allons juste passer à celle-ci et je vais expliquer ce que tout cela est. Donc, en gros, euh, il y a beaucoup de tables différentes que nous pouvons interroger et rechercher des journaux dans Log Analytics. Donc, par exemple, si vous vous connectez à Azure, vous savez, portail. Connectez-vous avec votre nom d'utilisateur de la cyber-plage et allez à l'analyse des journaux. C'est notre dépôt de journaux. Prenez celui de la cyber-plage. Ensuite, allez dans journaux et fermez ceci. Et si cela dit mode simple, changez-le en mode KQL. Et puis faites du mode KQL la valeur par défaut. Je ne le fais pas. Et puis vous verrez qu'il y a des tables ici et qu'il y a beaucoup de tables différentes. Donc, différents types de données sont enregistrés dans différentes tables dans l'environnement. Donc, par exemple, euh, activité Azure, eh bien, activité Azure, c'est comme si vous créez une machine virtuelle ou créez n'importe quel type d'objet dans le portail Azure, cela sera enregistré dans l'activité Azure et les journaux de connexion, c'est comme euh quand vous, si quelqu'un se connecte à Azure, comme un membre de la cyber-plage ou quelque chose comme ça, cela enregistrera tout, comme si c'était un succès ou un échec, d'où ils venaient, etc. Il y a juste une tonne de journaux ici, n'est-ce pas ? Mais pour cet exercice, euh, je vais juste travailler avec ces journaux en particulier ou ces tables comme ceci, comme les événements de connexion de périphérique. Euh, c'est comme si quelqu'un essayait de se connecter à une machine virtuelle. C'est comme le groupe de sécurité réseau de la cyber-plage, alias le pare-feu, et ensuite l'activité Azure, juste des choses dans le portail, la création de machines virtuelles, la suppression de choses, et ensuite les journaux de connexion chaque fois que quelqu'un se connecte à Azure. Donc, c'est à peu près ce que sont ces choses. Et puis cette chose ici. Euh, c'est un dictionnaire appelé champs et puis par exemple, c'est le nom de la table et puis ce sont les champs que euh je veux interroger dans la table. Donc, par exemple, euh, et j'ai juste choisi ceux-ci à la main. Donc, je vais vous montrer ce que je veux dire. Donc, si je vais à, si je copie les événements de connexion de périphérique, puis que je vais à l'analyse des journaux et que je colle simplement les événements de connexion de périphérique, il y a comme, il y a trop de champs. Ce sont comme les colonnes ou les champs. Il y en a trop. Il y en a beaucoup et nous n'avons pas besoin de beaucoup d'entre eux, n'est-ce pas ? Et si nous collectons tous ceux-ci, cela crée juste beaucoup de jetons inutiles car nous n'avons pas besoin de collecter l'ID du locataire à chaque fois et d'envoyer une tonne d'ID de locataire à ChatGPT car cela n'aide pas à notre utilisation, je veux dire, cela pourrait aider, mais cela n'aide pas dans notre cas d'utilisation, la plupart du temps, cela n'aidera pas à trouver des menaces ou quoi que ce soit. Donc, vous pouvez aussi dire quelque chose comme euh obtenir le schéma comme ça et puis l'exécuter et puis vous pouvez voir les différents champs, alias les colonnes et vous voyez qu'il y en a beaucoup, il y en a comme 53, vous n'avez pas besoin de tous ceux-ci pour faire de la chasse aux menaces, donc j'ai juste choisi à la main ceux que je pensais être les plus utiles pour une chasse aux menaces simple, qui sont ceux-ci par exemple, nous allons aux événements de connexion de périphérique, nous pouvons utiliser le mot-clé project euh et puis simplement coller ceux-ci et puis au lieu de retourner toutes les comme 53 colonnes, il retournera juste comme, vous savez, ces six ou peu importe ce que nous avons mis 1 2 3 4 5 6. Oui, juste six. Et cela réduira considérablement notre utilisation de jetons, dont nous parlerons dans la prochaine leçon. Donc, en gros, ce que je veux dire, c'est que tout ce que nous avons à faire, la façon dont cette requête s'exécute, en fait, je vais juste, je vais juste l'exécuter et je vais vous la montrer. Donc, vous pouvez faire cela avec moi. Donc, allez-y et faites une pause ici et nous commencerons le débogage. Et puis vous remarquez que pour le nom de la table, je l'ai défini comme activité Azure, comme je l'ai pré-défini. Donc, nous allons juste passer par-dessus, nous pouvons voir les choses s'assigner ici, les variables, le nom de la table, activité Azure, et puis les champs, c'est un grand dictionnaire, rappelez-vous, donc clé-valeur, clé-valeur, clé-valeur, etc., et puis il y a 1 heure, nous allons créer notre client d'analyse des journaux, vous avez dû utiliser une connexion sur la ligne de commande à un moment donné pour que cela fonctionne. Et puis c'est juste la définition de la fonction. Donc, elle sera construite et puis nous passerons par-dessus. C'est une définition de fonction. euh, la fonction n'a pas été exécutée, mais l'interpréteur a juste reconnu son existence et maintenant c'est là que le code s'exécute réellement pour la première fois, ou plutôt, c'est là que le code commence réellement à s'exécuter. Donc, nous allons appeler la fonction query log analytics et nous allons passer le client d'analyse des journaux, qui est le client. Fermez ceci. Nous allons passer l'ID de l'espace de travail d'analyse des journaux, qui remplacera ceci. Nous allons passer le nom de la table, qui est l'activité Azure, qui sera mise ici. Et puis nous allons obtenir les champs. Donc, nous allons obtenir les champs que nous voulons utiliser. N'est-ce pas ? Donc, rappelez-vous, cette chose de champs, cette variable est en fait un dictionnaire et elle contient les différents champs que nous voulons projeter pour chaque table donnée. Donc, en gros, comment cela fonctionne, si vous vous souvenez de la façon dont vous accédez à une valeur dans un dictionnaire, vous prenez le nom de la variable et vous passez la clé ici. Dans notre cas, la clé est l'activité Azure. Donc, nous utilisons la variable champs et nous passons l'activité Azure pour la clé et cela retournera les champs spécifiquement pour l'activité Azure. Et je vais l'exécuter à nouveau d'une autre manière qui, espérons-le, sera plus claire. Et puis les heures précédentes sont ici. elle sera mise dans l'intervalle de temps en heures. Donc, si je dis étape dans maintenant, cela ira dans la fonction réelle. C'est la fonction et puis maintenant vous pouvez voir comme le client, c'est notre client qui nous permet d'interagir, l'ID de l'espace de travail d'analyse des journaux, le nom de la table, et puis les champs qui ont été extraits du dictionnaire et puis l'intervalle de temps, qui est juste comme devrait être 1 heure et puis maintenant il va créer une variable appelée requête KQL et en fait, c'est littéralement tout ce que c'est, donc il prend le nom de la table comme ceci et puis il projette les champs pertinents comme ceci. Donc, nous allons laisser cela se construire. La requête KQL est construite dans la fonction. Et puis si nous la regardons, c'est un peu étrange à regarder ici, mais si nous l'imprimons ci-dessous, c'est la requête KQL, n'est-ce pas ? Donc, si nous copions ceci juste pour l'exemple, vous n'avez pas à faire cela, mais laissez-moi aller ici et la coller. C'est la requête qui a été créée et c'est ce qui va s'exécuter en fait à l'intérieur de notre, à l'intérieur de Python. Donc, nous allons passer par-dessus. Il va obtenir la réponse et prendre l'élément des tables et puis ou c'est une liste et puis l'élément zéro. Donc, à l'intérieur de la réponse, puis les tables, puis l'élément zéro et il va le stocker dans table result. Donc, il va stocker comme ces choses dans table result. Donc, si nous passons par-dessus maintenant, nous avons une variable appelée table result et nous pouvons voir les choses à l'intérieur ont comme les colonnes, les types de colonnes, le schéma, et puis les lignes. Donc, si nous passons par-dessus, cela est retourné comme c'est là que la fonction a été appelée et puis table results a été retourné à results comme ceci. Donc, nous avons une nouvelle variable appelée results qui contient tous nos résultats de requête. Et nous allons dire si les lignes sont égales à zéro, cela signifie qu'elles sont vides. Donc, quittez simplement le programme. Ce n'est pas le cas. Donc, il saute ici et extrait les colonnes. Extrait les lignes. Donc, maintenant nous avons comme des colonnes, plutôt nous avons des colonnes ici, puis nous avons des lignes ici. Donc, dans le dataframe, il va construire un dataframe à nouveau. Si nous regardons le dataframe, c'est similaire à ce que nous regardions dans la vidéo précédente. Il a justeBasically toutes les choses, mais dans un format différent. Euh, je ne vais pas trop regarder ça. Mais cela convertit en fait le dataframe en une chaîne plate. Donc, si nous regardons à l'intérieur de cet enregistrement, c'est juste une énorme. Oh, ce sera difficile à voir. Voyons si je peux. Oui, si vous passez la souris dessus, vous pouvez voir que c'est juste une énorme chose de tous les enregistrements qui ont été retournés par la requête. C'est essentiellement juste ces choses qui ont été retournées, mais c'est juste dans un format de chaîne énorme. Ensuite, il va imprimer à l'écran comme ceci, ce sera difficile à lire. Peut-être que je peux faire tous les enregistrements et puis le code va se terminer. Donc, euh, en gros, cela [s'éclaircit la gorge] a juste fait la même chose que le code précédent dans la leçon précédente, sauf que c'était plus structuré. Nous avons en fait utilisé une fonction et y avons passé des choses. Donc, je vais en fait rendre cela un peu plus facile à lire. Donc, euh, au lieu de, laissez-moi voir ici, nous pouvons le rendre plus facile. Donc, je vais dire, par exemple, je vais effacer ceci après l'avoir rendu plus facile à lire. Donc, je vais juste en faire un nouveau. Résultats = query log analytics. C'est le nom de la fonction. Et puis le premier argument est un client. Donc, je vais faire ce client = log analytics client. Et puis la chose suivante est l'ID de l'espace de travail. Workspace ID. Log analytics workspace ID. C'est un peu plus facile à lire si vous mettez les choses en ligne comme ceci et puis quand vous passez la chose. Si vous l'assignez au nom réel de la variable qui se trouve dans la fonction. Je ne sais pas si j'ai dit cela correctement. C'est juste un peu plus facile à lire et à comprendre car c'est la définition de la fonction. Elle utilise comme client, ID de l'espace de travail, table, champs, intervalle de temps, et cela a plus de sens et c'est plus facile à lire si vous l'écrivez comme ceci. Table, tout cela, table, puis nom de table, qui est ici, nom de table, nom de table, et puis euh champs. Et puis pour donner plus de sens à cela, pour aider, je suppose, pour aider à donner plus de sens, je vais mettre une autre variable ici comme euh champs et colonnes, c'est la même chose, colonnes. Donc, je vais juste appeler ça, d'accord, je vais appeler ça champs, champs que nous voulons inclure, et puis rappelez-vous, nous obtenons ceux-ci en utilisant le dictionnaire de champs. Donc, par exemple, comme champs et puis vous savez, si nous, si nous passons par exemple les événements de connexion de périphérique comme ceci, si nous passons ces champs, événements de connexion de périphérique, cela retournera comme ces choses, n'est-ce pas, mais pour que nous puissions, comme, je suppose, une façon de le faire qui est un peu plus propre juste pour nos intentions et nos objectifs, si nous définissons le nom de la table, donc par exemple, si le nom de la table que nous voulons interroger est événements de connexion de périphérique. Nous pouvons simplement utiliser ceci et puis nous pouvons juste, au lieu de mettre une chaîne codée en dur ici, nous pouvons juste faire ceci car ce sont des événements de connexion de périphérique. Et puis si nous passons le nom de la table, cela extraira les champs que nous voulons spécifiques au nom de la table. Quand nous l'exécuterons, peut-être que cela aura plus de sens, mais je veux juste vous montrer une autre façon de faire les choses. Donc, champs = ceci et puis la dernière chose était euh intervalle de temps en heures = heures précédentes. Donc, et cela a tendance à être un peu plus facile à lire que ceci. Donc, je vais juste supprimer ceci. Donc, cette fois, nous allons en fait interroger euh au lieu des événements de connexion de périphérique, je vais interroger le CL d'analyse réseau Azure. C'est comme le pare-feu essentiellement. Donc, je vais juste mettre ceci ici et puis je vais déboguer ceci. Et au fait, c'est assez difficile, la fonction est un peu difficile à comprendre pour les gens. Donc, je recommande juste d'utiliser GPT pour vous aider à comprendre ce qui se passe. Et puis n'ayez absolument pas peur de poster sur le forum et de poser des questions si vous avez besoin d'aide pour comprendre quelque chose, car cela vaut la peine d'apprendre à comprendre et cela vaut la peine de donner un sens à cela et d'être capable de l'augmenter et de le modifier pour faire des choses comme vous le souhaitez. Donc, cela vaut la peine de comprendre et ne vous découragez pas si vous trouvez que c'est trop difficile. Donc, nous allons passer par-dessus ceci. Va assigner le nom de la table d'analyse des journaux, obtenir les champs. Ce sont juste les variables qui sont construites et les heures précédentes. Puis obtenir la définition de la fonction client. Et puis maintenant, c'est là que nous définissons quels champs nous voulons inclure dans notre requête. Et si vous vous souvenez, c'est un dictionnaire. Et puis nous allons extraire la valeur Azure Network Analytics CL de la clé. Donc, cette clé, nous allons extraire ceux-ci. C'est ce que fait ceci. Nous allons passer par-dessus et nous voyons les champs que nous voulons interroger ici à gauche. Ce sont tous les champs pour la table Azure Network Analytics, alias la table du groupe de sécurité réseau, alias le pare-feu. Et puis maintenant je vais entrer dans cette fonction. La requête KQL est en cours de construction, elle va être imprimée, ce qui est ici. C'est la chose que nous interrogeons. Donc, si nous, si nous copions ceci, nous pouvons le copier à nouveau, juste pour essayer de connecter ce qui se passe pour vous et nous le collons ici. C'est comme, c'est ce qui va sortir, le type de flux, l'IP publique, le port de destination, etc. C'est comme essentiellement le trafic du pare-feu. Donc, passez par-dessus ceci et laissez la requête s'exécuter. Elle va extraire les tables et puis retourner le résultat. Et puis le résultat va être retourné ici. Cette variable results, par-dessus ceci. Extrait les colonnes. Extrait les lignes. Construit le dataframe. Crée une chaîne géante d'enregistrements qui est ici. Nous allons l'utiliser pour la chasse aux menaces à un moment donné, nous allons imprimer ceux-ci et puis cela se terminera. Et c'est à peu près tout, c'est à peu près tout. Et je veux juste dire, euh, le but de cette leçon est juste de montrer que vous pouvez avoir une fonction et que vous pouvez manuellement créer une requête KQL structurée à l'intérieur en fonction de la table et des champs que vous voulez rechercher. Bien sûr, vous pouvez faire des choses plus compliquées. Euh, nous pouvons dire, par exemple, euh, type de flux, nous pouvons dire, par exemple, où le type de flux est égal à flux malveillant. Donc, si nous voulons seulement retourner comme le trafic malveillant. Donc, nous pourrions, nous pourrions prendre ceci, n'est-ce pas, puis le copier et puis aller au code et puis juste après le nom de la table, nous pouvons faire quelque chose comme ceci, comme ceci. Et puis cela fonctionnerait aussi. Euh, je vais exécuter ceci, n'est-ce pas ? Je vais juste, oui, je vais juste commencer à le déboguer, mais je vais juste le casser peut-être à la toute fin. Je vais me débarrasser de ces points d'arrêt. Je vais juste continuer ceci. Vous pouvez voir la requête ici et vous voyez euh toutes les choses qui ont été imprimées. C'est des enregistrements, beaucoup et vous remarquez qu'il n'a que le flux malveillant comme type de flux maintenant et c'est très cool et bien. Donc, nous allons terminer ceci, mais que se passe-t-il par exemple, vous savez, si nous ne voulons pas, au lieu d'interroger le pare-feu, peut-être que nous voulons interroger la table des journaux de connexion, par exemple, et nous collons ceci ici. Donc, si vous exécutez ceci, euh, voyez, je vais le casser ici juste avant que la requête ne se produise. Donc, nous voyons que notre requête a été imprimée ici. Donc, je vais prendre ceci, le copier et je vais le coller ici. C'est notre nouvelle requête. Et vous voyez, vous pourriez remarquer qu'il y a déjà un problème avec elle. Oh, donc si nous exécutons ceci, c'est comme si l'opérateur où échouait à résoudre la colonne ou l'expression scalaire, le nom sera comme type de flux s. Cela signifie juste que la table des journaux de connexion n'a pas de colonne de type de flux. Donc, cela ne fonctionnera pas, n'est-ce pas ? Euh, oui, c'est à peu près tout. Et pour prouver cela, vous pouvez dire journaux de connexion, obtenir le schéma. Désolé, mon nez est bouché ou quelque chose comme ça. Je ne sais pas ce qui se passe. Ensuite, pouvez-vous juste accélérer ceci, comme couper ceci ou Miho, qui que ce soit qui édite ceci. Et puis vous, si vous regardez à travers, c'est tout le schéma pour les journaux de connexion. Vous remarquerez qu'il n'y a pas de euh, il n'y a pas de flux malveillant en ordre alphabétique, n'est-ce pas ? Pas de flux malveillant. Donc, si nous revenons au code, cette chose est sur le point d'exécuter cette requête invalide. Donc, nous allons juste voir ce qui se passe, vous savez. Il dit qu'une erreur s'est produite et la même chose, échec de la réponse, échec de la résolution de la colonne type de flux s. C'est juste quelque chose auquel vous devez penser, cela, je ne veux pas dire que c'est facile, mais c'est possible de formuler la fonction de telle sorte qu'elle empêche ce genre de choses de se produire. Euh, mais je voulais juste, je suppose, vous le montrer. Et nous allons traiter cela à l'avenir, lorsque nous construirons notre agent, car nous aurons une fonction qui construira la requête KQL pour nous. Mais nous devons tenir compte des différentes colonnes dans différentes tables, si cela a du sens. Donc, je vais juste supprimer ceci pour l'instant. Et ce que je vous recommande, c'est de prendre note que nous n'avons utilisé que, vous savez, quatre tables ici. Il y a une tonne d'autres tables. Donc, je pourrais recommander, juste pour que vous puissiez construire une compréhension, de choisir une autre table en dehors de celles-ci. Donc, par exemple, si vous allez à l'analyse des journaux, allez dans tables, vous pouvez aller à sentinel, puis peut-être aller à événements de fichiers de périphérique, par exemple. C'est une table, n'est-ce pas, événements de fichiers de périphérique. Donc, vous pourriez, vous pourriez aller à, vous savez, euh, vous pourriez l'ajouter ici, événements de fichiers de périphérique, et puis vous pourriez vouloir regarder le schéma. Donc, par exemple, événements de fichiers de périphérique et juste prendre 10 pour l'exemple et juste voir ce qu'il y a et voir quelles colonnes ou champs vous sont utiles, comme utiles. Vous pouvez dire, temps généré, peut-être que c'est assez utile parce que vous voulez savoir quand quelque chose s'est produit. Qu'est-ce que c'est ? Projeter le temps généré. Le type d'action est probablement utile. Euh, champs supplémentaires, peut-être. Je ne sais pas. Le nom de l'appareil est utile. Peut-être que le nom du fichier est utile car c'est une table d'événements de fichiers. Euh, peut-être le chemin du dossier. Vous pourriez vous en soucier. Au fait, c'est comme cyber bunny. Ce sont juste des machines virtuelles littérales de membres de la cyber-plage, des fichiers que nous regardons ici. C'est drôle. Quoi qu'il en soit, peut-être que le processus initiateur, la ligne de commande est utile, par exemple, la ligne de commande, par exemple. Donc, je prendrais juste ceux-ci pour l'exemple, je les copiais et puis je créerais une autre virgule, puis une autre entrée de dictionnaire, une autre paire clé-valeur. Donc, événements de fichiers de périphérique, puis les clés, ou plutôt les colonnes qui m'intéressaient, comme ceci. Et puis maintenant, quand nous exécuterons ce code, il interrogera cette table, puis il recherchera les champs que nous voulons retourner pour cette table, et il les projettera et il nous les montrera ici. Donc, si je l'exécute à nouveau, par exemple, il a déjà construit la requête. Il l'a imprimée. C'est la requête qui va se produire. Donc, si nous copions ceci pour l'exemple, et en fait, la requête retourne pour la dernière heure, et elle va montrer quelque chose comme ceci, probablement montrer ceux-ci. Donc, si nous revenons et que nous laissons cela s'exécuter, et vous pouvez voir, euh, cela a probablement imprimé la même chose ou quelque chose de très, très similaire. Euh, mais je n'ai pas pris 10. Il a juste, je pense qu'il a imprimé un tas d'entre eux. Mais j'espère que cela a du sens et que vous avez une idée. Il y a une tonne de tables. Je veux juste vous le faire comprendre. Et il se trouve que j'ai juste, vous savez, choisi ces quatre plus le cinquième que j'ai ajouté à la fin. Mais oui, faites-moi savoir si vous avez des questions à ce sujet. Euh, je sais que cela devient un peu difficile, mais c'est, encore une fois, je pense qu'il est vraiment important d'apprendre ce qui se passe et de l'apprendre en général. C'est juste vraiment utile si vous êtes capable de comprendre ce type de chose. Mais oui, nous vous verrons dans la prochaine leçon, je crois, où nous commencerons à parler de jetons et d'optimisation. Donc, nous vous verrons là-bas. Bienvenue. Dans cette leçon, je vais parler des jetons et des coûts, puis nous ferons une démo pour montrer les différents coûts des différents modèles en termes de jetons. Mais j'espère que nous pourrons en avoir une idée. Euh, c'est vraiment, vraiment important car lorsque vous créez un agent ou que vous traitez avec l'IA en général ou des modèles de langage étendus, il est bon de comprendre que, vous savez, vous devriez optimiser votre invite, surtout si vous les utilisez beaucoup, il est bon d'optimiser vos invites autant que possible et d'optimiser le modèle car cela peut faire une énorme différence en termes de coûts. Donc, en gros, ne pensez pas que je suis radin pour faire cela. C'était juste pratique. Euh, en gros, les jetons. Euh, j'ai juste utilisé GPT pour faire une leçon rapide, mais qu'est-ce que les jetons ? Quand vous utilisez ChatGPT, tout votre texte, comme les entrées et les réponses du modèle, comme quand vous dites bonjour et qu'il dit bonjour en retour, il est décomposé en jetons plutôt qu'en caractères. Et un jeton, comme un seul jeton, représente environ quatre caractères dans la langue anglaise. Euh, je ne connais pas les détails techniques du calcul des jetons. Euh, je ne suis pas sûr que certaines personnes le fassent évidemment, mais nous avons des bibliothèques et des choses pour aider à calculer combien de jetons quelque chose représente, ce que vous verrez dans la démo à venir. Mais chaque fois que vous envoyez quelque chose à GPT, comme l'invite, comme vous tapez quelque chose et que vous l'envoyez. Et puis chaque fois que vous recevez une réponse, cela compte. Ce sont tous des jetons, n'est-ce pas ? Il y a des jetons d'invite et puis des jetons de réponse. Et je crois que tout cela, quand vous envoyez quelque chose et qu'il renvoie quelque chose, je crois que tout cela s'appelle la fenêtre, n'est-ce pas ? Donc, par exemple, si vous dites bonjour, c'est comme environ six jetons, puis la réponse, c'est environ sept jetons, et puis vous pouvez dire que cette conversation a utilisé 13 jetons. Et pourquoi c'est important, c'est comme ce que nous venons de dire, plus l'invite est longue, plus les jetons sont consommés, et plus les jetons sont consommés, plus la conversation coûte essentiellement. Donc, nous allons utiliser ces quatre modèles particuliers dans la démo à venir, très rapidement, et vous pourrez voir la différence entre eux. J'ai mis un lien pour cela dans le code source réel pour cette leçon, donc vous pouvez juste le récupérer là-bas ou vous pouvez juste le taper. Mais en gros, ChatGPT ou OpenAI spécifiquement a une tonne de modèles différents. Il y a juste beaucoup de modèles différents et les coûts pour eux sont différents et ils sont meilleurs à différentes choses. Donc, par exemple, vous pouvez voir comme euh Oh, c'est intéressant. Ils ont l'intelligence au lieu du raisonnement pour celui-ci. C'est intéressant. Mais vous pouvez voir comme GPT 4.1 est assez intelligent par rapport à GPT 4.1 Nano. Et puis G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G

Le temps car nous pouvons limiter manuellement, par exemple, la quantité de réponse autorisée pour GPT. Donc, par exemple, j'ai créé cette variable ici appelée "max output tokens" et je l'ai simplement définie sur 5 000. Donc, si je veux dire, par exemple, à GPT, tu ne peux pas répondre avec plus de 5 000 tokens. Nous pouvons le faire. Pour ce faire, euh, je vais changer ceci car ici, c'est ici que nous avons estimé, par exemple, le nombre maximum de tokens utilisés dans la réponse et nous l'avons fait en nous basant sur le modèle que nous utilisions. Par exemple, GPT4.1 nano, vous savez, a euh GPT4.1 nano a une réponse de sortie maximale de, par exemple, 32 000 tokens. Mais si nous ne voulons pas faire cela, par exemple, nous pouvons le faire, nous pouvons en fait commenter cela comme ceci. Et ensuite, nous pouvons définir manuellement la sortie maximale à 5 000, soit 5 000. Et ensuite, là où cela est utilisé, euh, cela est utilisé pour calculer le coût du chat ici. Donc, au lieu de 32 000, c'est maintenant 5 000. Et cela est également utilisé, euh, lorsque nous envoyons réellement le chat à GPT. C'est donc la fonction qui envoie le chat à GPT. Et il y a en fait un paramètre que nous pouvons mettre "max completion tokens". Et nous pouvons le définir sur un nombre, par exemple, de 5 000. Donc, si nous ne voulons pas qu'il utilise plus de 5 000 tokens dans la complétion, nous pouvons le faire. Donc, je vais exécuter ce code. Ce sera la même chose, le même modèle, la même invite, comme les mêmes journaux que nous allons analyser, mais nous allons limiter la réponse que GPT peut produire. Et ensuite, en retour, cela modifiera l'estimation de son coût. Donc, cela devrait être plus proche de la réalité. Et je suis désolé si c'est confus. Je sais que ce n'est pas facile, mais juste, vous savez, faisons de notre mieux. Donc, nous définissons cela. Nous avons choisi notre modèle 4.1 nano. Nous allons passer en revue les fonctions. Construire le client API. Construire l'invite. Construire le message utilisateur. Estimer le nombre de tokens. Définir le nombre maximum de tokens utilisés dans la réponse à 5 000. Obtenir le coût par million. Estimer le nombre total de tokens. Donc, maintenant, ce sera moins car nous utilisons 5 000. Nous allons estimer le coût du chat. Et ensuite, vous remarquez maintenant qu'il est indiqué que le chat coûtera environ 0,3 centime. Donc, avant, si vous vous souvenez, c'était presque le double, 0,58 centime. Donc, maintenant, il estime 0,3 centime car nous avons limité les tokens de sortie. Donc, nous dirons simplement oui, ça casse. Et maintenant, nous allons réellement demander au modèle. Nous allons envoyer notre invite. Et ensuite, il va extraire l'utilisation réelle, par exemple, de la réponse. Il va aller dans l'objet d'utilisation et extraire le nombre réel de tokens qui a été utilisé. Euh, et puis, oui, le nombre total de tokens qui est notre invite plus les tokens de complétion qui est la réponse, et ensuite il calculera le coût réel. Donc, et ensuite il imprimera tout. Et vous remarquerez que c'est beaucoup plus proche de la réalité. Euh, le coût réel était le même. Cela devrait être le même, comme 25 cents ou pas 25 cents, mais comme 0,25, 25 centièmes de centime, comme ça. Mais le coût estimé est plus précis, car nous avons pu deviner plus précisément le coût de sortie, par exemple, de chat GPT, car nous l'avons limité à 5 000 à partir d'une fenêtre de 32 000. J'espère que cela a du sens. Nous avons essentiellement dit à Jack chat GBT que vous ne pouvez pas utiliser plus de 5 000 tokens dans la réponse. Par conséquent, je vais supposer que vous utiliserez un maximum de 5 000 et ensuite notre estimation devrait probablement toujours être légèrement supérieure. Et c'est ce qui s'est passé. Donc, vous verrez combien cela a coûté. Nous avons utilisé, euh, vous savez, GPT. Je pense que 4.1 nano est ce que nous avons utilisé. Donc, nous allons utiliser un modèle plus cher. Nous allons utiliser le plus cher, qui est au moins ici GPT5. Donc, je vais passer à GPT5. Et encore une fois, ce sera exactement la même invite, exactement les mêmes, euh, comme les journaux que nous envoyons à GPD. Tout sera exactement le même, sauf que le modèle sera différent. Et ensuite, nous pourrons comparer le prix entre l'utilisation de GPD5 et l'utilisation de, par exemple, 4.1 nano. Donc, je vais juste relancer ce code. Et ensuite, je n'ai pas besoin de casser ça. Je vais supprimer les points d'arrêt. Et je vais juste le laisser continuer. Et vous remarquerez maintenant que le coût estimé précédemment était, par exemple, 0,3 centime, mais maintenant il est presque 4 cents. C'est 10 fois plus cher. Et je suppose que c'est évident car vous pouvez le voir ici. C'est 10 fois plus cher, plus de 10 fois plus cher. Euh, donc nous allons simplement dire oui. Ensuite, nous le laisserons s'exécuter. C'est comme 3 cents pour l'analyse des journaux que nous faisons en ce moment. Laissez-le continuer. GPT5 prend plus de temps. Vous savez, c'est bien sûr le modèle lui-même est meilleur. Euh, à mon avis, il est plus précis et plus intelligent que 4.1 nano, mais vous voyez qu'il coûte plus cher et il est probable, vous savez, qu'il prendra plus de temps aussi. J'aurais probablement dû mettre une logique ici pour mesurer le temps qu'il faut pour terminer, mais ce n'est pas grave. Nous allons juste le laisser continuer. Cool. Et c'est terminé. Et vous remarquerez que le coût estimé était de 3,7 cents. Le coût réel était de 3,4. Les tokens estimés étaient ceux-ci. Et les tokens réels étaient ceux-ci, ce qui était légèrement inférieur. Et ensuite, je vais exécuter cela une fois de plus. Je vais régler le modèle sur 5 mini. Donc, nous pouvons faire cela. Et ensuite, vous pouvez avoir une idée. Rappelez-vous, ce sont les mêmes journaux, tout est pareil. Donc, je vais exécuter cela sans débogage. Vous remarquerez à quelle vitesse c'était. Et c'est quoi ça ? C'est comme 0,7 centime. C'est assez, assez moins cher. C'est 3 cents. 7 cents. Nous dirons oui. Et c'était aussi assez rapide. Oh non, ce n'était pas la vraie exécution. La vraie demande au modèle. Cela devrait être plus rapide que GPT5 cependant. C'était assez rapide en fait. Et vous pouvez voir, au lieu de 0,7 centime, cela a fini par coûter environ 0,6 centime. Et ensuite, vous pouvez voir le coût réel des tokens. Euh, le token, le nombre de tokens sera le même presque à chaque fois. Euh, cela devrait être le même à chaque fois, sauf pour les tokens de retour. D'accord, je mens à propos de ça. Donc, nous pouvons contrôler les tokens que nous envoyons à GPT, ce sera le même à chaque fois, mais la réponse de GPT est toujours différente, car, vous savez, c'est un LLM et il répond différemment à chaque fois. Mais c'est relativement, c'est relativement proche, comme 26 000, presque 28 000, 25 000. C'est relativement, c'est relativement proche à chaque fois. 25 000. Donc, oui, je vais peut-être expérimenter un peu plus avec ça. Euh, juste pour avoir une bonne idée. Je veux juste donner une idée de la vitesse du modèle, de la fenêtre de tokens et du coût et de tout cela. Euh, je vais expérimenter un peu plus avec ça dans la prochaine leçon. Euh, nous allons en fait combiner les requêtes d'analyse de journaux avec le traitement de ces modèles. Et ensuite, nous allons expérimenter un peu plus avec la fenêtre de tokens et quand vous envoyez trop, trop de journaux à GPT, ce qui se passera, juste pour avoir une meilleure idée de cela, et ensuite aussi avoir une meilleure idée de pourquoi cela fait, comment optimiser l'invite que nous envoyons à eux lorsque nous chassons les menaces et pourquoi tout cela est important. J'espère donc que cela a du sens. Euh, comme toujours, je sais que cela devient un peu difficile, mais plus vous y êtes confronté et plus vous pouvez exploiter GPT, et vous jouez avec, j'espère que vous développerez une intuition avec le temps. Mais si vous avez des questions, comme toujours, allez dans la communauté, publiez, taguez-moi. Ne soyez pas nerveux ou timide à ce sujet, car ce que nous faisons est difficile et je veux que les gens collaborent et s'entraident. Mais j'espère que cela a suffisamment de sens. Si ce n'est pas le cas, faites-le moi savoir si vous avez besoin d'aide et nous nous verrons dans la prochaine vidéo. Et une chose que je veux attirer votre attention rapidement, ce sont les coûts d'entrée et de sortie pour les différents modèles. C'est différent pour les tokens. Donc, par exemple, comme l'entrée, c'est essentiellement quand vous dites, par exemple, faites-moi une recette de gâteau et ensuite la sortie est ce que GPT répond. Et le truc avec la chasse aux menaces, c'est que dans les opérations de sécurité, généralement l'entrée est massivement plus grande que la sortie. Donc, c'est bien. Et ensuite, nous pouvons également contrôler la quantité de réponse que GPT est autorisé à produire dans la sortie. Donc, j'ai juste voulu parler du fait que tous les tokens ne coûtent pas la même chose. Ce que vous mettez dans chat GPT est moins cher et ce qu'il produit est plus cher et vous pouvez contrôler la sortie. Donc, nous pourrons le voir dans le code et laissez-moi voir rapidement et comment vous pourriez faire cela avec, vous savez, le chatbot, si vous utilisez le web, je pourrais dire, par exemple, donnez-moi une recette de gâteau et un moyen de contrôler la sortie, vous pouvez dire, répondez, répondez avec cinq mots ou moins. C'est une façon très rudimentaire de le contrôler dans le navigateur web si vous l'utilisez comme une personne normale. C'est drôle. Euh, mais avec chatbt ou avec l'API, vous pouvez le contrôler très précisément. Donc, par exemple, je vais juste essayer une autre de celles-ci. Donnez-moi une recette de nachos. Limitez votre réponse. Je vais en parler en termes de tokens à 10 tokens ou moins, juste pour l'exemple, et ensuite je ne sais pas si ce sont 10 tokens, vous savez, mais juste pour l'exemple. Donc, pour entrer dans le code, vous aurez besoin de deux fichiers. Je les mettrai dans la description ou comme vous voulez appeler ça. L'un d'eux est "tokens lesson", qui est le code principal que nous allons utiliser, et l'autre fichier est "logs", "logs short py". C'est littéralement juste une variable avec une variable de chaîne multiligne avec un tas de journaux du côté de la gamme. Ce sont les journaux d'événements de processus de l'appareil. Et nous allons juste utiliser cela pour construire une invite et faire une chasse aux menaces très basique. Mais la chasse aux menaces n'est pas le but de ce laboratoire. Le but est d'explorer les différents modèles et les différents coûts de tokens et de simplement prendre conscience que différents modèles coûtent différentes choses, si cela a du sens. Donc, en gros, en langage clair, ce que fait ce code, il y a un tas de modèles parmi lesquels choisir et si vous remarquez que ceux-ci sont synonymes, pas synonymes, mais ils correspondent à ceci. Donc, comme GPD5, vous savez, le coût d'entrée coûte ceci, le coût de sortie coûte ceci, et ensuite la fenêtre maximale, etc., et ensuite la fenêtre maximale de GPT5, puis le coût d'entrée, puis le coût de sortie, et ensuite ceux-ci sont tous les mêmes. Ils devraient être précis. Donc, comme GPT 4.1 nano, le coût d'entrée est de 10 cents par million de tokens. La sortie est de 40 cents par million de tokens. GPT 4.1 nano, le coût d'entrée est de 10 cents par million de tokens, 40 cents par million de tokens, etc. Donc, et nous allons utiliser ces données pour calculer le coût de nos invites et de nos messages à GPT juste pour avoir une idée de son fonctionnement et de son importance, et ce sera très important pour la prochaine leçon. Donc, je vais juste casser ça et ensuite je vais le parcourir et essayer de l'expliquer en cours de route. Je me rends compte que c'est probablement un peu petit. D'accord. Donc, je vais juste commencer le débogage et je vais le casser ici. Oh, je vais corriger cela avant que vous ne l'obteniez. Je ne sais pas pourquoi c'est, mais je vais recommencer le débogage. D'accord. Et ensuite, laissez-moi dézoomer un peu. Oui, c'est un peu difficile. Je voulais montrer toutes les choses à l'écran, mais "max output tokens". Euh, nous pouvons utiliser cette variable pour contrôler le nombre de tokens de sortie que GPT est autorisé à utiliser. Euh, donc je le définis juste ici. Et ensuite, c'est le modèle par défaut. J'ai donc décidé d'utiliser d'abord 4.1 nano car c'est le moins cher. Passer par-dessus. Donc, nous avons notre modèle actuel. C'est un GPD 4.1 nano. Je vais zoomer un peu. Je sais que c'est un peu difficile à lire, mais nous allons passer par-dessus ce dictionnaire de modèles en cours de création. Et ensuite, c'est juste une fonction. Euh, elle calcule simplement combien un chat va coûter. Nous allons essentiellement, lorsque nous l'utiliserons, passer le nombre de tokens que nous envoyons ainsi que le coût de ces tokens. Ce sera donc différent pour l'estimation de l'entrée et de la sortie d'un chat. Et ensuite, cette fonction est utilisée pour compter le nombre de tokens dans un message. Euh, elle utilise une bibliothèque spéciale et une logique GPT, essentiellement pour faire cela. Donc, elle prendra un message et ensuite elle affichera simplement le nombre de tokens que ce message a dans notre client API. Donc, nous pouvons communiquer avec GPT. Et ensuite, c'est vraiment important. C'est l'invite qui va être construite. Et en gros, elle dit : "Vous êtes un chasseur de menaces. Y a-t-il des anomalies ou des brèches potentielles ?" Et ensuite, elle passe tous ces journaux. C'est une invite de chasse aux menaces très rudimentaire. Et lorsque nous créerons l'agent, il sera bien meilleur que cela. Mais je voulais juste [renifle] créer une invite avec une quantité substantielle de choses. Euh, donc nous pouvons observer la variation des coûts, si cela a du sens. Donc, passer par-dessus cela et ensuite cela construit le message à envoyer à GPT. Donc, si vous vous souvenez, lorsque vous envoyez un chat à GPT ou une invite, il doit être dans ce format : le rôle, puis le contenu avec l'invite, et c'est une liste de ces objets dictionnaire. Donc, nous n'en envoyons qu'un seul avec notre invite ici, notre invite de chasse aux menaces. Donc, c'est le message créé comme ceci, et vous pouvez le voir ici, message d'invite, et vous pouvez voir la liste de zéro ou la liste d'un objet, rôle, puis contenu, et ensuite nous pouvons soit, oh, donc je vais passer par-dessus cela et l'estimation, d'accord, cela estime le nombre de tokens dans notre message d'entrée. Donc, elle a utilisé cette fonction ainsi que les messages pour calculer le nombre de tokens et elle a calculé qu'il y a environ 25 000 tokens, et ensuite ici, nous pouvons déterminer le nombre maximum ou le nombre maximum de tokens utilisés dans la réponse de GPT. Donc, nous pouvons soit le faire en le codant en dur ici avec cette variable, ce que nous avons fait. C'est comme 5 000, ou nous pouvons simplement supposer que GPT utilisera le nombre maximum de tokens de sortie autorisés. Et si vous vous souvenez, c'est juste ce que c'est. Donc, nous utilisons GPT 4.1 nano. Et pour ce modèle particulier, le nombre maximum de tokens qu'il peut produire est de 32 768. Donc, nous pouvons soit supposer qu'il produira ce nombre, soit le limiter en dur à ce que c'est, ce qui est 5 000. Donc, je vais probablement, en fait, je vais exécuter cela d'abord. Euh, je vais commenter cela. Je vais l'exécuter d'abord et calculer le nombre de tokens avec le maximum théorique qu'il est autorisé à faire. Donc, je vais juste relancer cela. Je vais juste, euh, le faire avancer. [renifle] D'accord, nous sommes de retour ici. Donc, je ferai cela la prochaine fois. Donc, je vais passer par-dessus cela et ensuite nous obtiendrons combien cela coûte pour le modèle, par million de tokens d'entrée et par million de tokens de sortie. Donc, cela utilise simplement le dictionnaire de modèles avec notre modèle actuel et ensuite il extrait la valeur du coût par million d'entrée et du coût par million de sortie. Donc, si nous passons par-dessus cela, parce que nous avons utilisé le modèle que nous avons utilisé était GPD 4.1 nano, le coût par million de tokens d'entrée est de 10 cents et le coût par million de tokens de sortie est de 40 cents. Donc, c'est juste d'ici, GPD4 nano, entrée 10 cents, sortie 40 cents. Donc, et maintenant nous allons estimer le coût de l'entrée avec cette fonction. Nous allons y passer le nombre de tokens et ensuite le coût par million de tokens. Et ensuite, cela produira le coût d'entrée estimé. Donc, il estime que nous allons payer environ 0,22 centime pour cette entrée. Et ensuite, il va estimer le coût de sortie. Donc, encore une fois, nous allons passer le nombre maximum de tokens utilisés, le maximum théorique par le modèle, et ensuite combien cela coûte, comme ça. Donc, il estime que si nous utilisons effectivement 32 000 tokens pour la sortie. Ce n'est pas probable, mais si nous le faisons, le coût de sortie estimé sera de 1,3. Et ensuite, il va estimer le coût total du chat en estimant le coût d'entrée plus le coût de sortie estimé. Donc, il estime que le coût total du chat est de 1,56 centime, ou, vous savez, 1,6. Et ensuite, il va informer l'utilisateur et lui demander s'il veut continuer. Il le fait. Donc, il estime que cela coûtera autant. Voulez-vous continuer ? Nous pouvons dire oui. Donc, si le choix n'est pas égal à oui, le choix a été abandonné, c'était oui. Donc, maintenant, il va réellement envoyer le message à chat GBT et nous allons obtenir une réponse. C'est donc le message de chasse aux menaces, comme vous êtes un chasseur de menaces. S'il vous plaît, regardez ces journaux. Y a-t-il des problèmes ? C'est donc ce qui se passe en ce moment. Je vais agrandir un peu car nous allons inspecter certaines choses ici. Donc, nous avons notre réponse de chat GBT qui est ici. Elle est stockée dans cette variable, et il y a des propriétés spéciales à l'intérieur de la réponse qui montrent en fait combien tout a coûté en termes de tokens, ou combien, oui, combien de tokens cela a coûté. Donc, si nous développons la réponse et que nous pouvons aller à la propriété d'utilisation, nous pouvons voir les tokens d'invite, qui est le nombre de tokens que nous avons envoyés, nous l'avons effectivement envoyé, c'était 24 584, et ensuite les tokens de complétion est le nombre total de tokens avec lesquels chat GPT a effectivement répondu n'était que de 673, et vous vous souviendrez que nous avons estimé que cela allait être, vous savez, le maximum théorique qui est de 32 000, mais il a fini par n'en utiliser que 673, par exemple. Donc, si nous passons par-dessus cela, il va extraire les tokens d'invite et les stocker ici. Donc, nous pouvons voir le nombre réel de tokens qui a été utilisé dans l'invite, puis le nombre réel de tokens de sortie, alias les tokens de complétion, puis le nombre total réel de tokens. Je ne pense pas que nous allons utiliser cela pour quoi que ce soit, mais de toute façon, nous l'avons stocké. Donc, maintenant, nous allons calculer le coût réel de l'entrée. Donc, nous allons prendre le nombre de tokens qui ont effectivement été entrés et ensuite nous allons, euh, également l'entrée, combien cela coûte, et ensuite cela calculera le coût réel que cela coûtera de faire cela. Donc, le coût d'entrée réel était d'environ 0,2, qu'est-ce que c'est, environ 0,24 centime. Ce n'est même pas un quart de centime. Il va faire la même chose avec la sortie. Euh, c'est aussi assez bon marché, comme 26 cents, ou, vous savez, environ 27 cents, essentiellement. Et ensuite, il va calculer le coût réel. Il additionne simplement le coût de l'entrée plus le coût de la sortie. Le coût réel de ce message n'était que de 27 cents. Et ensuite, il va faire quelques calculs pour nous. Donc, nous pouvons en fait, il va calculer et ensuite les colorer. Donc, si c'est supérieur à l'estimation, ce sera rouge. S'il est inférieur à l'estimation, ce sera vert. Donc, essentiellement, cela affiche tout pour nous. Nous pouvons voir le nombre estimé de tokens, le coût estimé. Ensuite, nous pouvons voir le nombre réel de tokens, le coût réel, et ensuite la réponse sont stockés ici. C'est la réponse réelle de chasse aux menaces qu'elle a donnée. Je ne suis pas vraiment intéressé par cela pour cette leçon. Si vous voulez le voir, vous pouvez supprimer cela d'ici et le relancer. Mais, vous savez, si vous voulez voir les résultats de la chasse aux menaces, mais ce n'est pas le but de cette leçon, donc je ne vais pas en parler, mais vous pouvez le voir si vous voulez. Mais comme vous pouvez le voir, ce sont des estimations, notre entrée de tokens estimée, notre sortie de tokens estimée, et ensuite le coût estimé était, le coût estimé était en fait de 1,5, mais la réalité est qu'il est arrivé bien en dessous de cela. Donc, le nombre estimé de tokens était assez proche, les tokens d'entrée, les tokens de sortie étaient très loin, car nous avons estimé qu'il allait utiliser toute la fenêtre, toute la fenêtre possible, mais il n'avait besoin que de 600 tokens et en conséquence, le coût réel du chat était bien moins cher. C'est beaucoup moins cher. Ce n'est même pas 1 centime, alors que c'est 1,5 centime. Donc, vous pouvez voir une erreur ici. Ce n'est pas vraiment une erreur, mais nous n'avons pas limité, comment puis-je dire, dans notre estimation, nous avons estimé qu'il allait utiliser toute la fenêtre, toute la fenêtre de sortie, mais ce n'est pas vraiment nécessaire. Il y a beaucoup de façons d'estimer combien cela va coûter, mais une façon est que vous pouvez simplement limiter la sortie en dur à quelque chose, donc vous obtenez une estimation plus proche. Donc, vous voyez que pour nos besoins, la sortie n'a même pas dépassé 700. Donc, nous pouvons simplement laisser cela se terminer, et ensuite lorsque nous estimerons la sortie, nous pourrons la coder en dur à, disons, mille, par exemple. Donc, je vais mettre la constante de variable "max output tokens" à mille, et ensuite nous irons à l'endroit du code où nous l'estimons réellement. Donc, c'est ici. Donc, au lieu d'utiliser le maximum théorique du modèle, nous pouvons utiliser le nombre codé en dur, par exemple, mille. Donc, je vais commenter cela et ensuite je laisserai le programme l'utiliser. Et vous devez faire attention car parfois vous pourriez avoir besoin de plus de mille tokens pour la sortie. Mais pour nos besoins, nous allons simplement le limiter à mille dans ce cas. Et ensuite, nous allons exécuter le même code à nouveau avec le même modèle, la même invite, tout pareil. Et ensuite, nous allons simplement observer que l'estimation est plus précise. Donc, nous allons exécuter cela à nouveau. Je vais juste, je vais juste l'exécuter sans débogage. Vous pouvez déboguer votre code, d'ailleurs, je le recommande vivement. Et ensuite, vous pouvez le parcourir et observer tout. Oh, apparemment, j'ai débogué. D'accord, donc je vais juste le laisser s'exécuter. Et le coût est de tant. Oui ou non. Donc, je dirai oui. Nous allons juste le laisser continuer. Et ensuite, je vais l'exécuter quelques fois de plus avec différents modèles. Et ensuite, nous verrons le coût augmenter à mesure que nous utilisons des modèles progressivement plus chers. Donc, maintenant, nous pouvons voir que les entrées de tokens estimées étaient de 25485. Et c'est vraiment, vraiment proche en fait, comme vous pouvez le voir. Et ensuite, la sortie de tokens estimée est de mille car nous l'avons limitée en dur. Et la sortie réelle a fini par être de 698. C'est légèrement plus élevé que celui-ci. La belle chose avec les LLM, c'est que la sortie sera toujours légèrement différente. Et ensuite, le coût estimé du chat était de 29 cents. Il a fini par être de 27 cents. Et c'est une estimation beaucoup plus proche car nous avons pu estimer les tokens de sortie car nous pouvons les limiter en dur, si cela a du sens. Euh, donc, en fait, laissez-moi juste exécuter cela une fois de plus. Je vais limiter la sortie à, disons, 100 et voir ce que le modèle fait. Donc, je vais juste, cette fois, je vais réellement exécuter sans débogage. Je remettrai cela à mille plus tard, mais je veux juste voir ce qu'il fait. Nous dirons oui ici. C'est tellement drôle. Il nous a littéralement donné exactement mille ou 100 tokens en sortie. Donc, en fait, je suis désolé. Je suis juste curieux de voir à quoi ressemble la sortie. Donc, je vais, euh, je vais supprimer ce commentaire et je vais l'exécuter à nouveau sans débogage. Et ensuite, nous pourrons réellement voir les résultats de la chasse aux menaces en moins de mille ou moins de 100 tokens. Donc, je vais juste dire oui. Et ensuite, il est ressorti à nouveau. Il est presque exactement dans le budget. Et ensuite, ce sont 100 tokens. Et vous pouvez voir qu'il a simplement tronqué, il voulait en dire plus, mais il a simplement tronqué la sortie à exactement 100 tokens. Et il ne nous dit pas réellement, vous savez, la sortie est trop limitée, c'est ce que j'essaie de dire. D'accord. Donc, je vais, euh, je vais le cacher à nouveau. Je n'ai pas besoin de voir la sortie à chaque fois. Et je vais réengager cela à mille. Donc, et ensuite je vais utiliser le modèle suivant. Je vais utiliser GPT5 mini. En fait, laissez-moi, laissez-moi exécuter cela une fois de plus. Je veux juste avoir tous les modèles sur l'écran, les différents modèles, afin que nous puissions les comparer facilement à la fin. Aussi, oui. D'accord. Et encore une fois, ce coût avec un 4.1 nano, ce coût est de 28 cents. Remarquablement bon marché. Donc, je vais prendre ce modèle. Je vais le mettre ici. Et ensuite, nous avons changé notre modèle en GPT5 mini. Vous vous souvenez, vous pouvez voir le coût et tout ici. Donc, et ensuite encore, tout cela est juste ici, vous savez, si vous voulez continuer à y revenir et à regarder cela. Donc, euh, je vais juste exécuter cela. Je ne vais pas le déboguer. Vous pouvez déboguer le vôtre. Je le recommande. Vous savez, parcourez et observez ce que fait le code pour en avoir une bonne intuition. Eh bien, cette fois, il a estimé 8 cents. Donc, nous allons exécuter cela. Et nous avons eu une erreur. D'accord. Utilisez "max completion tokens" à la place. D'accord. C'est drôle. Euh, donc c'est une bonne leçon. Je suppose que je vais expliquer ce qui s'est passé. Donc, c'est la fonction que nous utilisons pour demander à chatgp, pour envoyer notre invite à chat GPT. Mais apparemment, ce modèle que nous avons utilisé, qu'est-ce que nous utilisons, 5.1 mini, il a besoin d'utiliser "max completion tokens" à la place de "max tokens". "Completion tokens". "Max tokens" n'est pas pris en charge avec ce modèle. Utilisez "max completion tokens" à la place. Donc, je vais juste le régler. Donc, c'est juste quelque chose à garder à l'esprit, différents modèles auront des comportements différents en ce qui concerne l'API et les choses en arrière-plan. Donc, je vais juste exécuter cela à nouveau, je suppose. "Max completion tokens". Euh, oui, je ne veux pas que ce soit trop compliqué. Il y a différentes façons de gérer cela. Comme, vous savez, si le modèle est GPT 5.1 mini, alors c'est le paramètre pour lui, vous savez, mais je n'entrerai pas dans tout cela encore. Je vais juste exécuter cela. Et si vous rencontrez une erreur inattendue ou différente, allez absolument sur le forum de la communauté et publiez et taguez-moi. Mais, d'accord, c'est GPT. Euh, était-ce GPT 5.1 mini ? Si nous nous souvenons, GPT était un 4.1 nano, il est arrivé à 28 cents, et ensuite GPT 5.1 mini, est-ce ce que nous utilisons ? Oh, désolé. GPT 5 mini, qu'est-ce que je dis ? Il est arrivé à 81 cents. Donc, combien est-ce de plus ? C'est environ trois fois, trois fois plus cher. 81 cents. Et si nous regardons le coût ici, c'est environ trois fois plus, vous savez, en termes d'entrée et de sortie, peut-être, vous savez, 2,5 fois plus, quelque chose comme ça. Donc, c'est intéressant. Donc, nous allons faire le modèle suivant, le plus cher ensuite, GPT 4.1. Nous allons le régler ici. Nous allons observer le coût et tout le reste. Donc, nous allons juste exécuter cela sans débogage. Qu'est-ce que Oui. Et n'hésitez pas à faire une supposition basée sur ce GPT4.1. Je vais juste faire une supposition maintenant. Euh, donc il ressemble, voyons, entrée. C'est comme, c'est comme huit fois plus cher que ceci. C'est exactement, l'entrée est huit fois plus chère, la sortie est quatre fois plus chère que GPT5. Donc, je vais dire, euh, combien était-ce 8 avant ? Donc, ce devrait être, par exemple, 6 cents ou quelque chose comme ça. Je vais deviner, oh, c'est 3 cents. D'accord. Euh, donc l'estimation est assez proche. Oh, il a utilisé tous les tokens en fait. Il a utilisé tous les tokens de sortie. C'est intéressant. Et celui-ci a fini par coûter 3,25 cents, ou, oui, 3,25 cents. Et ensuite, le dernier, nous allons utiliser GPT5, c'est je crois le plus cher. Donc, nous allons jeter un coup d'œil. Oh non, ce n'est pas en fait, c'est moins cher. C'est moins cher. L'entrée est moins chère que 4.1. Voyons voir ce qui va se passer ici. Oh mon dieu. Je ne voulais pas faire ça. D'accord. Donc, nous allons exécuter cela. Nous allons exécuter sans débogage et nous allons dire, d'accord, nous allons voir ce qui s'est passé ici. Impossible de mapper automatiquement G. D'accord. Je suis certain que je sais ce qui s'est passé. C'est parce que, euh, tick token, la chose qui compte les tokens, ne sait pas comment faire cela avec GPT5 encore. Mais nous pouvons, il y a un moyen, je sais, je sais comment résoudre cela parce que je l'ai rencontré un autre jour. Vous pouvez le forcer à utiliser un certain, euh, un modèle différent. Oh mon dieu, comment puis-je dire ça ? Bref, il y a un moyen de le forcer à fonctionner. Donc, laissez-moi juste faire cela en direct. Et vous pouvez probablement me copier ou je vais peut-être corriger le code ou quelque chose comme ça pour qu'il fonctionne quand vous y arriverez. Mais, euh, où est ce calcul de token ? Oh, "count token messages". D'accord. Donc, faites ceci. Je vais prendre ceci et ensuite j'irai à GPT. Et ensuite, au fait, je corrigerai probablement ce code pour que cela ne casse pas comme ça quand vous l'obtenez. Mais, euh, juste pour la leçon, je vais dire, euh, s'il vous plaît, corrigez ce code. Donc, lorsque vous passez GPT5, il codera en dur la chose appropriée. Puisque tick token ne reconnaît pas encore le modèle GPT5, faites ceci pour qu'il le sache. Probablement le corriger. Oh, c'est ce que je voulais dire, le coder en dur pour utiliser ceci. Je pense que c'est correct. D'accord. Donc, nous allons juste prendre cette fonction. Je suis assez certain que cela va fonctionner. Et ensuite, je vais remplacer, je vais juste remplacer ceci. Donc, je ne sais pas exactement comment cela fonctionne pour être honnête, mais laissez-moi l'expliquer. Cette fonction qui calcule combien de tokens un message utilise, utilise cette chose. Euh, je suppose que les différents modèles utilisent un type d'encodage différent, mais c'est, je ne sais pas. Cette bibliothèque n'a pas été mise à jour pour reconnaître GP GPT5 encore. Donc, ça ne marche pas. Donc, vous lui avez juste dit que si le modèle est GPT5, alors codez en dur l'encodage à ceci, sinon obtenez l'encodage spécifique pour le modèle. Donc, cela fonctionnera probablement. Donc, nous allons juste exécuter cela. Je viens de le coder à l'instant. Oh mon dieu. Mais c'est plutôt bien pour notre leçon ici. Donc, je vais juste dire, oui. J'espère que cela fonctionnera et que nous ne passerons pas beaucoup de temps. Je pense que cela fonctionnera cependant. DPT5, j'ai remarqué que cela prend du temps. Euh, je ne sais pas exactement ce qu'il fait, mais j'ai remarqué qu'il produit de nouveaux résultats en chasse aux menaces, meilleurs que 4.1, ou il remarque plus de choses. Donc, je suppose qu'il utilise son gros cerveau pour faire quelque chose. Mais cela a tendance à prendre plus de temps. Vous vous souvenez de GPT4, quel était le dernier que nous avons fait ? 4.1 a coûté 3,25. Et ensuite, celui-ci est arrivé à, semble-t-il, légèrement plus cher, ce qui était surprenant. Donc, quatre, cette requête a coûté 4 cents et elle a utilisé tous les tokens, semble-t-il. Oui. J'espère que cela a du sens. Euh, n'hésitez pas à ajuster les journaux si vous le souhaitez, ou si vous êtes dans le cyber-range, n'est-ce pas ? Vous pouvez aller à l'analyse des journaux et obtenir différents journaux, n'est-ce pas ? Et vous pouvez expérimenter un peu avec cela. Mais pour cette leçon, je voulais juste montrer, vous savez, tous les tokens ne sont pas créés égaux. Les tokens d'entrée sont généralement moins chers, la sortie est plus chère. Vous pouvez limiter le nombre de tokens qui sont produits, qui sont produits. Euh, c'est juste notre variable, mais vous pouvez, où est la fonction ? Vous pouvez limiter les tokens comme ceci, combien sont produits, et ensuite différents modèles coûtent différentes sommes d'argent. Donc, vous pourriez vouloir considérer, vous savez, si je devais juste, si quelqu'un me tenait une arme sur la tête et me disait, choisis un modèle, choisis-en un, ou je vais te tuer. Je choisirais probablement, je choisirais probablement GPT5 Mini, parce que c'est, vous savez, nouveau et c'est assez intelligent et c'est assez rapide et c'est assez bon marché aussi, n'est-ce pas ? C'est assez bon marché comparé à ceux-ci. Donc, mais vous pourriez avoir un scénario où vous voulez vraiment vous assurer que quelque chose est correct, n'est-ce pas ? Et alors vous utiliseriez GPT5, ou peut-être que vous avez un autre scénario où vous devez alimenter une énorme fenêtre, une énorme invite à GPT, à GPT et vous voulez qu'elle soit relativement précise. Donc, dans ce cas, vous pourriez vouloir utiliser GPT 4.1. Et il y a bien sûr d'autres modèles aussi. J'ai juste choisi ceux-ci. J'espère donc que cela a du sens. Je voulais juste vous donner une intuition pour ces choses et ensuite vous faire prendre conscience des différents modèles et des différences entre eux. Mais oui, euh, nous nous verrons dans la prochaine leçon. Bienvenue. Dans cette leçon, nous allons couvrir la limitation du débit de l'API spécifique à l'API OpenAI chat GBT. Donc, essentiellement, ce que c'est, vous n'êtes autorisé à envoyer qu'une certaine quantité de tokens, je suppose, à l'endpoint de l'API dans une période donnée. Et plus votre quota, entre guillemets, est élevé, plus vous êtes autorisé à envoyer. Donc, >> [renifle] >> euh, essentiellement, je vais expliquer ce que c'est et ensuite nous le regarderons un peu dans le code, puis nous passerons à la leçon suivante. Celle-ci devrait être assez rapide. Donc, rappelez-vous qu'il existe de nombreux modèles différents que nous pouvons utiliser et ce sont ceux avec lesquels nous travaillons actuellement. Donc, si vous faites défiler un peu vers le bas, vous verrez. Oh, ai-je dépassé ? Non. Oh, il y a des limites de débit pour chacun de ceux-ci. Donc, par exemple, GPT5 est dans la colonne la plus à gauche. Donc, si nous faisons défiler vers le bas, nous verrons les limites de débit, et nous verrons le niveau gratuit. Niveau un, vous pouvez envoyer 30 000 tokens par minute. Niveau deux, vous pouvez envoyer, comme, 450 000 tokens par minute. Et si vous vous demandez comment atteindre le niveau un et le niveau deux, il y a cette page de limites de débit. Je mettrai des liens vers les deux, soit dans la leçon, soit dans le code réel. Mais [renifle] par exemple, si vous avez un compte et que vous y dépensez cinq dollars, cela vous place dans le niveau un, apparemment si vous dépensez 50 dollars et qu'il y a eu 7 jours depuis votre dernier paiement réussi, cela vous place dans le niveau deux, puis dans le niveau trois, puis dans le niveau quatre, etc. Donc, notre compte professionnel est probablement, il est probablement, probablement niveau cinq maintenant, pour être honnête. Parce que 1000 dollars, je ne sais pas si nous avons dépensé 1000 dollars encore. Peut-être après avoir créé tous ces jeux de questions pratiques. Mais le compte de pratique que j'ai créé avec cela, je pense que c'est le niveau un parce que je n'ai dépensé que cinq dollars pour le financer. Je pense que je pense que j'ai encore 4,20 dollars. Donc, [renifle] essentiellement, ce que cela signifie, c'est que si nous utilisons, euh, GPD5, qui est cette colonne de gauche, nous ne pouvons pas envoyer plus, dans une seule requête, nous ne pouvons pas envoyer plus de 30 000 [renifle] tokens, et en une minute entière, nous ne pouvons pas envoyer 30 000 tokens. Donc, essentiellement, ce à quoi cela ressemble, allez-y et, vous pouvez couper cela, Leia ou Miho ou qui que ce soit qui édite cela. D'accord, vous pouvez commencer à partir de maintenant. Donc, essentiellement, j'ai inclus du code pour cette leçon. Nous avons ce "logs long py" et ce "logs short py", et ce sont essentiellement des journaux du cyber-range, de la table des événements de processus, des événements de processus de l'appareil. Le "log short" est juste une version courte de cela, et le "logs long" est une chose absolument gigantesque de journaux, essentiellement, c'est juste beaucoup de journaux, et ce "logs long" dépasse, il dépassera à coup sûr 30 000 tokens. Donc, je veux juste montrer une démo avec cela. Ce code est très similaire à notre leçon précédente, mais j'ai changé quelques trucs. Donc, vous pouvez télécharger ce code. Téléchargez ces trois-là. Ce "rate limit test py" et ensuite ces deux choses, comme ça. Et [renifle] ensuite, assurez-vous simplement que votre modèle est réglé sur gp5. Et ensuite, nous ferons défiler un peu vers le bas, et ensuite sous ce message d'invite, c'est l'invite que nous allons envoyer à GPT. Nous allons utiliser une, oh, cela devrait être un système. Euh, nous allons utiliser une invite système et une invite utilisateur. L'invite système consiste simplement à donner au modèle le contexte de ce qu'il veut. Donc, vous êtes un chasseur de menaces. Si vous, euh, si l'utilisateur fournit des journaux, analysez-les pour détecter une activité malveillante. Et ensuite, c'est notre invite utilisateur. Nous allons simplement dire, voici quelques journaux. Et ensuite, nous allons importer ces grands journaux, journaux de sécurité. Et "big logs" est juste, si nous faisons défiler vers le haut, j'ai importé "logs long" qui est ceci comme "big logs", et c'est juste tous ces énormes journaux, n'est-ce pas ? Donc, ce sont les messages que nous allons envoyer. Nous allons calculer les tokens et tout cela, et ensuite avant de faire réellement l'appel API, nous pourrons voir combien de tokens c'est, et rappelez-vous, ce compte, ce compte particulier est essentiellement neuf et je n'ai dépensé que cinq dollars dessus. Donc, cela devrait signifier que nous ne sommes qu'au niveau un. Donc, si nous envoyons plus de 30 000 tokens, en théorie, cela devrait générer une erreur, n'est-ce pas ? J'espère donc que cela a du sens. Donc, nous allons simplement exécuter cela et commencer le débogage. Et nous voyons que les tokens d'entrée estimés sont de 151 000, c'est beaucoup, n'est-ce pas ? Donc, il dit "appuyez sur n'importe quelle touche pour continuer". Et ensuite, il s'arrête ici. Et ensuite, euh, oui, je vais juste passer par-dessus cela. Et ensuite, c'est la fonction qui envoie réellement la charge utile, les messages à GPT. Donc, nous allons essayer de le faire. Et ensuite, nous avons une erreur. Elle dit, c'est l'erreur. Euh, [renifle] c'est l'exception si nous voulions l'attraper. La requête est trop grande pour GPT5 dans votre organisation en tokens par minute. La limite de débit de tokens par minute est de 30 000 et vous avez demandé 100 000, essentiellement. Je ne suis pas sûr pourquoi ce nombre est si éloigné de celui-ci, car il est assez éloigné, mais de toute façon, c'est trop. Les tokens d'entrée ou de sortie doivent être réduits pour pouvoir s'exécuter avec succès. Visitez ceci pour en savoir plus sur vos limites de débit. Et cela nous dit que notre limite est de 30 000. Donc, cela signifie que, vous savez, nous sommes essentiellement au niveau un. Et il y a probablement un moyen de voir quel niveau vous êtes avec le code pour éviter que cela ne se produise même. Donc, par exemple, je vais juste expérimenter un peu avec cela. Vous n'avez pas à me copier. Vous pouvez juste regarder. Mais je vais copier ceci. J'irai à GBT et je dirai, comment vérifier l'API préventivement pour voir quel niveau nous sommes, quelque chose comme ça. Je suppose que nous pouvons le faire et je vais juste coller ceci. Vous atteignez une limite de débit. [éclaircit la gorge] Le moyen le plus simple est d'aller dans le tableau de bord et les limites de débit. Il montre votre niveau actuel. Oh, d'accord. Laissez-moi cliquer dessus et voir si c'est vrai. Donc, niveau, oh, c'est ici. Le niveau d'utilisation de votre organisation a un impact sur votre blah blah blah. Votre niveau actuel est un. D'accord, très bien. Utilisez l'API par programme. Apparemment, vous pouvez l'utiliser par API aussi. Je ne vais pas essayer de gérer cela, mais je voulais juste jeter un coup d'œil. Donc, par exemple, nous savons que c'est trop gros. Donc, arrêtons cela pour l'instant. Et ensuite, au lieu d'envoyer les longs journaux ou les journaux longs, je vais envoyer les petits journaux. C'est l'autre chose que nous avons importée. Donc, si nous faisons défiler vers le haut, nous voyons "big logs", "small logs". Donc, "small logs" a beaucoup moins et cela ne devrait pas atteindre notre limite. Donc, je vais m'assurer que c'est cassé ici. Et ensuite, je vais tenter de l'exécuter. Oh mon dieu. Commencer le débogage. Et je vais faire quelques activités supplémentaires juste pour que nous puissions avoir une idée de ce qu'est la limite de débit et peut-être comment empêcher le programme de planter si nous atteignons la limite. Donc, les tokens d'entrée estimés sont de 25 000. Et cela devrait être dans notre limite de débit pour au moins GPD5, qui est ce que cette colonne est, ce que nous utilisons, modèle actuel GPD5. [renifle] Donc, nous allons appuyer sur entrée pour continuer. Ensuite, nous allons passer par-dessus cela et espérons que cela fonctionne. Donc, et je dois aller aux toilettes. Donc, vous pouvez, vous pouvez couper cela. D'accord, nous sommes de retour et il semble que cela ait fonctionné. Je vais juste laisser le programme se terminer. Et ensuite, nous voyons que les tokens d'entrée réels étaient de 24 000, les tokens de sortie étaient de 36. C'est inférieur à 30 000 et cela a coûté, il semble que cela coûte 6 cents pour s'exécuter. Donc, c'est assez cool. Essayons donc de faire une autre chose. Je ne suis pas sûr de la façon dont cela va se passer, mais utilisons les longs journaux à nouveau. Donc, j'utiliserai à nouveau les grands journaux. C'est le truc énorme. C'était plus de 100k tokens, je pense. Mais nous utiliserons un modèle différent. Donc, vous remarquerez que, qu'est-ce que ces deux modèles ? Il semble que pour ces deux-là, le niveau un, le total des tokens par minute est de 200 000 pour les deux. Donc, qu'est-ce que c'est ? GPT5 [renifle] mini et GPD4.1 Nano. GPT5 mini coûte 25 cents par million. Donc, je vais essayer d'utiliser GPT5 mini et voir si nous pouvons traiter les grands journaux avec. Rappelez-vous, cela a échoué la dernière fois lorsque nous avons essayé de le traiter avec GPT5. Donc, je vais mettre GPT5 mini ici et je vais recommencer le débogage. Rappelez-vous, nous utilisons les longs journaux cette fois, ou le grand, les journaux énormes. Où est notre message ? Oh, il est juste ici. Donc, nous voyons, oh, quelle est notre limite ? Qu'est-ce que c'était ? J'ai déjà oublié. 200k. 200k et nous avons 149 tokens d'entrée estimés. Donc, cela devrait techniquement traiter. Voyons donc ce qui se passe avec cela. Donc, nous allons passer par-dessus cela et laisser cela continuer. Cette chose prend du temps à traiter cela. D'accord.

Ça a fonctionné, ça n'a pas planté cette fois-ci. Donc, c'est bien. Et je vais juste lancer ce programme. Je l'ai juste décomposé ici. Et ensuite, nous voyons les jetons d'entrée réels 143k jetons de sortie ce nombre. Et cela a coûté 4 cents pour fonctionner. Et je viens de décomposer cette chose ici. Euh, juste pour rappel, vous pouvez, si vous êtes intéressé par la visualisation de la chasse aux menaces réelle qu'il a effectuée, vous pouvez regarder ceci si vous le souhaitez. Euh, encore une fois, ce n'est pas le but de cette leçon. Oh mon dieu. Encore une fois, ce n'est pas le but de cette leçon, mais euh vous pouvez, c'est quelque chose que vous pouvez voir si vous le souhaitez. Mais je voulais juste montrer que même si nous avons une tonne de jetons, si nous passons le modèle à quelque chose qui a une fenêtre de limite de débit plus grande, comme les jetons par minute, nous pouvons toujours traiter la requête et cela devrait aller. Euh, je veux dire, peut-être que vous comprenez ce que je dis. Il y a toujours un cas d'utilisation commerciale pour la sélection de votre modèle. comme si vous savez si c'est trop gros et que vous devez juste le traiter, vous pouvez toujours euh par exemple, lorsque nous créons l'agent IA, il y a toujours quelque chose que nous pouvons faire dans le code qui dit, vous savez, si c'est trop gros ou si ça plante, vous pouvez utiliser un modèle différent. Je vais donc vous montrer à quoi cela ressemble euh ici. Par exemple, laissez-moi euh je vais juste arrêter ça pour l'instant. Et puis euh je vais revenir à l'utilisation de euh GPD5 car si vous vous souvenez, c'est cette colonne qui est GPT5. Le niveau un est comme 30 000 limites ou 30 la limite est de 30 000 jetons par minute, ce que notre grande requête de journaux dépasse 100K. Je vais donc vous montrer quelque chose que vous pouvez faire. Par exemple, nous pouvons dire euh je vais juste le laisser planter une fois de plus juste pour que nous puissions observer l'erreur. Je vais donc changer ce modèle pour GPD5 et je vais commencer à déboguer cela. Je vais utiliser euh je vais tenter d'utiliser à nouveau le bloc try accept. Donc, euh, laissez-moi voir où est notre Ok, donc j'appuierai sur entrée pour continuer. [renifle] Au fait, vous devez cliquer dans la console avant d'appuyer sur entrée. Euh, donc cette chose va fonctionner. Je vais donc juste la laisser aller comme ça. Et je vais la réparer d'une manière très grossière. Et voyez, nous avons une erreur de limite de débit. Donc, euh, je vais faire je vais juste je vais la réparer avec chat GPT en fait. Je vais donc copier ceci juste pour que vous puissiez voir ce qui est possible et comment les développeurs utilisent peut-être chat GBT pour gagner du temps. Je vais donc copier tout cela et ensuite j'irai sur GPT et ensuite je dirai euh j'ai reçu ce message d'erreur, puis je dirai s'il vous plaît, s'il vous plaît, refactorisez ce code. De sorte que si une limite de débit se produit, euh si une exception de limite de débit euh quoi que ce soit se produit, passez au modèle GP. Oups. Modèle GP. Oh mon dieu. GPT 5 mini. Est-ce le bon modèle ? Est-ce comme ça que ça s'appelle ? Laissez-moi vérifier. GBD- Oh, ce n'est même pas ici. Attendez. Je veux juste m'assurer que je dis le bon modèle. GPD-5-mini. Ok, c'est correct. GPD 5 mini. Et ensuite je montrerai le code qui est en question. Je vais appuyer sur échap pour le réduire. Et ensuite, c'est le code qui fait la requête. Ok. Et je vais coller ceci. Et ensuite, il devrait créer quelque chose avec un bloc try accept. Et s'il accepte, il devrait alimenter GPT5 mini au modèle. Je suppose qu'il va faire quelque chose comme ça. Vous savez, s'il est, eh bien, il est assez intelligent, donc je pense qu'il le fera. Il dit donc d'envelopper votre chose dans un bloc try accept. Et c'est notre code que nous essayons. Et ensuite, si nous obtenons cette erreur de limite de débit, ce qui s'est produit ici. Je ne sais pas si nous pouvons voir cela encore. Euh oh. Quoi qu'il en soit, si nous obtenons l'erreur de limite de débit, alors imprimez ceci et essayez de faire l'appel à nouveau mais en utilisant le modèle GPD5 menu. Il y a une bien meilleure façon de faire cela. C'est en fait assez grossier, mais cela fonctionnera toujours pour nos intentions et nos objectifs. Une façon plus euh quel est le mot que je cherche ? Une façon plus robuste de gérer cela serait de euh vous savez, si vous êtes limité par le débit, alors faites une logique qui collecte les modèles de notre niveau qui géreront ces jetons et les afficheront à l'utilisateur et permettront à l'utilisateur d'en choisir un qui est assez grand. Euh [renifle] mais pour nous, je voulais juste faire quelque chose de vraiment simple pour montrer que si nous sommes limités par le débit, vous pouvez passer à un meilleur modèle avec une fenêtre plus grande ou une limite de débit plus grande, et ensuite le code se poursuivra. Je vais donc copier ceci. J'ai besoin d'importer l'erreur de limite de débit, mais je peux le faire. Et ensuite, si nous remplaçons ce code ici, je pense que nous pouvons juste faire comme ça open AI. Je pense que nous pouvons Oups. Je pense que nous pouvons juste faire ça. Je pense. Oh non, peut-être qu'il doit être en minuscules. Attendez. Oh, de open AI peut-être. Peut-être que nous faisons juste ça. Ok. Désolé. Je pense qu'il doit être en minuscules. S'il est incorrect, il le fera. Oh, nous le faisons de open AI. Attendez. De open AI. Quoi qu'il en soit, je vais juste importer ceci. Je n'essaie pas de m'en occuper pour l'instant. Ok. Et ensuite, j'effacerai ceci. Ok. Ok. Donc maintenant, encore une fois, nous allons définir notre modèle. Notre modèle est réglé sur GPT5 ici. Mais la limite de débit de GPT5 est de 30 000. Donc nos journaux sont trop gros pour lui. Donc, lorsqu'il va demander à chat GBT ici, il échouera. Et ensuite, il frappera l'exception d'erreur de limite de débit. Et si cela se produit, il dira limite de débit atteinte, retour à GPD5 mini. Il réglera le modèle, le codera en dur, puis essaiera de faire la requête. Nous allons donc juste lancer ceci et voir ce qui se passe. Je veux juste vous montrer, vous savez, il est possible d'avoir un agent intelligent. Nous ferons cela à l'avenir avec notre agent. Nous le rendrons suffisamment intelligent pour faire une sélection ou une recommandation de son propre chef et peut-être obtenir l'autorisation [renifle] de l'utilisateur avant de faire la chose. Mais vous pouvez évidemment avec Agentic AI, vous pouvez juste le faire faire la chose sans demander la permission. Mais bref, c'est pour l'avenir. Donc, c'est évidemment trop de jetons pour notre limite de 30 000. Nous allons donc juste dire entrer ici. Il va essayer de faire ça. Je vais donc passer à travers cette chose comme ça et observer l'erreur. Une erreur va se produire et nous avons attrapé l'erreur spécifique. Donc vous voyez qu'il n'a pas affiché la chose rouge à l'écran. Parce qu'il a attrapé l'erreur et si nous survolons ce E, nous pouvons voir le type d'erreur. C'est ce qui se serait affiché si nous ne l'avions pas attrapé. L'erreur, la requête est trop grande pour cette organisation. Votre limite de 30k. C'est la chose que nous avons vue la dernière fois, n'est-ce pas ? Donc, au lieu d'échouer, il est allé dans ce bloc de code et il exécute tout. Limite de débit atteinte, retour à GPT5 mini. Et ensuite, il va exécuter la requête à nouveau avec le nouveau modèle comme ça. Attendez juste ça. Cool. Et en fait, ça a marché. Très bien. Nous allons juste passer à travers cette chose encore un peu, vous savez. Et vous pourriez demander pourquoi utiliser GPT5 ? Utilisez simplement GPT5 Mini. C'est juste parce que, vous savez, différents modèles ont des cas d'utilisation différents. Rappelez-vous, vous savez, GPT5 Mini, il est plus rapide, mais il a un raisonnement pire et euh quoi que ce soit. Il y a des différences entre eux. Le GPD5 Mini est beaucoup moins cher que le GPD5. Au moins l'API. Donc, cela dépend juste de votre cas d'utilisation, n'est-ce pas ? Nous allons donc laisser cette chose se terminer. Je vais juste la laisser aller jusqu'à la fin et ensuite euh cela nous a coûté, ce n'était pas bon marché. C'était 20 cents gaspillés là-dedans. Mais ce n'est pas grave. C'était beaucoup de journaux, d'ailleurs. C'est comme un livre. Nous allons donc juste laisser cela se terminer et c'est fait. Oui. J'espère que cela a du sens. Et rappelez-vous, je veux juste vous rappeler que ce ne sont pas les seuls modèles disponibles. J'utilise juste ces modèles juste pour, vous savez, pour ne pas avoir à en lister 10. Je veux juste vous montrer qu'il existe différents modèles et qu'ils ont des propriétés différentes comme des limites de débit différentes, des fenêtres différentes et tout ça. Donc, n'hésitez pas à expérimenter avec d'autres modèles. Si vous allez à l'écran, vous savez, vous pouvez toujours ajouter une autre colonne comme ça et ensuite choisir, je ne sais pas si vous pouvez utiliser toutes celles-ci, mais il y en a beaucoup que vous pouvez vérifier et vous pouvez voir les différences entre elles. comme GPT5 Nano apparemment, c'est extrêmement rapide, on dirait, et c'est aussi extrêmement bon marché. On dirait comme 5 cents par million de jetons avec une énorme fenêtre. Donc GPT5 Nano pourrait être le meilleur pour faire du codage général et des choses comme ça. Et encore une fois, avec l'agent, vous pouvez le faire par défaut sur le moins cher. Et ensuite, vous pourriez lui faire dire quelque chose comme euh voulez-vous faire une analyse avec un modèle de raisonnement plus avancé ? Et si l'utilisateur dit oui, il exécutera simplement la invite à nouveau ou quoi que ce soit avec GPD5 ou quelque chose comme ça. Pratiquement, vous pouvez littéralement faire ce que vous voulez, mais je voulais juste montrer ce que sont les limites de débit et vous aider à avoir une idée et une intuition à leur sujet. Mais oui, nous nous verrons dans la prochaine vidéo. Euh, je pense que la prochaine leçon portera sur l'optimisation des requêtes KQL pour vraiment montrer la différence entre les prix et comment cela peut affecter les prix plus vous optimisez. Nous nous verrons donc dans cette leçon. [renifle] Bienvenue. Euh, dans cette leçon, nous allons couvrir et essayer de mieux comprendre pourquoi il est vraiment important d'optimiser votre requête KQL et ensuite d'envoyer le moins de journaux possible au modèle avant de les faire analyser car spoiler, cela devient cher. Vous voulez donc vraiment optimiser cela, surtout si vous faites beaucoup de chasse et envoyez beaucoup de choses à votre modèle. Vous ne voulez pas envoyer de journaux superflus ou inutiles car oui, ce n'est tout simplement pas bon marché. De plus, ce n'est pas bon pour l'environnement non plus. Euh, mais bref, tout ce dont vous avez besoin pour cette leçon est ce fichier, ce fichier d'optimisation des requêtes KQL, et je vais le préparer, donc il correspond à ce que j'ai ici. Et ensuite, allez-y et téléchargez-le, puis mettez-le dans votre dossier, et ensuite, ouvrez votre dossier dans VS Code, et ensuite nous pouvons commencer ici. Donc, en gros, je vais juste expliquer ce que je vais parcourir ce code, mais je vais expliquer ce qu'il fait très rapidement. En gros, nous allons interroger KQL ou nous allons interroger log analytics pour certains journaux. Par exemple, comme les événements de connexion de périphérique, puis nous allons voir combien chaque requête coûtera à traiter avec chaque modèle. Comme il va parcourir tous les modèles et dire, si vous utilisez GPT5, cela coûtera tant. Et ensuite, nous allons élaguer nos journaux, optimiser notre requête, puis observer le nouveau coût et espérons-le, avoir une idée de pourquoi il est important d'optimiser nos requêtes. Donc, avant de parler trop, je vais juste entrer dans le vif du sujet, je suppose. Euh, donc je vais juste, donc tout ce qui se trouve à l'intérieur de ces longs tirets de commentaires, ce sont essentiellement nos leviers que nous pouvons actionner pour affecter le coût. Mais la plupart du temps, nous allons juste changer cela dans cette leçon, juste pour que nous puissions, je veux juste me concentrer sur l'optimisation de la requête et voir comment cela affecte le coût. Et aussi C. Et ensuite, le vôtre aura probablement ceci, mais je vais juste quitter le code. Comme je vais, il y a une boucle ici qui dit pour le modèle et les modèles et tout le reste. Je vais juste quitter le code juste avant qu'il ne dise imprimer ou appuyer sur n'importe quelle touche pour continuer car je n'ai pas nécessairement besoin de traiter de journal ou je n'ai pas besoin d'envoyer quoi que ce soit à GPT, je suppose dans cette leçon. J'essaie juste d'estimer le coût en fonction du modèle et de la taille du journal. C'est donc à peu près tout ce que nous faisons. Je vais donc voir, je vais casser le code peut-être que je vais juste, je vais le casser ici. Client OpenAI, après les définitions de fonctions, et je vais juste expliquer tout au fur et à mesure. Donc, allez-y et commencez simplement le débogage. Ensuite, nous allons passer par-dessus. Notre client OpenAI est créé, ce qui nous permet d'interagir avec GPT. Je ne pense pas que nous allons vraiment l'utiliser dans cette leçon. Et ensuite, notre client log analytics est créé. Cela nous permet d'interroger log analytics. pour définir les jetons de sortie maximum, limitant la quantité de réponses que l'API peut fournir pour limiter le coût. Ceci est la sélection actuelle du modèle. Euh, en fait, nous n'utiliserons probablement même pas cela. Nous allons passer par chaque modèle, mais je l'ai juste laissé ici. [s'éclaircit la gorge] Et puis il y a des heures, c'est pour combien d'heures nous allons interroger notre table dans Log Analytics. Et ensuite, c'est notre requête réelle. Nous allons modifier cela ou ajouter des éléments pour réduire la taille, mais nous allons passer par cela et ensuite j'utiliserai step into en fait. C'est notre requête log analytics. Elle va interroger log analytics avec notre requête qui est juste des événements de connexion de périphérique, juste la table. Je vais donc utiliser step into au lieu de step over juste pour pouvoir entrer ici et regarder. Donc, c'est là que la requête se produit. Vous auriez Oh, oui. Et au fait, si vous obtenez une erreur ici, je vais juste attendre que la mienne passe. Donc, si vous obtenez une erreur ici, vous devez ouvrir la ligne de commande. Ouvrez donc simplement, cliquez sur démarrer et tapez commande ou si vous utilisez Mac, ouvrez terminal et ensuite vous devez faire comme ez login comme ça parce que vous devez être connecté pour pouvoir interroger log analytics. Donc, cliquez sur votre compte, si vous ne l'avez pas ici, tapez-le simplement. C'est votre compte cyber range. Donc, je suis connecté et ensuite vous pouvez simplement choisir cyber range un ou deux, l'un ou l'autre, c'est automatiquement réglé sur un. Je vais donc juste appuyer sur entrée et je suis connecté. Donc, si vous obtenez une erreur ici, vous devez vous connecter et redémarrer votre code. Mais bref, je vais passer par-dessus. Et ensuite, c'est comme la table qui a été retournée par notre requête. Donc, si nous regardons les lignes de cette table, il y a 1161 lignes. Et si nous exécutons cette requête manuellement comme ça, des événements de connexion de périphérique où le temps généré est supérieur ou égal à 3 heures, nous obtenons environ 1134 lignes. Il semble qu'il y ait une légère divergence. Je ne sais pas pourquoi, mais c'est assez proche de lignes. Nous allons donc passer par-dessus. Il va compter les enregistrements. 1161. Il va faire des choses et ensuite essentiellement transformer tous ces journaux en une grande chose en texte brut que nous pouvons envoyer à GPT pour analyse. Nous ne l'enverrons pas à nouveau. Nous allons juste l'utiliser pour estimer combien coûteront les requêtes ou plutôt combien coûteront les discussions avec cette requête que nous avons faite. Donc, maintenant, cette chose a fonctionné et à l'intérieur de cette variable, il y a tous ces journaux pour les dernières 3 heures de la table des événements de connexion de périphérique, chaque champ aussi. Il a chaque colonne que vous pouvez voir. Donc, cela va créer les messages de l'invite. Il y a deux messages. Je vais réduire un peu cela. Un euh oh oui les deux messages. Le premier, c'est le message système pour le contexte. Vous êtes un chasseur de menaces. Si l'utilisateur fournit des journaux, analysez-les pour détecter une activité malveillante. Et ensuite un message utilisateur qui dit, "Voici quelques journaux." Et ensuite, nous passons cet énorme ensemble de journaux avec une interpolation de chaîne. Ce serait donc notre message que nous avons envoyé à Chappie GPT pour faire la chasse aux menaces. Et ensuite, nous allons estimer le nombre de jetons. Nous allons passer les messages, passer les messages ici, et ensuite le modèle, au lieu de normalement, nous estimerions le nombre de jetons pour tous les modèles individuellement, mais tous les modèles, je crois que nous utilisons, utilisent le même encodage. Nous pouvons donc simplement faire cela et le nombre de jetons sera le même pour tous. Donc, si nous passons par-dessus, nous obtenons le nombre estimé de jetons d'environ 350 000 journaux. Nous allons donc définir le nombre maximum de jetons utilisés en réponse à 5 000. C'est juste une variable constante que nous avons définie en haut. Et ensuite, nous entrons dans une boucle for. Et c'est une boucle. Elle va parcourir chaque modèle que nous avons dans models. Comme si nous regardons ceci, ce sont nos modèles avec lesquels nous avons affaire. C'est en haut, en haut du code. C'est un dictionnaire que nous avons créé. Il va parcourir et essentiellement calculer le coût et afficher le coût pour chaque modèle. En supposant, vous savez, que nous envoyons cela à J chat GPT. C'est combien cela coûterait pour chaque modèle. Je vais donc juste casser cela ici comme ça. Et ensuite, si vous cliquez sur continuer, cela fera tout le code et l'affichera ici en bas comme vous pouvez le voir. Donc, si nous envoyons tout cela à GPT5, cela coûtera environ 49 cents, environ un demi-dollar. C'est un peu beaucoup. Si nous appuyons sur continuer, cela fera tout et nous le montrerons pour GPT4.1, c'est environ 39 cents. Et ensuite, si nous disons étape par étape, nous pouvons voir ces choses individuelles. Nous pouvons voir le code s'exécuter ligne par ligne. Nous le voyons ici. Donc, GPT5 mini, c'est environ 9 cents. Si nous disons continuer à nouveau, GPT 4.1 nano, c'est environ 3 cents si nous envoyons tout cela. Et c'est une quantité stupéfiante de jetons aussi, d'ailleurs. Et je veux dire que si nous envoyons cela, cela va en fait échouer car même si GPT5 et GPT5 Mini ont une fenêtre de 400 000. Donc, par exemple, si nous regardons la comparaison des modèles, nous voyons comme GPD5 et 5 Mini a une fenêtre de 400 000. Mais en fait, la fenêtre ou plutôt l'entrée maximale que vous êtes autorisé à envoyer à ceux-ci est en fait comme 400K moins ceci. C'est donc comme 2772 000. Même si nous limitons la sortie maximale à 500K, j'ai appris que l'entrée maximale est en fait comme ceci moins ceci. Donc, je ne pense pas que l'un de ces modèles puisse gérer cela, sauf peut-être 4.1 nano car il a cette fenêtre absolument massive d'un million et une sortie maximale de seulement 32k. Donc, c'est juste en théorie si nous pouvions envoyer cette quantité à GPT5, c'est combien cela coûterait. Euh oui, c'est ça. Donc, si nous continuons par-dessus, j'ai mis une sortie ici. Donc le code va juste sortir comme ça. Et oui, c'est ça. Donc Oh, c'est intéressant. Cinq pour Oh, ai-je cinq modèles ? Attendez. Cinq 4.1 5 mini 4.1 Nano 5 4.1 5 mini Oh, pourquoi a-t-il dit deux cinq minis ? Oh, c'est comme Oh, quelque chose ne va pas avec ça. Je ne sais pas ce qui s'est passé avec ça. Quoi ? Quelque chose ne va pas avec mon Donc, je vais effacer ça. Quelque chose ne va pas avec ça. Je vais juste euh le relancer une fois de plus. En fait, laissez-moi supprimer ce terminal et en ouvrir un nouveau. Et je vais juste le lancer sans débogage juste pour qu'il puisse aller jusqu'au bout. Et puis parce que je veux avoir la chose la sortie à l'écran pour pouvoir la comparer après avoir réduit un peu les journaux. Et puis qui que ce soit qui édite cela, ils peuvent supprimer cette chose où j'étais juste en train de regarder ces choses beaucoup. Donc voici notre sortie euh GBD5 4.1 5 mini nano. Et vous pouvez voir que le nombre de jetons est le même bien sûr, mais le prix est assez différent. C'est comme 10 fois plus que ça. C'est donc avec nos journaux. Et rappelez-vous euh en fait, laissez-moi aller à notre c'est c'est notre requête KQL. J'ai juste interrogé directement les événements de connexion de périphérique. Je ne l'ai pas filtré du tout. Donc, si nous allons à notre log analytics, nous pouvons en fait utiliser notre cerveau pour comprendre quels journaux sont les plus importants pour notre chasse aux menaces. Et si vous vous demandez comment je sais quels journaux sont plus importants. Je vous recommande d'aller suivre le cours sur les opérations de sécurité et la chasse aux menaces. nous plongeons vraiment assez profondément là-dedans, mais j'expliquerai les choses au fur et à mesure. Donc, en gros, comme les choses sont maintenant, par exemple, si nous disons obtenir le schéma et exécuter cette requête, nous pouvons voir qu'il y a, en commençant par zéro, un total de 54 champs ici que nous envoyons à GPT. Et c'est beaucoup. Nous calculons les jetons sur 54 champs au total. Et nous n'avons pas besoin de tout cela pour faire une chasse aux menaces appropriée car beaucoup d'informations sont essentiellement inutiles. Donc, nous allons utiliser le mot-clé project pour sélectionner uniquement les champs que nous jugeons importants. Donc, par exemple, le temps généré, c'est évidemment important car vous en avez besoin pour obtenir une chronologie de ce qui s'est passé. C'est essentiellement inutile si le journal n'a pas d'heure car il aurait pu se produire il y a 10 ans, ce n'est pas utile. Et puis le domaine du compte. Il est discutable de savoir si c'est utile. Je crois que c'est la même chose que le nom de l'appareil. Je ne suis pas sûr pour être honnête. Et cela pourrait valoir la peine de jeter le schéma ou les champs dans GPT et de demander, expliquez-moi ce que tout cela signifie. Parce que je ne sais pas quelle est la différence entre le domaine du compte et le nom de l'appareil. Cela me semble pareil. Donc, je vais m'abstenir d'utiliser le domaine du compte et ensuite le nom du compte. C'est probablement important car c'est la table des événements de connexion de périphérique, n'est-ce pas ? Donc, c'est quand quelqu'un essaie de se connecter à un serveur ou à une machine virtuelle, un journal est créé. Donc, le nom du compte, nous voulons voir avec quoi ils se connectent. Le SID du compte, c'est important dans la vraie vie. Il est important de savoir quand vous trouvez quelque chose qui a pu être compromis et si vous avez de l'argent gratuit, c'est quelque chose que vous incluriez, mais je ne l'inclurai pas car le champ est assez long et c'est un laboratoire, donc je ne l'inclurai pas. Le SID est comme euh je ne sais pas comment l'expliquer. C'est comme l'identifiant unique d'un compte. Donc, vous pouvez avoir deux comptes nommés comme rap ra ra ra ra ra ra ra ra ra ra ra ra ra ra ra ra ra ra ra ra rack p p p p p p p p p p p p p p p p p p p p pan par exemple, mais ils pourraient avoir un SID différent et cela indiquerait qu'il s'agit d'un compte différent. C'est ma compréhension. Je vais donc exclure cela. Je vais inclure le type d'action car c'est vraiment important, que le compte ait pu se connecter ou non en tant que quelqu'un qui a pu se connecter, je suppose. Champs supplémentaires, je ne vais pas inclure cela. Je ne vais pas inclure l'ID de l'appareil car c'est la même chose. C'est comme l'identifiant unique de l'appareil. Il pourrait y avoir deux appareils nommés ainsi, mais s'ils ont un ID différent, vous pouvez supposer qu'il s'agit de deux choses différentes. Raison de l'échec. Je ne suis pas euh ce serait bien d'inclure, mais vous savez, il semble qu'il y ait beaucoup de nuls ici, donc peut-être que je ne vais pas l'inclure. Qu'avons-nous d'autre ? Il y a beaucoup de choses ici que nous pourrions inclure, n'est-ce pas ? IP distante. C'est probablement utile. Cela fournira beaucoup de contexte car l'IP distante comme 10008 à l'intérieur du cyber range, c'est en fait le moteur de scan, le moteur de scan tenable, le port distant, ce serait probablement utile dans la vraie vie, mais je ne vais pas l'inclure. Je vais juste inclure les choses les plus basiques pour que nous puissions avoir une idée, donc le temps généré, le nom du compte, le type d'action et l'IP distante, ce serait suffisant pour nos intentions et nos objectifs. Je vais donc lancer ceci et ensuite nous pourrons le voir. C'est un journal vraiment vraiment allégé. Donc, comme le temps généré, le nom du compte, le type d'action, puis l'IP distante. Et nous devrions probablement inclure plus que cela dans la vraie vie. Mais c'est suffisant pour un laboratoire juste pour montrer la différence de taille des journaux si nous allégeons et optimisons notre requête. Je vais donc copier ceci comme ça. J'irai ici et ensuite c'est notre c'est notre requête. Je vais donc juste coller ceci ici comme ça. Et vous vous souvenez que nous euh je n'inclurai pas cela en fait parce que nous le faisons ici et qu'il est géré par le module log analytics d'une manière différente. Je vais donc juste inclure les projets ici et ensuite je vais le lancer une fois de plus et ensuite si vous voulez le déboguer, vous pouvez casser votre code quelque part. Je suppose que je vais le casser ici et ensuite je vais juste le déboguer. Oh, en fait, non, non, non. Je veux observer les enregistrements retournés en premier. Je vais donc le casser juste avant que la requête ne se produise. Donc, si vous vous souvenez ici, lorsque nous exécutons cela pendant les 3 dernières heures, nous obtenons environ 1300 journaux. Donc, si nous allons à notre code, nous allons entrer dans cette fonction et ensuite nous allons entrer dans ce espace de travail log analytics est en cours d'interrogation. La requête est terminée. Donc, si je passe par-dessus et que je vois ce nombre d'enregistrements. C'est 1357. C'est assez proche. Oh, c'est exactement la même chose en fait. Donc, c'est maintenant exactement la même chose. Je pense que nous l'avons fait dans un laps de temps suffisamment proche. Donc, il va créer un gros déversement de texte brut avec nos journaux comme ça. Et il le retournera. Donc, à l'intérieur de cette variable de journaux, ce sont tous les journaux. Et ensuite, encore une fois, il va construire notre message système qui est comme, vous savez, donner le contexte du modèle, puis notre message utilisateur qui est la commande voici quelques journaux, les déverse dans une interpolation de chaîne, puis c'est important. Il va estimer le nombre de jetons de l'invite. Et vous voyez déjà, il est devenu 46 000, passant de 390 000. C'est probablement environ, qu'est-ce que c'est, un facteur de huit ou quelque chose comme ça. Il est environ huit fois plus petit. Donc, si nous passons par-dessus cela et que je supprime ce point d'arrêt, je vais juste le laisser fonctionner et nous pourrons voir la différence de coût. Précédemment, nous pouvons voir que la ligne de commande devient vraiment désordonnée pour être honnête. Je ne suis pas sûr pourquoi cela se produit, mais vous pouvez voir que GPD5 coûte environ 53 cents pour traiter 390 000 jetons, mais après l'optimisation de notre requête, GPD5 coûte maintenant environ 10 cents pour traiter 46 000 jetons. C'est assez significatif. Ensuite, GPT5 mini 2 cents. GPT4 41 nano moins d'un cent. C'est un peu plus de la moitié d'un cent. Et c'est pourquoi il est vraiment important d'optimiser vos journaux car nous obtenons la même quantité de journaux, mais nous avons simplement supprimé beaucoup de filtres qui ne nous intéressaient pas. Et il est bon d'avoir plus de contexte que vous pouvez fournir au modèle, mieux c'est car il peut mieux chasser les menaces. Donc, par exemple, si vous savez qu'il y a deux ordinateurs nommés Oh, je n'ai pas inclus le nom de l'appareil ici. C'est un Eh bien, j'aurais probablement dû le faire. Nom de l'appareil. J'aurais probablement dû le faire. Mais par exemple, si vous avez deux appareils qui ont le même nom, mais que l'ID de l'appareil est différent, par exemple. Cela fournit des informations précieuses sur la chasse aux menaces, n'est-ce pas ? Parce que vous pourriez remarquer que si vous alimentez le modèle un tas de journaux et qu'il y a deux appareils qui ont le même nom d'appareil, le modèle n'a aucun contexte qu'ils pourraient potentiellement être des appareils différents, n'est-ce pas ? Donc, il est logique de pouvoir inclure l'ID de l'appareil, n'est-ce pas ? Il faut juste en tenir compte en termes de coût. Par exemple, je vais exécuter cette requête où j'inclus l'appareil, peut-être oui, le nom de l'appareil et l'ID de l'appareil. Je vais copier ceci. Je vais copier cette chose de projet. Oh, désolé. Et au fait, si vous sélectionnez une chose et que vous dites exécuter, cela n'exécutera que cette chose et cela produira une erreur. Comme si seulement cette ligne, si je l'exécute, elle produit une erreur, n'est-ce pas ? Mais si vous sélectionnez tout et exécutez, cela fera la requête. Je vais donc copier tout ce bloc et j'irai ici et ensuite je me demande si je peux Je vais appuyer sur Windows Shift et prendre une capture d'écran de ceci. Je pense qu'elle est allée sur le bureau mais ok. Oh. Copier dans le presse-papiers. Ok, je voulais juste garder cela ouvert car cela les perturbe. Quoi ? Pour une raison quelconque, cela perturbe la ligne de commande. Donc, j'ai mon nouveau filtre. Je vais donc le mettre ici, mec. Attendez. Laissez-moi essayer de faire ça à nouveau. Je vais essayer de copier ceci et ensuite j'ajouterai quelques champs ici. J'ajouterai le nom de l'appareil et l'ID de l'appareil. Et vous savez, techniquement, il serait probablement prudent d'ajouter également l'ID du compte. Je ne vais pas faire ça. Mais je vais juste tout exécuter sans débogage. Et ensuite, oui, je vais juste l'exécuter. Je vais juste l'exécuter. Et vous remarquez les nouveaux jetons d'entrée, le précédent, laissez-moi voir le précédent estimé, les jetons d'entrée étaient de 46 000 et ensuite l'ajout de l'ID de l'appareil et du nom de l'appareil a essentiellement doublé, il a doublé le nombre de jetons et a presque doublé le coût également. C'est donc quelque chose à considérer, n'est-ce pas ? Donc, si nous ne voulons pas utiliser l'ID de l'appareil, disons que nous voulons juste faire une chasse de base ou quelque chose comme ça et que nous ne voulons pas être si extra, vous savez, nous voulons juste avoir une chasse de base juste pour le bien de notre laboratoire. Je vais juste supprimer l'ID de l'appareil d'ici. Cela réduira les jetons d'une quantité substantielle. Laissez-moi donc en fait copier ceci aussi. Donc, commande Shift S, obtenez ceci. C'est donc avec l'ID de l'appareil et j'ai supprimé l'ID de l'appareil. Nous verrons donc combien cela coûte sans cela. Je vais donc lancer ceci et je vais euh je vais juste lancer sans débogage. Nous avons une bonne idée de la façon dont ce code fonctionne. Et ensuite, après avoir supprimé l'ID de l'appareil, qu'avons-nous ? Précédemment avec GPT5, c'était 17 cents. La suppression de l'ID de l'appareil l'a réduit de 4 cents. C'est assez substantiel, 4 cents, car si vous faites cela assez souvent, cela s'accumule vraiment. 1 cent, c'est beaucoup dans ce contexte. Et puis GPT 4.1 nano, précédemment, c'était environ 1,2 cent, il est descendu à environ 8 cents. Donc, c'est comme, qu'est-ce que c'est ? Ce n'est pas moins de la moitié, mais c'est assez proche, mais c'est assez substantiel. C'est une quantité décente d'argent, n'est-ce pas ? Surtout si vous faites cela encore et encore. Et c'est ce que je considérerais comme le minimum d'importance pour les événements de connexion de périphérique. Donc, faisons juste quelques requêtes de plus. Je vais en faire quelques autres avec une table différente. Donc, au lieu des événements de connexion de périphérique, regardons les tables dont nous disposons. Security Center gratuit. Je ne sais pas ce qu'il y a dedans. Alerte de sécurité. Ligne de base de sécurité. Sécurité. Vous pouvez littéralement choisir n'importe quoi. N'importe quoi que vous voulez. Je vais juste voir ce qu'il y a ici. [s'éclaircit la gorge] Euh, ok. Événements de processus de périphérique, c'est un très gros. Je sais que je l'utilise beaucoup. Vous n'avez pas à l'utiliser, mais c'est vraiment significatif. Donc, événements de processus de périphérique, je vais dire, vous savez, où le temps généré est supérieur ou égal à, je vais juste faire 3 heures à nouveau, nous verrons, désolé. Je vais donc lancer ceci tel quel, schéma complet. Donc, je vais prendre ces événements de processus de périphérique comme ça. Oh, et au fait, au fait, nous le faisons pour les 3 dernières heures seulement, n'est-ce pas ? Et cela augmente considérablement. Vous pouvez imaginer si nous faisons les dernières 24 heures ou quelque chose comme ça. Donc, je vais faire les dernières 24 heures. C'est toujours des événements de connexion de périphérique pour les dernières 24 heures. Et vous savez, en gros, quand vous définissez le projet, quand vous filtrez, quand vous filtrez les champs, vous rendez essentiellement le journal vraiment mince. Mais si vous réduisez le temps, vous rendez le journal vraiment vraiment [s'éclaircit la gorge] court. Et en l'augmentant de 3 à 24, nous augmentons la longueur du journal, je suppose, ou la taille. C'est vraiment très grand. Il y a plus d'enregistrements. Mais il y a moins d'enregistrements dans le sens où nous les avons beaucoup filtrés. Donc, au cours des dernières 24 heures, cela a coûté, vous savez, de 13 cents à 5252 cents. [s'éclaircit la gorge] C'est donc significatif et c'est quelque chose à garder à l'esprit. Mais bref, je vais rechercher les événements de processus de périphérique, tous pour les dernières 3 heures comme ça. et il a retourné 12 000 enregistrements. Et je vais copier ces événements de processus de périphérique. Et si nous disons obtenir le schéma, par exemple, obtenir le schéma. Nous pouvons voir combien de champs ou combien de lignes il y a ici. Et il y en a beaucoup, de 0 à 72. Cela signifie donc 73 lignes au total ici. Donc, [renifle] nous allons revenir à notre code et nous allons dire il y a des heures. Nous allons dire 3 heures. Et ensuite, nous allons supprimer tous ces filtres. Et ensuite, je vais passer les événements de processus de périphérique ici. Et nous allons juste lancer cela sans débogage pour avoir une idée. Rappelez-vous, nous ne filtrons pas cela. Nous allons obtenir les 70 champs pour les 3 dernières heures. Et cela va [renifle] être beaucoup car il y a pas mal de choses ici. La taille du journal est généralement assez grande. Et je vous montrerai dans une seconde pourquoi. En fait, je vais aller ici et vous montrer. Je vais donc réduire un peu cela. Je vais réduire cela. Et nous pouvons voir que nous pouvons faire cela et cela se développe essentiellement. Nous pouvons faire défiler vers la droite pour toujours, n'est-ce pas ? C'est vraiment long. Ou nous pouvons développer l'un de ceux-ci et nous pouvons le voir en ligne comme ça. C'est plus logique et plus facile à regarder. Nous pouvons donc voir que nous avons l'ID du locataire, le domaine du compte, le nom du compte. Oh, au fait, cette table, ces événements de processus de périphérique, c'est quand quelqu'un ouvre un fichier sur sa machine virtuelle ou exécute un programme ou quelque chose comme PowerShell ou une commande en ligne, une commande s'exécute ou quelque chose comme ça, un processus démarre essentiellement, n'est-ce pas ? Donc, en fait, je vais regarder l'un de ceux qui est sous Windows car cela pourrait être plus familier aux gens. Donc, si nous choisissons l'un de ceux où laissez-moi voir le nom du compte n'est pas root, je suppose, ou le nom du compte est NT authority ou système. Je vais juste regarder l'un de ceux-ci et nous pouvons voir les choses qui sont ici comme le domaine du compte, le nom du compte, le SID du compte, le type d'action, l'ID de l'appareil et il y a beaucoup de choses, n'est-ce pas ? Donc, les choses les plus importantes pour cela, je vais les parcourir un peu. Mais pour l'instant, regardons ce qui s'est passé ici. C'est absurde, n'est-ce pas ? Qu'est-ce que je ne sais même pas combien d'enregistrements c'est ou combien de jetons. C'est 13 100 000 jetons. Il n'y a aucun modèle qui puisse même traiter cela, n'est-ce pas ? Ce n'est pas possible. Le plus grand modèle, je pense qu'il peut traiter environ un million de jetons, ce qui est je pense 4.1 nano. Mais bref, théoriquement, si nous pouvions traiter tout cela par GPT5, cela coûterait 16 dollars pour le faire et 13 dollars, 3 dollars. Un dollar, c'est beaucoup pour une seule requête. C'est une quantité d'argent importante. Donc, pour la chasse aux menaces, je recommanderais [s'éclaircit la gorge] de réduire la taille du journal, vous savez, parce que peut-être que vous voulez regarder dans les 3 heures, n'est-ce pas ? Vous devez réduire la quantité de champs que vous inspectez réellement avec le journal. Donc, par exemple, voyons ce qui est important. Nous pouvons simplement faire la distinction ou faire la vous savez, décider de ce qui est important par nous-mêmes où nous projetterions l'ID du locataire n'est probablement pas important pour nous car il sera littéralement le même pour chaque ordinateur, sauf si nous avons plusieurs locataires. Le domaine du compte pourrait être important, mais peut-être que le nom de l'appareil est probablement plus pertinent. Mais le nom du compte est important. Donc, nous allons projeter certainement le moment où cela s'est produit. C'est important. Et puis le nom du compte est important. C'est le compte qui a lancé le processus. Le nom de l'appareil est vraiment important car nous devons savoir sur quel appareil cela s'est produit. Et le nom du fichier. Je crois que c'est le fichier qui a été exécuté, je suppose, ou celui qui a exécuté. Je ne me souviens pas, encore une fois, c'est une très bonne utilisation de chat GPT pour comprendre exactement ce que font tous ces champs. La taille du fichier, c'est le nom du ou la taille du fichier qui a été exécuté, je suppose. Donc, au lieu d'obtenir le nom du fichier, cela pourrait être important, mais l'initiateur, il y a un champ appelé la ligne de commande du processus initiateur et je crois que c'est potentiellement plus important. Je pense. Oh, peut-être pas. Donc, peut-être que nous devons obtenir le nom du fichier et ensuite la ligne de commande du processus initiateur est probablement importante. Et puis il y en a un autre dont je me souviens, le nom du fichier du processus initiateur. Qu'est-ce d'autre serait important ou pertinent pour une chasse aux menaces. Et parfois, certains champs sont vides dans [renifle] certains journaux. Donc, regardons juste ces choses et je suis juste, au fait, si vous faites une chasse aux menaces appropriée et que vous définissez légitimement le schéma et ce que vous voulez utiliser et envoyer au modèle, vous ferez plus de recherches que cela car vous savez, Shaw, tout cela est important, Shaw, l'empreinte digitale de la chose, toutes ces choses sont importantes, mais vous devez considérer que cela deviendra assez cher si vous commencez à envoyer des grilles ou des identifiants comme ceux-ci au modèle. Cela deviendra vraiment cher si vous avez beaucoup de journaux. Donc, c'est probablement suffisant [s'éclaircit la gorge] pour l'instant pour nos intentions et nos objectifs, car vous voyez à quel point le journal est grand. Laissez-moi regarder quelque chose. Ok. Ok. Donc, pour l'instant, je vais juste utiliser ces champs juste pour garder le journal d'une taille raisonnable. Je vais donc prendre ceux-ci. Je vais revenir ici et ensuite je suppose que je vais en prendre une photo. Je sais que cette leçon devient un peu longue, mais je veux juste aider à construire une intuition pour les choses. Nous allons donc ouvrir ceci juste pour avoir quelque chose à comparer. Je ne sais pas pourquoi c'est comme ça. Pourquoi fais-tu ça ? Et ensuite, nous irons aux événements de processus de périphérique et ensuite nous allons euh j'oublie si j'ai copié le projet. Oh, le Ok, nous allons copier ceci, le projeter pour les 3 dernières heures, et ensuite je vais juste le lancer sans débogage et nous verrons car rappelez-vous sans rien élaguer, nous avons juste obtenu tous les champs pour les 3 dernières heures, 16 dollars. Nous ne pouvons évidemment pas interroger autant car il y a trop de jetons, mais bref. Mais maintenant, il a pu réduire considérablement. C'est seulement comme, au lieu de 16 dollars, c'est toujours comme 19 dollars. C'est beaucoup pour une seule requête. Et c'est trop de jetons pour que n'importe quel modèle puisse les traiter. C'est comme 1,5 million de jetons. Donc, pour quelque chose comme les événements de processus de périphérique, ce n'est pas vraiment quelque chose que vous feriez pour tous les ordinateurs de votre environnement car rappelez-vous que le cyber range a environ 400 ordinateurs ici et je ne sais pas combien d'entre eux sont intégrés à defender for endpoint. Cela dépend juste de combien d'utilisateurs le font, mais c'est plus quelque chose que vous ciblerez un ordinateur individuel. Comme je ne ciblerais pas toute la table. Je vais donc la filtrer encore plus. Par exemple, peut-être où le nom de l'appareil est égal à peut-être ce gars, l'appareil de cette personne stmm. C'est l'appareil de quelqu'un, je ne sais pas à qui il appartient. Je vais juste le lancer ici et voir. Et il y a beaucoup moins de journaux. Il y a 105 journaux pour les 3 dernières heures. Vous pouvez probablement faire euh vous pouvez en choisir un vous-même ou vous pouvez probablement obtenir un cible Windows si vous suivez. 116 cibles Windows. C'est comme le pot de miel de Cybrains, je suppose. Je vais juste utiliser celui de cette personne. Oups. Je vais donc prendre les deux filtres. Je vais juste copier comme ça. Et j'irai ici. Et ensuite, je vais remplacer ceci comme ça. Donc, nous pouvons filtrer la requête par nom d'appareil et par nos champs. Je vais donc juste lancer ceci sans débogage. Peut-être que je vais en prendre une photo si cela me le permet. Cool. Donc, ok. [renifle] Donc, rappelez-vous, nous avons interrogé les 3 dernières heures avec l'appareil euh qu'est-ce que c'est les événements de processus de périphérique pour tous les ordinateurs. Nous avons fini par obtenir encore 1,5 million de jetons d'enregistrements. Mais maintenant [renifle] nous avons filtré, nous l'avons filtré pour regarder la machine virtuelle d'un utilisateur spécifique et maintenant c'est beaucoup plus raisonnable. C'est seulement comme 850 enregistrements, n'est-ce pas ? Désolé, je veux dire 8 520 enregistrements et c'est toujours comme, 6 cents, c'est une somme décente pour une seule requête, mais c'est beaucoup mieux que 2 dollars, n'est-ce pas ? C'est comme 40 fois moins essentiellement. Probablement comme 35 fois.

moins. Attendez, laissez-moi Je suis Je suis curieux de savoir à quel point je suis précis avec ceux-là. Alors, qu'est-ce que c'est ? 0. Je pense que c'est environ 37 fois moins * 37. Oh, c'est légèrement moins que ça. C'est probablement comme, vous savez, 33 fois moins ou quelque chose comme ça. Mais bref, c'est c'est beaucoup moins. Bien sûr, vous avez moins de contexte. vous vous concentrez sur une seule machine virtuelle, mais quand même, c'est juste important de savoir que ça dépend de ce que vous voulez faire et de ce qui est même possible avec le modèle, n'est-ce pas ? Donc, j'espère que cela vous donne une idée de pourquoi il est important d'optimiser vos journaux non seulement pour la période pendant laquelle vous interrogez. Nous avons fait principalement 3 heures ici. Mais aussi les champs que vous envoyez au modèle, car même en ajoutant un champ, cela va augmenter considérablement la taille du journal ou la taille du jeton. Donc, par exemple [renifle] cette ligne de commande de processus d'initialisation est bien sûr intégrale à la chasse aux menaces dans le champ des événements de processus de l'appareil car je vais vous montrer qu'elle contient ce qui a été exécuté essentiellement. C'est vraiment important. Mais je veux juste vous montrer que même en ajoutant ceci, cela représente une quantité substantielle de jetons. Donc, si je supprime ceci et que j'exécute ceci sans débogage, GBD5 coûtait environ 6 cents et ceci coûte environ 2 cents. Si nous supprimons simplement ce champ, oh, c'est toujours une quantité décente. Je suppose que cela n'a réduit que d'un cent. Je m'attendais à ce que cela réduise beaucoup plus, car ce champ est assez grand, n'est-ce pas ? Mais bref, oui, vous pouvez voir que cela a du sens, ajouter ou supprimer un champ fait une grande différence. Oh, je suppose que c'est seulement un peu moins parce que les journaux, la quantité de journaux n'est pas si importante car nous ne ciblons qu'un seul ordinateur. Mais bref, j'espère que cela a du sens. Je vous encourage Oops. Qu'est-ce que j'ai fait ? Je vous encourage à jouer un peu plus avec ça parce que rappelez-vous qu'il y a beaucoup, il y a une tonne de tables différentes. Nous avons juste eu la chance d'en utiliser quelques-unes sélectionnées dans notre chasse aux menaces, mais il y en a littéralement beaucoup. Donc, je pourrais expérimenter avec elles ici dans Log Analytics et je pourrais expérimenter avec elles ici et voir combien cela coûte pour différentes périodes et différents journaux projetés ou différents champs projetés. Mais oui, c'est une leçon sur l'optimisation de vos requêtes KQL et pourquoi c'est important et comment cela peut affecter les coûts à long terme. Alors imaginez simplement mettre cela à l'échelle de centaines par jour. Évidemment, vous voudriez dépenser un centime [renifle] au lieu de cinq centimes et demi, n'est-ce pas ? C'est substantiel. Plus vous le faites, plus cela peut coûter cher. Mais j'espère que cela a du sens. Comme toujours, posez des questions sur le forum si vous êtes bloqué ou si quelque chose n'a pas de sens et taguez-moi. Sinon, nous nous verrons dans la prochaine vidéo, qui sera probablement le début où nous commencerons à créer notre agent d'IA de cybersécurité réel. Alors, réjouissez-vous de cela et nous vous verrons bientôt. Bienvenue et bienvenue dans la première section où nous allons commencer à construire notre agent d'IA. Et pratiquement tout ce que nous avons fait jusqu'à présent sera utilisé d'une manière ou d'une autre dans les leçons suivantes. Je veux aussi dire que ne vous découragez pas. Parce que ce que nous faisons est assez difficile, surtout si vous n'avez jamais fait de programmation auparavant. Vous n'êtes pas habitué à Python. Alors ne vous découragez pas. Cela demande juste beaucoup de répétition et peut-être quelques conversations avec chat GBT, puis l'utilisation de la communauté pour mieux comprendre tout cela. Alors, ne vous découragez pas et n'essayez pas d'avoir l'état d'esprit où vous vous dites oh, je n'ai pas produit ce code, donc je dois atteindre le niveau où j'ai besoin de le produire. Je veux dire, si vous voulez pouvoir faire ça, c'est bien. Mais mon intention est de vous amener au niveau où vous êtes capable d'interpréter le code et de comprendre ce qui se passe et de comprendre ce qu'il fait. Si vous voulez pouvoir produire du code, c'est bien. Mais ce n'est pas mon intention avec ceci. Et je ne veux pas que les gens s'attardent trop sur cela. Nous essayons juste d'avoir une bonne compréhension de ce qui se passe et de comprendre le flux de travail d'un agent de cybersécurité IA et de comprendre comment utiliser les API et comment utiliser les LLM et juste comprendre tout cela au lieu d'essayer de devenir un ingénieur logiciel à part entière ou quelque chose comme ça. Alors, essayez simplement de vous concentrer sur la compréhension et si vous êtes bloqué, demandez à la communauté et n'hésitez pas à me taguer si vous le souhaitez. Et je veux aussi dire que cela vaut vraiment la peine de revenir en arrière et de faire les sections précédentes, comme même les bases de Python, puis les éléments constitutifs, c'est sûr. Comme si vous parcourez cette section et que vous revenez et regardez à nouveau la section des éléments constitutifs, cela aura beaucoup plus de sens et vous aurez beaucoup plus de contexte sur ce que nous faisons dans cette section, puis vous pourrez regarder à nouveau cette section. Je pense que tout cela aidera beaucoup. Mais oui, ne vous découragez pas. Essayez simplement de vous concentrer sur la compréhension, de vous concentrer sur le débogage et de faire attention à ce que fait le code, puis utilisez-nous tous comme ressources. Et oui, nous nous verrons dans la prochaine vidéo. Alors, avant de vraiment commencer, je voulais parcourir ce diagramme très rapidement juste pour vous montrer à un niveau élevé ce que fait l'agent. Vous n'avez pas besoin de suivre. Vous pouvez simplement vous détendre et regarder. Nous allons entrer dans les choses et faire le travail pratique dans la prochaine vidéo. Mais en gros, je voulais juste montrer un flux de haut niveau. Donc, lorsque vous exécutez l'agent ou que vous exécutez le programme, notre agent de base demandera d'abord à l'utilisateur ce qu'il veut faire, ce qui est indiqué par cette boîte, et ensuite les boîtes jaunes indiquent une sorte d'interaction de l'utilisateur. Donc, l'utilisateur répondra avec ce qu'il veut faire. Je vais juste coller ceci. Et ensuite, la prochaine chose que l'agent va regarder est ce que l'utilisateur a mis et essayer d'en dériver les zones correctes à rechercher et ensuite les métadonnées appropriées pour accompagner leur demande. Donc, par exemple, nous pouvons passer outre ceci. Il décidera où chercher, est-ce dans la table des journaux d'audit ou le journal de l'appareil sur les événements de processus de l'appareil, où devons-nous chercher pour comprendre ce qui inquiète l'utilisateur, puis une fois qu'il l'aura trouvé, il affichera les tables dans lesquelles il va chercher ainsi que la justification. Donc, si nous passons outre ceci, il l'a trouvé. Il va donc afficher les tables. Donc, les journaux de connexion 48 heures dans ces champs, puis la justification pour l'activité suspecte au niveau du locataire signalée par l'utilisateur. J'ai donc décidé de regarder dans les journaux de connexion, etc. Nous validerons les champs. Nous passerons outre ceci, les champs et les tables sont validés. Et ensuite, il va interroger Log Analytics et collecter les journaux. C'est ce que cela fait. Donc, la requête est exécutée contre Log Analytics. La requête est terminée. Environ 1 900 enregistrements ont été retournés. Et ensuite, il va construire l'invite à envoyer au point de terminaison de l'API de GPT, ce qui est ce sur quoi nous allons baser la chasse aux menaces. L'invite est l'invite initiale de l'utilisateur, ce qui l'inquiétait, des informations sur la façon de chasser les menaces dans ces tables spécifiques, qu'il va obtenir ici, puis il va ajouter ces 1 800 journaux à la toute fin. Donc, ce que nous voulons, comment chasser les menaces, puis le contexte pour savoir où chercher. C'est ce qui se passe maintenant. Et ensuite, l'invite système de chasse aux menaces est construite. Cela donne à GPT plus de contexte sur ce qu'il est censé faire et comment il est censé se comporter. Donc, l'invite système de chasse aux menaces est construite. Les messages sont assemblés. Combiner les invites utilisateur et système pour calculer les jetons et estimer le coût. Donc, il va combiner ces deux messages, puis il va compter les jetons. Je ne pense pas l'avoir mis ici. Mais il compte essentiellement la longueur du message et ensuite il va permettre à l'utilisateur de choisir un modèle approprié, puis de valider le modèle par la suite. Donc, si nous passons outre ceci, c'est un peu difficile à voir. Je vais l'agrandir un peu. Vous pouvez voir qu'il nous donne un tas d'options différentes pour les modèles. Et ensuite, c'est notre modèle actuel, le modèle par défaut. Nous pouvons choisir un modèle différent ou continuer avec celui-ci. J'appuierai juste sur Entrée pour continuer avec ce modèle. Nous allons valider le modèle. Le modèle est valide. Et ensuite, la prochaine chose qu'il va exécuter la chasse. Donc, il va noter l'heure de début pour voir combien de temps prend la chasse. Et ensuite, c'est là que la chasse s'exécute ici. Donc, la chasse aux menaces est exécutée par GPT5 Mini. Mais, curieusement, oh, c'est tellement drôle. Les jetons, l'estimation des jetons était très proche du maximum pour le modèle. En fait, c'était probablement légèrement supérieur. Comme vous pouvez le voir, il était dépassé de 3 000 jetons. Donc, normalement, la chasse aurait eu lieu ici, [rire] mais il y avait trop de jetons, notre demande était trop importante. Donc, normalement, les résultats auraient été affichés à l'utilisateur juste ici, puis le programme se serait terminé, puis des choses futures pour chaque résultat, envisager de prendre une sorte d'action de remédiation. Par exemple, si le modèle ou la chasse déterminait qu'il y avait une compromission avec une confiance élevée, nous exécuterions une sorte d'action contre elle. Mais c'est tout. Je voulais juste vous donner un aperçu de la façon dont cet agent chasse dans un contexte graphique, côte à côte. Je mettrai donc un lien vers ceci ci-dessous dans cette vidéo ainsi que dans la prochaine vidéo, afin que vous puissiez l'utiliser si cela vous aide pendant que vous observez l'exécution du programme. Et je vais le laisser ici. C'est juste une chose vraiment intéressante car l'estimation n'est pas exacte. C'est assez proche. Mais ce n'est pas exact. Notre estimation était de, vous savez, 269K, mais en réalité, le nombre de jetons était de 273K, ce qui est juste au-dessus. C'était donc vraiment intéressant. Je vais donc le laisser là. Mais oui, nous nous verrons dans la prochaine leçon. Bienvenue. Dans cette leçon, nous allons plonger directement dans les choses et commencer à faire des choses avec le code. Voici comment cela va fonctionner : j'ai déjà créé un agent de base qui fait des choses de chasse aux menaces. Il lui manque beaucoup de fonctionnalités et quelques choses ne vont pas. Mais il fonctionne et fait des choses génériques assez bien. Mais nous allons nous plonger dans cela. Nous allons voir comment cela fonctionne dans cette leçon. Et ensuite, dans la prochaine leçon, nous parlerons des choses qui ne vont pas et de ce qui manque. Et ensuite, dans les leçons suivantes, nous ferons une analyse approfondie des composants individuels pour nous assurer que nous comprenons vraiment comment cela fonctionne. Et ensuite, nous commencerons à ajouter des fonctionnalités. C'est comme une véritable chose agentique où il effectue réellement une sorte de remédiation. Alors, téléchargez ceci. Je mettrai un lien ci-dessous. C'est un fichier zip. Donc, si vous double-cliquez dessus, il y aura un autre dossier à l'intérieur appelé baseline agent ou il s'extraira si vous utilisez Mac. Je vais donc le mettre sur mon bureau comme ceci. Comme ceci. Et ensuite, j'ouvrirai VS Code. Alors, allez-y et ouvrez VS Code. Quiconque édite peut couper ça. Alors, si vous avez déjà un dossier ouvert, fermez-le en cliquant sur "Close Folder" ici. Mais nous allons aller dans "File" puis "Open Folder". Et ensuite, nous allons ouvrir le dossier que nous venons de mettre sur notre bureau ou où que vous ayez décidé de le mettre. C'est le baseline agent. Nous allons donc sélectionner ceci. Et il y a beaucoup de choses ici. Nous en parlerons éventuellement. Mais la première chose que nous devons faire, si vous allez dans "keys", vous devez y mettre votre propre clé OpenAI. Alors, allez-y et faites un contrôle-clic ici. J'ai mis un lien ici pour votre commodité. Et ensuite, vous pouvez simplement créer une nouvelle clé si vous en avez besoin, ou coller votre clé si vous vous en souvenez. J'ai donc juste créé cette clé. Je vais donc l'utiliser. Je vais donc la coller. Et assurez-vous qu'il n'y a pas d'erreur de syntaxe et qu'elle est correcte. Et ensuite, [renifle] la prochaine chose que nous devons faire est, si vous allez dans "model management" et ensuite sous "current tier", vous pouvez probablement laisser cela à un, mais si vous savez que vous êtes dans un niveau supérieur, allez-y et mettez votre niveau ici. Ceci est pour les niveaux d'API OpenAI. Et plus votre niveau est bas, plus vous serez limité dans ce que vous pouvez envoyer à l'API GPT et à quelle fréquence vous pouvez envoyer des choses. Si vous voulez savoir quel est votre niveau, vous pouvez simplement cliquer sur ceci ou faire un contrôle-clic et vous verrez votre niveau ici. C'est mon compte alternatif, je suppose. Donc, la plupart des gens seront au niveau un parce que vous venez probablement de créer ce compte pour cette leçon. Donc, cela devrait aller. Et ensuite, c'est à peu près tout ce dont vous avez besoin. Sous "keys", bien sûr, c'est là que vous mettriez l'ID de l'espace de travail Log Analytics. Donc, si vous êtes membre de Cyber Range, c'est déjà correct. Mais si vous ne l'êtes pas, vous devez simplement y mettre votre ID d'espace de travail Log Analytics. Je ne m'attends pas à ce que quelqu'un fasse cela. Vous devriez probablement juste rejoindre le Cyber Range si vous ne l'avez pas déjà fait et l'utiliser. Mais nous allons aller dans "main" et ensuite nous allons simplement exécuter les choses tout de suite. Je ne vais pas faire une analyse approfondie de tout. Je vais juste expliquer un peu les choses au fur et à mesure, mais allez-y et définissez un point d'arrêt ici juste avant ce client d'espace de travail Log Analytics. Faites cela. Ensuite, allez dans "Run" puis "Start Debugging" et "Python Debugger". Je vais fermer cette chose et ensuite nous laisserons cette chose s'arrêter. Ce client de journal, il est juste utilisé pour interroger notre espace de travail Log Analytics pour les journaux. Nous allons donc passer outre ceci. Le client est créé. Ce client OpenAI est pour interroger l'API ChatGPT. Nous allons donc passer outre ceci. Il utilise la clé API OpenAI que nous venons de créer, et c'est là que le modèle initial est défini et qu'il provient du module "model management" que nous avons importé. Donc, par exemple, si nous cliquons sur "explorer" ces deux fichiers, nous voyons "model management" ici, qui est ceci, et il importe "default model". Donc, si nous cliquons sur "model management", nous voyons beaucoup de choses ici. Mais nous pouvons voir "default models" ici. Et il est défini sur GPD5 mini. Nous retournons à "main" et nous passons outre ceci. Nous voyons "model". Il a été défini sur GPT5 mini. Et ensuite, cela utilisera une fonction appelée "get user message" qui fait partie du module "prompt management". Et nous voyons ici le module "prompt management". Et il y a beaucoup de choses ici. Je vais juste le réduire. Et nous voyons "get user message". Donc, cette chose est sur le point de s'exécuter. Elle va nous demander ce que nous voulons faire. Alors, si nous passons outre ceci, nous le voyons. Agentic stock analyst à votre service. Que voudriez-vous faire ? Je suis inquiet que quelqu'un se soit connecté à notre locataire au cours de la dernière journée environ ou d'autres fautes d'orthographe malveillantes malveillantes. Est-ce correct ? Malveillant s'est produit. C'est donc notre message générique que nous envoyons à notre agent. Et ensuite, il va le formater et le stocker dans un objet message lisible par ChatGPT. Donc, le rôle, le contenu utilisateur et ensuite la chose que nous venons de taper, puis le contexte de la requête. Nous allons faire une analyse approfondie de cela plus tard, mais je vais vous montrer ce qu'est cet objet après sa création, mais en gros, il utilise GPT ainsi que ce que l'on appelle des outils pour déterminer exactement où chercher les choses pertinentes pour notre requête et décide également d'un tas d'autres choses sur notre requête, comme s'agissait-il d'un ordinateur spécifique ou d'un utilisateur spécifique, etc. Alors, nous allons plonger dans cela beaucoup plus tard, mais je vais juste passer outre pour l'instant. Et ensuite, si nous allons dans "debug", nous voyons que ce contexte de requête non formaté a été créé. Et si nous regardons ceci, je vais réduire ces choses. Contexte de requête non formaté. Vous pouvez voir qu'un tas de choses ont été remplies. Il a essentiellement fait notre première requête à ChatGPT et a dit, d'accord, l'utilisateur a dit ceci, c'est le contexte de ce que nous faisons, renvoyez tout cela et ensuite il a décidé qu'il allait chercher dans les journaux de connexion, il a décidé qu'il allait chercher dans les dernières 24 heures parce que nous avons dit la dernière journée environ, il a décidé qu'il allait chercher dans ces champs spécifiques des journaux de connexion et ensuite s'agit-il d'un utilisateur individuel non, s'agit-il d'un hôte individuel non, s'agit-il d'un groupe de sécurité réseau non, parce que nous demandons une activité malveillante contre notre locataire, comme les journaux de connexion, puis la justification de sa décision pour GPT de peupler tous ces champs, nous pouvons lire oh, c'est difficile à lire, oh, ici, préoccupations signalées par l'utilisateur concernant les connexions récentes, les journaux de connexion contiennent des événements de connexion Azure AD avec l'emplacement IP, etc., la fenêtre de 24 heures couvre environ la dernière journée. Les champs choisis donnent qui, quoi, etc., etc. Il donne juste le contexte de pourquoi il a peuplé toutes ces choses. Et nous allons plonger dans cela beaucoup plus tard, alors ne vous inquiétez pas trop. Cette fonction assainit cette chose pour s'assurer que tous les champs sont présents et s'ils n'ont pas de valeur, ils sont juste une chaîne vide. Nous en parlerons plus tard, mais elle assainit juste l'objet. Alors nous passons outre ceci, et ensuite cela va simplement afficher le contexte de la requête à l'utilisateur, ce qu'il fait. Paramètres de recherche de journaux finalisés. Il nous dit, vous savez, c'est la table. Ce sont les champs. Si nous passons outre ceci, il nous dira la justification. C'est la chose dont nous venons de parler. Et ensuite, cela garantira que la table et les champs renvoyés par le modèle sont effectivement autorisés à être interrogés. Et c'est ce qu'on appelle une barrière de sécurité. Par exemple, si pour une raison quelconque GPT revenait et disait, oh, d'accord, nous devons chercher dans la table d'informations d'alerte ou quelque chose comme ça et que ce n'est pas une table autorisée, nous ne voulons pas laisser notre agent faire cela. Nous devons donc spécifier des barrières de sécurité. Et c'est juste une des barrières de sécurité. Il s'assure juste que la table qui a été sélectionnée, puis les champs dans la table qui ont été sélectionnés sont corrects. Et nous allons plonger dans tout cela éventuellement. C'est donc juste une vidéo d'aperçu général. Nous passons outre ceci, validation des tables et des champs. Les champs dans les tables ont été validés et conformes aux directives autorisées. C'est donc bien. Et ensuite, le prochain, il va interroger notre espace de travail Log Analytics. Je ne vais pas plonger profondément là-dedans pour l'instant. Je vais juste le parcourir et le laisser aller. Et il interroge un espace de travail Log Analytics en ce moment. et la requête est terminée. Il va compter les enregistrements ici. Passer outre, imprimer 818 enregistrements retournés, et ensuite si les enregistrements sont zéro, il va sortir. C'est un message médiocre, mais c'est juste une des choses qui ne va pas. Et ensuite, cela va en fait créer une grande invite qui va aller à ChatGPT. Elle va combiner le message de l'utilisateur qui était, je suis inquiet que quelque chose ne va pas. Elle va fournir le nom de la table, où chercher, ainsi que les enregistrements complets. Donc, elle va créer cette grande invite. Alors, si nous passons outre ceci, et ensuite ce message utilisateur de chasse aux menaces, ce message a été créé par cette fonction. C'est donc une invite, essentiellement. Message utilisateur de chasse aux menaces. Je vais vous montrer. Alors, si nous allons dans "debug" ici, et au fait, je recommande de regarder cette vidéo plusieurs fois. C'est juste une de ces choses que vous devez exposer beaucoup avant qu'elles ne commencent à avoir du sens. Mais je vais regarder ce qu'il y a à l'intérieur de ce message utilisateur de chasse aux menaces. Alors, ici, message utilisateur de chasse aux menaces. Vous pouvez voir ici. Et laissez-moi voir si je peux copier ceci. J'ai double-cliqué dessus. J'essaierai de le copier. Je vais aller dans ChatGPT et ensuite me connecter si vous n'êtes pas déjà connecté. Et je vais juste le coller ici. Et vous pouvez voir que c'est notre demande initiale. Je crains que quelqu'un se soit connecté. C'est notre demande ici. Et ensuite, la chose qui a été ajoutée en fonction de la table dans laquelle vous chassez les menaces IA, vous analysez les journaux de connexion. Et ensuite, c'est une autre invite qui a été ajoutée à notre demande initiale. Toute cette invite, nous regarderons tout cela plus tard, mais elle dit essentiellement que vous êtes une IA de chasse aux menaces, vous allez regarder dans la table des journaux de connexion XYZ. Et ensuite, ce sont tous les journaux réels, cette énorme quantité de journaux. Donc, en revenant à notre programme, nous passons outre ceci. C'est le message système de chasse aux menaces. Cela donne donc du contexte sur la façon dont nous voulons que ChatGPT se comporte. Et lorsque nous utilisons l'API, cela a été couvert dans les éléments constitutifs où il y a un message système et ensuite il y a un, je pense qu'il s'appelle message utilisateur. Je ne me souviens plus comment il s'appelle. Laissez-moi voir. Je pense que c'est "user message". Oui. Où le rôle est "user" et ensuite le message système. Le rôle est "system". Cela donne du contexte sur la façon dont nous voulons que GPT se comporte. Alors, si nous copions ceci par exemple, message système de chasse aux menaces, nous pouvons le voir ici. Contenu. Je vais juste copier ceci à nouveau. Et si nous allons à GPT, je vais juste faire défiler jusqu'en haut de ceci. Je ne sais pas si cela va fonctionner, mais je veux juste le coller ici pour vous montrer à quoi cela ressemble. C'est comme le message système. Vous êtes une IA de chasse aux menaces de cybersécurité, bla bla bla. Tout le contexte de ce que nous voulons qu'il fasse et comment nous voulons qu'il le fasse. Donc, en gros, nous avons notre message système et notre message utilisateur. Et ensuite, il va combiner cela dans une autre variable appelée objet de messages de chasse aux menaces. Alors, si nous passons outre ceci, les deux choses sont là. Nous avons le message système et nous avons le message utilisateur. Et ensuite, nous allons compter les jetons pour cela car il y a une limite au nombre de jetons que nous pouvons envoyer à ChatGPT. Si vous vous souvenez de la leçon sur les jetons et des éléments constitutifs, nous passons outre ceci. Il semble qu'il y ait environ 120 000 jetons, ce qui est une quantité assez décente. Et ensuite, en fonction du nombre de jetons, il va choisir un modèle pour nous ou du moins nous donner l'option de le faire. Alors, si nous passons outre ceci, beaucoup de choses se sont passées en bas. Alors, si nous faisons défiler ceci un peu, nous voyons que ce sont les quatre modèles que nous avons définis dans nos barrières de sécurité ou notre gestion des modèles, et nous pouvons voir la limite d'entrée, combien de jetons le modèle peut prendre, et ensuite c'est notre limite de débit basée sur notre niveau. Par exemple, GPT5 mini et 4.1 ont une limite de, je pense, 200 000 jetons par minute. Et ensuite, si nous choisissons GPD5, cela devrait théoriquement échouer car il n'a que 30 000 jetons par minute, mais notre seule requête est quatre fois ce montant. Donc, il s'affiche en rouge car c'est un dépassement de la limite. Et nous pouvons voir les coûts estimés ici. Si nous utilisons 4.1 nano, cela coûte 1 centime, GPT5 mini coûte 3 cents, puis respectivement GPT5 coûte 16 cents. Et vous pouvez comprendre cela. Et cette chose ici, elle montre que notre modèle actuel est GPT5 mini car c'était le modèle par défaut. Et si nous appuyons simplement sur Entrée, GPT5 Mini sera utilisé pour exécuter cette requête. Et vous pouvez voir ici, ce sont les résumés pour GPT5 mini, où la limite d'entrée pour le modèle est dans les limites, puis la limite de débit est également dans les limites. Nous pouvons donc simplement dire oui, ou nous pouvons dire Entrée et il choisira GPT5 mini par défaut. Je vais donc faire cela, puis il va valider le modèle. Assurez-vous que GPT5 mini est autorisé, le modèle que nous avons sélectionné. Valide. Et ensuite, il va initier la chasse cognitive. Donc, cette ligne, elle prend un horodatage du moment où la chasse a commencé, puis la chasse s'exécutera. Nous allons donc passer outre, passer outre, et ensuite lorsque cela se produit, il va envoyer, donc désolé, lorsque cela se produit, il va envoyer l'invite système ainsi que l'invite utilisateur à ChatGPT, ainsi que le modèle, et il va faire une analyse et il va nous revenir. Donc, si vous vous souvenez, j'ai commencé à coller des choses ici. C'est un peu l'équivalent de ce qui va se passer. Donc, si j'envoie juste ceci à ChatGPT, c'est un peu l'équivalent de ce qui se passe en ce moment. Mais dans notre cas, cela se passe en arrière-plan avec l'API. Cette grande invite a été créée et envoyée à GPT. Je le fais juste ici pour voir, vous savez, comparer les résultats de le déverser dans le navigateur par rapport à l'utilisation de l'API réelle. Juste comme une petite note, le navigateur lui-même a déjà un message système qu'il utilise et auquel nous n'avons pas accès, mais j'ai quand même versé notre propre message système ici, juste pour voir ce qui se passerait. Donc, il fait effectivement l'analyse et il va produire, il va produire les résultats de la chasse aux menaces pour nous et cela ressemblera probablement un peu à ce qui est renvoyé par notre agent réel. Mais nous verrons. Donc, cette chose, elle est terminée, on dirait. Donc, s'il n'y a pas de résultats de chasse, nous allons sortir. Mais, on dirait qu'il y avait quelque chose. Alors, nous allons passer outre ceci, passer outre ceci, et ensuite nous allons passer outre ceci. La chasse cognitive a pris ce nombre de secondes et a trouvé quatre menaces potentielles. Passer ceci dit d'appuyer sur Entrée ou Retour pour voir les résultats. Alors, si nous faisons cela, disons Entrée et ensuite, il est passé à la chose suivante. Nous devons donc réellement passer outre ceci pour voir les résultats. Et ensuite, il a déversé tous les résultats à l'écran. Non seulement il les a déversés à l'écran, mais il les a également enregistrés dans ce threats.json L. Donc, ces quatre derniers ici, ils étaient déjà là. Je pense que je les ai accidentellement inclus, mais ces quatre derniers ici sont les menaces réelles qui ont été trouvées. Et nous pouvons en fait voir une version plus lisible par l'homme de ceci. Si nous faisons défiler un peu vers le haut sur la ligne de commande. Petite menace numéro un. Je ne vais pas entrer dans les détails car les vôtres seront très différents car votre chose a utilisé différents journaux et les LLM sont différents, etc. Mais nous pouvons juste parcourir ceux-ci. Voyage impossible, réutilisation probable du jeton de session, car quelqu'un s'est connecté de Perth en Australie, puis de Toronto en 5 minutes, d'une manière ou d'une autre. Ce sont de vrais, d'ailleurs. Voyage impossible, mélange de lieux et courte période. Seattle et Taipei. Je peux deviner qui c'était probablement. Mais, échecs répétés de mot de passe invalides suivis de succès. Cela peut donc être un brute force potentiel contre le locataire, puis plusieurs échecs d'authentification rapides pour un compte de service. Oh, c'est intéressant. En fait, je ne sais pas ce que c'est, mais ce sont toutes de vraies découvertes. Donc, si vous êtes curieux, nous pouvons revenir en arrière et regarder GPT. C'est intéressant parce que c'est toujours en cours d'analyse. C'est pourquoi je pense que GPT peut-être GPT5 est parti au moment où vous regardez ceci. Je ne sais pas, mais il est possible que j'ai l'impression que GPT5 ou plutôt, lorsque vous utilisez GPT dans le navigateur, il change de modèle et fait des choses en arrière-plan, fait quelque chose d'étrange et essaie de déterminer quel modèle est le meilleur à utiliser, car cela prend beaucoup trop de temps pour être honnête. Mais je vais juste cliquer dessus. Je suppose que cela continue toujours. Je vais juste le laisser aller. Donc, quiconque édite ceci, allez-y et accélérez ou coupez. Cela prend beaucoup de temps. Bref, cela prend une éternité. Je suppose que cela ne va pas fonctionner. Donc, bref, c'est ça. Je vais le relancer une fois de plus, mais je ne vais pas le déboguer. Vous pouvez passer beaucoup de temps à faire cela si vous le souhaitez, comme le déboguer et tout. Je vais juste le faire une fois de plus. Cette fois. Voyez, je vais exécuter sans débogage. Donc, analyste sock agentique à votre service, que voudriez-vous faire ? Donc, cette fois, je vais interroger, plutôt, je vais regarder un peu de brute force de connexion contre la machine virtuelle, mais je vais voir quelle VM a le plus d'activité au cours de la dernière journée environ. Alors, je vais aller dans l'espace de travail Log Analytics pour le cyber cerveau. Je vais donc aller dans les événements de connexion de l'appareil et je vais dire, je vais dire count égal et je vais dire qu'est-ce que je fais, summarize count égal count by be device name order by account descending. Je veux juste voir quels ordinateurs ont le plus d'activité. Donc, il semble que la machine virtuelle de cette personne ait beaucoup de tentatives de connexion. Je vais donc copier ceci et je vais revenir ici et dire, je suis un peu inquiet qu'un de nos postes de travail ait été compromis. Il a été exposé à Internet pendant les derniers jours. C'est l'ID du poste de travail. Eh bien, pas le nom du poste de travail. Et heureusement, je l'ai mis à la fin parce que c'est juste comme X. Il y a un caractère de retour et cela s'est exécuté tout de suite. Donc, oh, ce n'est pas vraiment ce que je voulais. C'est donc un problème. Je voulais regarder dans la table des événements de connexion de l'appareil, mais vous remarquez qu'il a choisi les événements réseau de l'appareil. C'est un problème avec quelque part dans la gestion des invites. Oui, c'est un problème avec la gestion des invites. Nous devons fournir suffisamment de contexte dans notre environnement pour que l'agent sache où chercher correctement. Je vais donc juste arrêter ceci et je vais le faire à nouveau. Mais c'est quelque chose que nous devons corriger plus tard. Alors, je vais dire "Start Debugging". Je vais juste le déboguer et je vais essayer de mieux le formuler cette fois. Je vais tuer ça. Dire continuer. Parlez à votre service. Que voudriez-vous faire ? Je vais dire, je pense. Oh mon Dieu. Je pense que quelqu'un s'est peut-être connecté illégalement à l'un de nos postes de travail, comme un pirate informatique ou quelque chose comme ça. C'est le nom du poste de travail. Je ne sais pas quand c'est arrivé. Peut-être au moins un jour ou plus. Beaucoup de fautes de frappe ici, mais ce n'est pas grave. Donc, j'ai dû le guider un peu avec mon invite pour lui faire savoir que, oh, je parle des connexions de l'appareil. Voyez maintenant, il a choisi les événements de connexion de l'appareil. C'est ce que je voulais. Avant, il aurait dû pouvoir le dériver, mais c'est parce que notre invite et tout n'est pas assez bon. Il a choisi la mauvaise table, essentiellement. Il y a beaucoup de problèmes avec ceci, mais nous allons observer ceux-ci et essayer d'en corriger beaucoup. Alors, regardez ce qu'il a fait. Les champs et les tables ont été vérifiés. C'est la table qu'il a choisie, ce qui est un peu ce que je voulais. Et il y a beaucoup d'enregistrements. 2100 enregistrements. Et ensuite, ce sont nos choses. Donc, cette requête coûtera 3 cents si nous la laissons aller. Et ensuite, elle est dans les limites de GPT5 mini. Nous pouvons donc dire, je vais juste dire oui cette fois et dire Entrée. Remarquez que cela prend pas mal de temps car nous lui avons envoyé 100 000 jetons. Cela prend du temps. Cela a pris une minute. GPT4.1 est beaucoup plus rapide, je crois, mais il n'est pas aussi bon. Eh bien, il est assez bon, mais d'accord. Je vais dire Entrée. Et ensuite, il va déverser toutes les découvertes à l'écran. Je ne vais pas entrer dans les détails. Je vais peut-être juste les parcourir un peu pour que vous puissiez les voir si vous le souhaitez. Laissez-moi faire ceci pour voir. Les vôtres seront sans aucun doute différents. Bien sûr, période différente, journaux différents. Et je veux essayer quelque chose. Je veux essayer de faire un dépassement. Voyons ce qui se passe. Alors, je vais exécuter ce code. Je vais juste Oui, je n'ai pas de points d'arrêt, mais je vais le déboguer et ensuite j'utiliserai la même invite. Alors, laissez-moi aller chercher ça. Voici l'invite. Alors, je vais copier ceci. Bon sang, puis-je faire ça ? Oui. Alors, je vais coller [musique] ceci. Alors, et quand il arrive à la partie où il pose des questions sur le modèle, je vais essayer de choisir l'un des modèles dont la limite de débit est beaucoup trop basse pour la quantité de jetons que nous lui envoyons. Et juste pour observer ce qui se passe. Et je vous montrerai une chose de plus après cela, puis nous terminerons cette leçon. Donc, il collecte les journaux, il interroge Log Analytics. Alors, oh, ce sont tous des dépassements. Oh, intéressant. D'accord. D'accord. Voyons pourquoi cela s'est produit. D'accord, c'est un autre problème. Vous voyez, même si j'ai spécifié le nom de l'appareil, il a échoué à l'insérer ici. C'est encore un problème avec le prompting. Comme la dernière fois, vous savez, les LLM vous renverront quelque chose de différent à chaque fois, l'invite n'est pas comme l'invite système que nous avons utilisée pour l'aider à décider de la requête KQL à faire, elle était trop faible, je suppose, donc cette fois, elle n'a pas pu dériver le nom de l'appareil même si nous l'avons spécifié ici, je suis presque sûr, je suis presque sûr que je l'ai spécifié, laissez-moi voir, laissez-moi faire Oh, quelque chose est arrivé à l'invite. C'est pourquoi cela a échoué. Mais bref, pour vous, pour vous, par exemple, laissez-moi arrêter ceci. Je veux m'assurer que la chose essaie de récupérer trop de journaux pour que nous puissions les interroger. Alors, faisons ceci. En fait, c'est probablement bon. Je vais juste recommencer à déboguer ceci. Je vais probablement couper beaucoup de cela. Alors, faites de votre mieux et je le mettrai dans le cadre et je dirai où le couper. Mais, d'accord. Alors, nous allons dire, je pense. Oh mon Dieu. Je pense que quelqu'un s'est connecté illégalement à certaines de nos VM dans la dernière journée environ. Pouvez-vous regarder et voir ce que vous pouvez trouver ? Beaucoup de fautes de frappe. Mais remarquez que je n'ai pas spécifié de nom de machine virtuelle ici. J'ai juste dit que quelqu'un s'est connecté à nos machines virtuelles. Et donc le modèle, il va utiliser son cerveau et beaucoup du contexte que nous lui avons fourni. Nous n'en avons pas trop parlé, mais il va décider où chercher en fonction de notre invite. Et il a essentiellement décidé de chercher dans la table des événements de connexion de l'appareil, mais c'est une requête KQL vraiment bâclée, vraiment bâclée de ma part, mais c'est une des choses qui ne va pas. Mais en gros, vous remarquez que, il dit essentiellement toutes les machines, quelque chose qui commence par une chaîne vide. Cela signifie toutes les machines. Donc, il a essentiellement regardé toutes les machines virtuelles, les échecs de connexion dans les dernières 24 heures, ce qui représente une quantité substantielle d'enregistrements. Comme vous pouvez le voir, près de 7 000 enregistrements ont été retournés, ce qui a fini par faire 300, 341 000 jetons, n'est-ce pas ? Donc, pour GPT5 Mini, c'est parfait. Donc, la fenêtre de jetons maximale d'entrée pour GPT5 mini est de 272 000. C'est évidemment dépassé, et aussi la limite de débit de 20 000 ou 200K. C'est évidemment dépassé aussi. Alors, je vais essayer d'exécuter ceci juste pour voir ce qui se passe, plutôt, je vais l'exécuter avec GPT 4.1 parce que la limite d'entrée est dans la plage, mais la limite de débit est 10 fois dépassée. Donc, quand il demande quel modèle je veux utiliser, je vais juste dire GPT, je vais juste dire GPT 4.1, celui-ci. Alors, je vais dire Entrée. Et cela m'a averti. C'est au-dessus de la limite. Continuer. Nous pouvons dire Entrée pour continuer. Et ensuite, il va faire de son mieux. Limite de débit de jetons par minute de GPT4.1. Je devrais probablement avoir un meilleur message ici, mais il essaie de faire la chasse aux menaces. Je serai surpris que la limite de jetons, la limite de débit soit vraiment fantaisiste, car parfois elle vous laisse faire pour une raison quelconque si c'est une seule requête, mais parfois elle ne le fait pas. Mais nous verrons ce qui se passe, mais la limite d'entrée du modèle réel est vraiment stricte. Voyez, il nous a laissé faire quand même, même si la limite de jetons est comme, d'accord, il a trouvé cinq. Il a trouvé cinq menaces. Nous allons dire Entrée. Je vais laisser ceux-ci se déverser à l'écran. Je ne vais pas les examiner, mais je vais l'exécuter une fois de plus. Démarrer le débogage. Quelqu'un s'est connecté à certaines VM dans notre environnement au cours de la dernière journée environ. Je ne suis pas sûr de quelle VM. Pouvez-vous vérifier si vous trouvez des IOC ? Donc, cette fois, je vais, cela va renvoyer trop de journaux et je vais choisir un modèle où l'entrée réelle ne peut pas prendre autant de jetons. Donc, GPT5 mini, il échoue sur la limite d'entrée et il échoue également sur la limite de débit. Donc, nous allons juste le laisser aller. C'est un mauvais message, je dois corriger ça. Alors, je vais dire Entrée. D'accord. Et ensuite, nous avons eu une erreur. Une erreur, je pense, non, cette erreur a été interceptée, mais elle a juste été imprimée à l'écran. Les jetons d'entrée ont dépassé la limite configurée de, vous savez, 272 000, le message a résulté en 342. Veuillez réduire la longueur du message et il sort juste. C'est donc un autre problème, le laisser tenter d'interroger quelque chose ou le laisser tenter d'envoyer trop de jetons, c'est bien, mais le programme s'est juste planté comme ça à la fin et il a juste fini et ensuite notre ligne de commande est rouge. C'est donc un autre problème. Je voulais juste vous montrer ceci. Nous n'avons pas plongé trop profondément dans quoi que ce soit. Oh oui, je vais en fait, laissez-moi exécuter ceci une fois de plus. Je vais juste vous montrer quelque chose de très rapide. Alors, nous allons recommencer à déboguer et ensuite je vais casser ceci, peut-être ici. Je veux juste vous montrer que vous pouvez entrer dans la fonction. Donc, si vous voulez, nous n'avons pas fait une analyse vraiment approfondie de ce que fait tout cela. Nous le ferons dans les leçons suivantes, mais si vous voulez le faire à l'avance, nous avons juste passé outre tout. Mais si vous entrez, par exemple, en fait, laissez-moi, laissez-moi le rebriser ici. Donc, si vous voulez entrer dans les choses par vous-même et voir ce qu'elles font. Par exemple, j'ai cassé ce code ici. Si nous disons "step into" au lieu de "step over", il entrera en fait dans ce module et vous pourrez voir ce qu'il fait. Alors, "step into". Oh, je suppose qu'il ne le fait que pour les fonctions. Donc, par exemple, pour celui-ci, si nous disons "step into", il entre en fait dans le module "prompt management" et ensuite vous pouvez entrer, comme ça, vous pouvez observer chaque ligne de code. Quelqu'un s'est connecté à quelque chose qu'il n'était pas censé faire. Et vous pouvez faire comme ça, vous pouvez voir qu'il construit l'invite. Il la renvoie. Et ensuite, au lieu de passer outre, vous pouvez entrer avec "get log query from agent". Vous pouvez entrer et vous pouvez voir toutes les choses qui se passent. Je ne vais pas expliquer les choses. Je montre juste que vous pouvez le faire. Alors, et ensuite, si vous voulez passer outre, vous pouvez dire "step over" et il fera juste, il fera juste ces choses en arrière-plan et passera à la suivante. Mais si vous voulez entrer, vous savez, "display query context", cela déverse la chose à l'écran. Alors, je vais passer outre celui-ci. Vous pouvez voir qu'il le déverse juste. "Display query context rationale". Si vous voulez en fait entrer dans ceci et voir ce que fait la fonction, vous pouvez le faire. Alors, comme ceci. Alors, oui, je vais terminer ceci. Oui, c'est l'introduction à notre agent de base. Vous avez vu quelques problèmes avec. La prochaine vidéo, avant de faire une analyse approfondie des composants individuels, je vais parler de certaines des choses principales qui sont, je dis trop. Donc, dans la prochaine vidéo, je vais parler de certaines des principales choses qui ne vont vraiment pas avec ceci. Nous en avons déjà vu quelques-unes. Mais je vais en souligner beaucoup et ensuite nous en corrigerons probablement beaucoup en cours de route. Mais oui, réjouissez-vous de cela et nous nous verrons dans la prochaine vidéo. Oh oui, comme toujours, si vous êtes bloqué, avez des questions, je sais que c'est beaucoup. Je recommande de revoir ceci plusieurs fois et de le parcourir et de faire de votre mieux pour le comprendre. Mais oui, si vous êtes bloqué, allez dans la communauté, faites un post, taguez-moi, et nous nous verrons dans la prochaine leçon. Cool. Bienvenue. Cette leçon sera assez complexe et peut-être même un peu longue, alors faites de votre mieux pour y prêter attention. Je recommande vraiment de la regarder plus d'une fois. C'est probablement l'une des leçons les plus difficiles, je suppose. Mais si vous êtes bloqué, allez simplement sur le forum, la communauté, laissez un post, taguez-moi, définissez la catégorie comme cybersécurité IA, et nous nous en sortirons éventuellement. Mais en gros, dans cette leçon, nous allons couvrir une partie spécifique du flux de travail de l'IA agentique. Spécifiquement, nous allons découvrir comment prendre ceci, vous savez, quand l'agent démarre, c'est comme ce que je

À votre service, que souhaitez-vous faire ? Et ensuite, vous donnez cette chose lisible par l'homme comme : je crains que quelqu'un ne se soit connecté à Windows Target One. Donc, en gros, le but de cette leçon est de comprendre comment passer de cette chose lisible par l'homme à l'obtention de l'agent qui génère ces données structurées que nous pouvons utiliser pour interroger réellement Log Analytics et effectuer une forme de remédiation agentique à la fin. Donc, en gros, nous comprenons comment passer de cette entrée comme : je m'inquiète pour Windows Target One à l'obtention de cette sortie structurée autour. L'idée est donc que nous disons cela à l'agent, il fait quelque chose avec GPT, puis il extrait toutes ces informations à ce sujet. Donc, sur la base de cette requête, par exemple, il a décidé d'aller voir dans la table des événements de connexion de l'appareil. D'accord, je dois regarder dans les dernières 72 72 heures parce que l'utilisateur a dit ces derniers jours. D'accord, je dois regarder dans ces champs, spécifiquement pour cet appareil car ils l'ont mentionné ici. Et puis, d'accord, ce n'est pas à propos d'un utilisateur spécifiquement. C'est à propos d'un hôte. Ce n'est pas nécessairement à propos d'un groupe de sécurité réseau. Et puis voici tout le raisonnement pour ces données structurées que le modèle a trouvées. Et pour rappel, c'est le flux de l'agent, n'est-ce pas ? Comme une exécution complète lorsque nous lui disons ce que nous voulons jusqu'à ce qu'il affiche toutes les menaces qu'il a trouvées. Donc, nous avons essentiellement, je sais que c'est difficile à lire, mais ce n'est pas grave. Vous n'avez pas à le lire, mais en gros, en un seul flux complet, nous interagissons avec ChatGPT ou avec l'API ChatGPT deux fois. La première fois, c'est pour comprendre ce que l'utilisateur veut et comprendre comment dériver des données structurées à partir de sa phrase en anglais humain. Donc, la première fois, nous donnons à ChatGPT la phrase en anglais et il déverse un tas de choses comme la table, les champs, est-ce un utilisateur, etc. toutes ces données structurées qu'il déverse, puis nous l'utilisons pour interroger l'espace de travail Log Analytics et nous obtenons tous les journaux que nous utilisons ensuite pour la chasse aux menaces ici, puis les résultats sont affichés et nous pouvons ensuite passer à une remédiation à l'avenir. Donc, GPT est utilisé deux fois, la première fois pour obtenir ces données structurées, la seconde fois pour effectuer la chasse aux menaces après que les journaux aient été collectés. Donc, dans cette leçon, nous allons juste couvrir l'obtention des données utilisateur, puis comment elles sont transformées en ces données structurées, et ensuite nous nous arrêterons là. Et ensuite, nous allons, vous savez, comprendre, nous allons approfondir d'autres parties du flux de travail agentique plus tard. C'est donc ce que nous couvrons dans cette leçon. Je vais donc inclure du code source pour cela. Je veux juste m'assurer que nous utilisons tous le même code tout le temps. Alors, allez-y et téléchargez-le. Je mettrai un lien dans la description ci-dessous. Il ressemblera à ceci. Alors, téléchargez-le et dites simplement si vous utilisez Mac ou autre chose, extrayez-le et décompressez-le sur votre bureau. Et ensuite, nous l'ouvrirons. Je vais donc fermer ceci et le rouvrir pour que vous puissiez le voir. Oups. Donc, si votre dossier est fermé, vous pouvez aller dans l'explorateur. Vous pouvez dire ouvrir le dossier et aller, vous savez, où que vous l'ayez décompressé. Le mien est sur le bureau et voici le mien. Alors, nous allons l'ouvrir. Et avant de lancer ceci, assurons-nous que vous avez votre clé API. Donc, si ma clé API est ici, n'essayez pas de l'utiliser car je l'ai probablement supprimée. Alors, allez-y et assurez-vous que votre clé est ici. Vous pouvez obtenir votre propre clé API à partir d'ici. J'ai mis un lien ici. Je vais donc coller le mien. Et aussi, avant de commencer, vous voulez vous assurer que vous êtes connecté également. Alors, allez-y et ouvrez une ligne de commande. Cliquez sur le menu Démarrer ou si vous êtes sur Mac, allez dans Terminal, puis cmd, puis un espace login, puis vous sélectionnerez votre compte et entrerez votre mot de passe si nécessaire. Vous êtes peut-être déjà connecté, mais je veux juste m'en assurer. Appuyez sur Entrée pour sélectionner l'abonnement et nous devrions être prêts. D'accord, alors maintenant, allez-y et ouvrez main.py et nous allons parcourir cela une fois, à un niveau élevé, puis nous allons faire une analyse plus approfondie et voir exactement ce que tout est. Je vais donc interrompre ici, sur cette requête non formatée, où nous obtenons le contexte de la requête. C'est la chose principale que nous faisons dans cette leçon. Et puis je vais interrompre à nouveau ici où nous affichons le contexte de la requête. Et puis je vais interrompre, je vais interrompre à nouveau ici avant d'interroger réellement Log Analytics. Parce que je ne veux pas faire ça pour cette leçon. Nous comprenons juste encore une fois comment passer de ceci à ceci, comment cela fonctionne. Cool. Et encore une fois, ce sera un peu compliqué. Regardez simplement jusqu'au bout, regardez-le à nouveau et faites de votre mieux. Je vais donc interrompre ceci, et je vais dire exécuter et déboguer le fichier Python. Et je vais en fait utiliser cette requête. Je vous recommande de le faire aussi, juste pour que nous ayons quelque chose de similaire. Je vais donc copier ceci ici. Je suis inquiet. Mon Dieu, je suis inquiet. Windows Target One, etc. Je vais donc simplement coller ceci ici. Windows Target One. Ceci est une machine virtuelle Cyberrange. Elle est toujours allumée et elle est toujours attaquée, juste pour information. Alors, je vais dire Entrée. Et vous pouvez voir que le code s'est arrêté à nouveau immédiatement. Je vais donc, je vais entrer dans ceci. Nous pouvons examiner cette fonction. Et au fait, ceci, il s'est arrêté ici et cette fonction get query context, cette fonction est à l'intérieur du module executor. Donc, si nous allons dans l'explorateur ici, vous pouvez voir le module executor ici, double-cliquez dessus, puis vous voyez cette fonction get query context ici. C'est donc ce qui s'exécute et cette fonction, c'est ce qui produit ceci ou elle collecte ces données et c'est à ce point précis, get query context. Nous avons donc reçu le message de l'utilisateur, je m'inquiète pour Windows Target One et ceci est sur le point de s'exécuter. Alors, si nous entrons, et nous expliquerons cela en détail dans un instant, mais il récupère le prompt système du module de gestion des prompts ici, qui est ceci. Nous en parlerons dans un instant. Il a donc récupéré le prompt, puis maintenant il va faire l'appel API à l'API ChatGPT. Il va passer le modèle GPT5 mini, le message système, le message utilisateur qui est je m'inquiète pour Windows Target One. cette chose est celle qui est réellement responsable de la création de ces données structurées, mais nous en parlerons dans un instant, puis le choix de l'outil, nous en parlerons bientôt. Je vais donc simplement laisser cela s'exécuter pour l'instant. Je vais juste laisser cela fonctionner. C'est ce qui se passe en ce moment. Il demande à GPT, c'est pourquoi cela prend du temps. L'appel est terminé, nous pouvons donc entrer, étape, étape, retour. Il a donc récupéré le contexte de la requête. Il va le nettoyer, nous pouvons donc passer par-dessus et c'est là qu'il va le déverser à l'écran. Je vais donc ouvrir ceci. Je vais passer par-dessus et nous voyons qu'il a déversé tous ces métadonnées et ce contexte de requête à l'écran. Nous avons donc dit, je m'inquiète, je m'inquiète pour Windows Target One. Je pense que quelqu'un s'y est connecté ces derniers jours, puis il a décidé, d'accord, table des événements de connexion de l'appareil, plage horaire 72 heures, ce qui fait 3 jours, car nous avons dit ces derniers jours, il a choisi le nom de l'appareil à partir d'ici. Il a décidé que ce n'était pas à propos d'un utilisateur. Il a décidé que c'était à propos d'un hôte. Il a décidé que ce n'était pas nécessairement à propos d'un NSG. Et puis voici tout le raisonnement pour tout le reste ci-dessus qu'il a choisi. Et puis le script, nous allons simplement vérifier les garde-fous, puis l'espace de travail Log Analytics sera interrogé avec les métadonnées qui ont été récupérées. Mais je vais juste arrêter ceci pour l'instant. Nous allons donc exécuter ceci une fois de plus. Mais nous allons approfondir cette section ici où il interroge réellement GPT, et nous allons comprendre quel est le prompt système et quels sont les outils, car ces deux choses sont ce qui permet réellement d'extraire toutes ces métadonnées particulières simplement sur la base de notre simple ligne ici. Alors, retournons à main et nous allons exécuter et commencer à déboguer une fois de plus. Je vais utiliser la même requête. Je suis un peu inquiet pour Windows Target One. Je vais copier ceci. Analyste SOC à votre service. Que voulez-vous faire ? Je vais coller ceci. Dites Entrée. Arrêté ici. Je vais, je vais entrer dans ceci. Et c'est là que la magie opère. Je suppose que nous pouvons dire que nous entrons, et la première chose que nous allons regarder, car rappelez-vous, ceci est la première partie, nous interagissons avec GPT où nous essayons de comprendre, nous essayons de dériver la table, les champs, etc. en fonction de la demande de l'utilisateur. C'est donc ce que c'est. C'est important. Nous allons donc envoyer un message système et un message utilisateur à l'intérieur du paramètre messages, ainsi que des outils, entre guillemets, des outils. Nous n'avons pas encore appris cela. Et puis les choix d'outils requis. Donc, d'abord, il va récupérer la variable de sélection d'outils du prompt système. Et nous allons l'utiliser comme message système. Donc, cette variable de sélection d'outils du prompt système. Je vais copier ceci. Elle est à l'intérieur du module de gestion des prompts. Donc, si nous allons dans l'explorateur, puis dans le module de gestion des prompts, puis qu'elle est juste ici, sélection d'outils. C'est donc essentiellement juste un prompt. Si vous vous souvenez, lorsque vous interagissez avec ChatGPT, vous avez la possibilité de lui envoyer ce qu'on appelle un message système et un message utilisateur. Et vous vous souviendrez que nous en avons parlé plusieurs fois auparavant. Le message système donne simplement à ChatGPT le contexte de ce que vous voulez qu'il fasse et comment vous voulez qu'il agisse. Comme si vous étiez un boulanger, vous savez, parlez comme si vous viviez en France en tant que boulanger français ou quelque chose comme ça. Quelque chose comme ça. Et puis le message utilisateur réel est ce que vous voulez qu'il fasse. Donc, ce serait comme, dites-moi comment préparer le meilleur gâteau pour l'anniversaire d'un enfant de 10 ans. Quelque chose comme ça. Donc, dans notre cas, notre message système est ceci. Vous faites partie d'un appel de fonction d'outils. Votre but est de prendre le langage humain naturel lié à la chasse aux menaces d'un analyste SOC humain et de déterminer quelles tables enquêter, ainsi que de déterminer de quoi concerne la demande. S'agit-il d'un compte utilisateur, d'un hôte d'appareil, d'un pare-feu NSG, etc. Vous devrez être prêt à fournir un raisonnement pour votre évaluation également. Je peux juste, pour le plaisir, ajouter ceci aussi. Et puis le contrat d'utilisation des outils. C'est important. Vous pouvez appeler exactement un outil. Cela nécessitera beaucoup d'explications, mais vous pouvez en fait avoir plusieurs outils, mais nous n'en avons qu'un. Je vous montrerai ce que c'est dans un instant. Vous devez retourner un objet JSON qui inclut chaque paramètre défini par le schéma de l'outil, qui sera fourni plus tard. Lorsqu'une valeur est inconnue ou non applicable, définissez-la sur une chaîne vide, false pour les booléens ou vide ou un tableau vide pour les tableaux. Ne jamais omettre de paramètres. Ne demandez que les champs listés pour chaque table dans la description de l'outil. D'accord, c'est comme si cela n'avait peut-être pas beaucoup de sens pour l'instant, mais cela aura plus de sens lorsque nous verrons réellement les outils. C'est donc le prompt système de sélection d'outils. De retour dans l'executor, nous avons notre message système. Maintenant, ici, c'est ainsi que le message système est structuré. C'est juste un objet JSON qui ressemble à ceci. RO system content et puis cette grande chose que nous venons de lire, puis c'est la fonction qui appelle réellement, qui fait l'appel API à ChatGPT, puis pour essayer d'obtenir les données structurées, nous lui passons ou nous utilisons le paramètre modèle, le paramètre messages, le paramètre outils et le choix des outils. Donc, le paramètre modèle que nous utilisons est ChatGPT5 mini, les messages que nous utilisons sont le message système, cette chose que nous venons de lire dans la gestion des prompts, ainsi que le message utilisateur, qui est notre message original, puis nous utilisons cette chose, c'est ce qui crée réellement toutes les données structurées et dit, cela indique à ChatGPT ce qu'il faut retourner et ce qu'est un tas de choses. Cela lui donne juste beaucoup de contexte et lui permet de retourner des choses qui ont du sens. C'est donc à l'intérieur du module de gestion des prompts, qui est ici, à l'intérieur de la variable outils. Alors, nous double-cliquons sur la gestion des prompts. Il y aura une variable outils ici. Et c'est un peu compliqué, mais j'essaierai peut-être d'expliquer cela à l'envers. Cela aura peut-être plus de sens. Alors, je vais effondrer les propriétés et j'effondrerai également la description. Et donc, en gros, cette chose d'outils, nous la donnons à ChatGPT et en gros, vous pouvez y penser, vous pouvez y penser comme si nous donnions à ChatGPT un formulaire vide, un morceau de papier, vous savez, un formulaire et qu'il a des zones vides à remplir. Il a comme nom de table, nom d'appareil, plage horaire, champ appelant, etc. Et il est obligé de mettre quelque chose dans chacun de ces champs, je suppose que nous pouvons dire, ou si vous imaginez un morceau de papier, vous savez, un formulaire où vous remplissez quelque chose, il est obligé de mettre quelque chose dans chacun de ceux-ci, n'est-ce pas ? Il doit mettre quelque chose dans chacun de ceux-ci, puis cette propriété, elle lui donne une sorte d'information sur ce que signifie chaque champ. Par exemple, nom de table, comme la table Log Analytics à interroger, par exemple, événements de processus d'appareil, etc. Et puis dans le champ nom d'appareil, ce sera une chaîne de caractères et c'était comme le nom de l'appareil à filtrer, par exemple, PC utilisateur1, l'appelant, etc. etc. et puis par exemple, ils correspondent tous à des choses ici. Par exemple, ceci concerne l'utilisateur individuel qui est ici. C'est juste si la requête concernait un compte utilisateur individuel ou non, et c'est un booléen. Donc, cela signifie que GPT doit dire vrai ou faux pour cela. Ceci concerne l'hôte individuel, cela signifie que la requête concerne un hôte, un serveur ou un client individuel, et vous devez mettre vrai ou faux ici. Et la même chose avec celui-ci concernant un NSG, vous mettez vrai ou faux. Et puis le raisonnement, c'est une chaîne de caractères. Votre raisonnement pour avoir choisi les propriétés que vous avez. Essentiellement, cela signifie simplement vous expliquer. Et si nous remontons, si nous regardons dans cette description, c'est plus la description donne à GPT plus de contexte pour les différents champs et propriétés et les choses avec lesquelles nous travaillons et ce que nous voulons qu'il fasse. Alors, si nous l'étendons, par exemple, si vous vous souvenez de notre requête, je suis un peu inquiet que Windows Target One ait pu être connecté de manière malveillante ces derniers jours, cela donnera à GPT le contexte pour les tables qui existent et ensuite ce que les différentes choses que les tables contiennent. Par exemple, si je, si je rends les choses plus faciles pour nous et que je saute directement ici, celui-ci contient une activité de connexion contre un ou plusieurs serveurs ou postes de travail. Donc, lorsque GPT regarde ceci, il se dit, oh d'accord, pour le nom de table, celui-ci a le plus de sens car la requête de l'utilisateur était comme si quelqu'un s'était connecté ces derniers jours, ils sont inquiets, cette table contient une activité de connexion, donc ce doit être celle dont j'ai besoin, puis pour décider quels champs retourner, nous lui avons donné du contexte et au fait, cet objet ici est juste quelque chose que j'ai construit et assemblé. Cela prend du temps, mais c'est ainsi que vous donnez à GPT ou à votre agent un contexte sur votre environnement. Donc, ces champs, cela indique à l'agent quels champs sélectionner en fonction de la table sélectionnée. Donc, événements de connexion d'appareil, ce sont les champs qu'il devrait retourner, etc. Et j'ai juste ajouté un peu plus de choses ici pour lui donner du contexte pour l'aider. Je ne lirai pas toutes ces choses en détail, mais en gros, comme si un nom d'utilisateur est mentionné, dans le prompt utilisateur, supposez qu'il s'agit du nom principal de l'utilisateur, qui est un champ dans l'une des tables. Si la requête appartient à la table des événements de connexion de l'appareil ou à la table des journaux de connexion. Si une activité réseau est remise en question pour un hôte spécifique, cela se trouve probablement dans la table des événements réseau de l'appareil. Donc, si j'avais dit quelque chose comme, je m'inquiète de l'activité réseau malveillante provenant de Windows Target One, probablement cette table aurait été sélectionnée à la place. Donc, c'est juste beaucoup plus de contexte pour aider GPT à décider quelle table choisir, quels champs choisir, etc. Et puis ces paramètres / propriétés. C'est plus de contexte pour lui, car rappelez-vous, nous disons à GPT que vous devez retourner tout cela simplement sur la base de ceci. Oh mon Dieu, qu'est-ce que c'est ? Simplement sur la base de ceci, vous devez retourner ces informations. Et puis il apprend ce que sont ces informations à partir des propriétés ici. Et puis cette description ici fournit, la description fournit encore plus de contexte. C'est donc ce que sont les outils. Alors, si nous retournons à l'executor, nous disons, nous lui donnons beaucoup de contexte comme le message système, comment se comporter. Nous lui donnons beaucoup de contexte. Donc, le message système, comment se comporter. Le message utilisateur, ce que nous voulons, ce dont nous nous inquiétons, n'est-ce pas ? Et puis les outils, qui est exactement comme, c'est essentiellement ce formulaire vide, vous devez remplir ce formulaire, vous devez mettre quelque chose pour un appareil, mettre quelque chose pour une table, etc. Nous lui donnons les outils. Pour qu'il puisse les remplir et nous les retourner. Et puis si nous disons choix d'outil automatique, je crois qu'il ne retournera pas tout ou quelque chose comme ça. Ou il ne le fera pas. D'accord. Il ne le fera pas. Si nous lui disons quelque chose d'étrange qui n'est pas lié à la chasse aux menaces ou quelque chose comme ça. Oh mon Dieu. Donc, si nous disons quelque chose qui n'est pas lié à la chasse aux menaces, il ne retournera rien. Parce que vous êtes autorisé à avoir plus d'une chose ici. Alors vous remarquerez cette chose d'outils. C'est en fait un tableau ou une liste et il y a une seule fonction à l'intérieur. Nous n'en avons qu'une. Donc, en gros, le choix de l'outil, il n'y a qu'un seul outil à choisir dans notre instance. Comme jusqu'à présent, nous allons probablement en ajouter un nouveau à l'avenir, mais il n'y en a qu'un à choisir. Donc, si nous disons requis, il choisira toujours cette chose ici. Mais si nous disons, par exemple, choix d'outil automatique, nous pouvons dire automatique. Et si nous disons, si le prompt est quelque chose comme, quel est le meilleur, quel est le meilleur sac à main pour ma petite amie ou quelque chose comme ça, il regardera ces outils et il lira la description et il ne verra rien à propos des sacs à main ou des petites amies, et ensuite il ne retournera rien, n'est-ce pas ? Mais pour nos intentions et nos objectifs, je vais juste forcer cela à retourner quelque chose ou je vais forcer cela à utiliser cet outil / cette fonction. C'est donc ce que c'est. C'est donc essentiellement juste un tas de contexte, le modèle que nous voulons utiliser, un tas de contexte pour ce que nous voulons faire et ce que nous voulons qu'il retourne, puis lui donner la possibilité de décider s'il faut utiliser ou non l'une des fonctions. Je vais donc simplement parcourir ceci comme d'habitude et il a retourné un tas de choses. Et au fait, vous pouvez toujours cliquer sur cette chose de débogage et l'étendre, puis réduire ces choses et vous pouvez voir ces choses ici. Par exemple, ces arguments, maintenant il a tout ce qui a été retourné par ChatGPT, l'appel de l'outil. Vous pouvez le voir, nous passons, étape, et je vais passer par-dessus et ensuite il va afficher notre contexte de requête, tout ce qui a été retourné par GPT en utilisant les outils, comme ça. Je vais donc, euh, je vais terminer ceci et je vais faire une autre requête. Je vais, laissez-moi voir ici. Je vais ouvrir, je pense que je peux, je vais obtenir mon nom d'utilisateur particulier. Je pense que je peux juste copier ceci. Puis-je, ne suis-je pas autorisé ? Je veux copier mon nom d'utilisateur pour pouvoir l'utiliser. D'accord. Je vais donc copier ceci. Je ne suis pas sûr si cela fonctionnera bien, mais je vais juste essayer de toute façon. Alors, je vais revenir ici et je vais exécuter ceci. Je vais aller dans main et je vais exécuter ceci une fois de plus. Commencer le débogage et je vais dire, je suis, oh mon Dieu, je suis un peu inquiet qu'un de nos utilisateurs travaille à distance illégalement en utilisant un VPN ou quelque chose comme ça. d'un autre pays. Leur nom d'utilisateur est, je vais juste utiliser mon normal, non, je vais utiliser ceci à loginific.com. Attendez. D'accord. Je ne suis pas sûr si cela fonctionnera bien car notre agent n'est pas vraiment affiné, mais je vais juste voir ce qui se passe, n'est-ce pas ? Alors, euh, oui, je vais juste laisser cela se faire. Je vais juste passer, étape, je vais passer. Je vais le laisser faire et voir ce qui se passe. Je suis légèrement inquiet parce que ce nom est vraiment long et obscur, mais peut-être que ça marche. Nous verrons. Ça devrait. Nous allons passer par-dessus ce contexte de requête. Afficher le contexte de requête. Oh, intéressant. Donc, il a décidé de regarder dans les journaux de connexion, ce qui est correct. Et pour la plage horaire, il a choisi une semaine car je ne pense pas avoir spécifié quoi que ce soit à ce sujet. Et au fait, vous pouvez contrôler cela. Je n'ai pas dit de regarder dans les 3 derniers jours. Je n'ai rien dit sur l'heure, mais il a choisi une semaine par défaut. Mais c'est là que vous pourriez aller, vous pouvez aller dans la gestion des prompts. Et vous pouvez aller dans, je pense que c'est le prompt système pour l'appel des outils. Et vous pouvez dire quelque chose ici comme, si aucun laps de temps n'est spécifié par l'utilisateur, choisissez 4 jours, 96 heures. Vous pouvez faire quelque chose comme ça. Cela donne du contexte et le guide pour faire ce que vous voulez. Par exemple. Mais, il a choisi les journaux de connexion, a choisi les tables, il a décidé que c'était lié à l'utilisateur, pas lié à l'hôte, pas lié au NSG, et puis voici le raisonnement pour cela ou le raisonnement qu'il a fourni. Laissez-moi voir le contexte de la requête. Oh, j'ai besoin de modifier cela pour qu'il imprime réellement le nom d'utilisateur principal car vous remarquez qu'il n'imprime pas le nom car je ne l'ai pas laissé faire cela en fait. Alors, je vais corriger cela maintenant en fait. Laissez-moi arrêter ceci. Et au moment où vous recevrez ce code, il sera corrigé. Je pense que c'est dans le module utilitaires et c'est le cas. Alors, nous pouvons dire nom d'appareil. D'accord. Appelant. Alors, je vais juste copier ceci et je vais laisser cela ici car c'est une bonne pratique. Je pense que si je pense utilisateur, je pense que c'est ce nom d'utilisateur principal, pas vide. utilisateur. Je pense que je peux faire ça. Laisser. Non. Laissez-moi juste essayer de lancer ceci une fois de plus. Si cela échoue, je ferai en sorte que mon éditeur le coupe. Alors, je vais juste, je vais utiliser la même invite à nouveau. Alors, vous pouvez utiliser, vous pouvez utiliser votre propre, comment ça s'appelle ? Votre propre nom d'utilisateur si vous le souhaitez. Assurez-vous simplement de le taper correctement. Et rappelez-vous, cela a choisi une semaine car je n'ai spécifié aucun laps de temps. Mais j'ai en fait changé le prompt système pour dire 4 jours si aucun laps de temps n'est spécifié. Alors, je vais essayer cela maintenant en fait et voir si cela fonctionne. Et qu'est-ce que cette chose fait ? Je vais arrêter ceci et je vais l'exécuter. Retournons à main et exécutons ceci une fois de plus. Que souhaitez-vous faire ? Je suis un peu inquiet à propos de cet utilisateur. Alors, nous allons passer par-dessus ceci et nous allons laisser la requête se dérouler. Je vais en fait laisser cette chasse aux menaces se dérouler complètement pour que nous puissions voir ce qu'elle trouve, puis nous terminerons la leçon. Je vais parler un peu plus. Mais oui, donc le contexte de la requête. Compris. Affichez-le et voyez comment ceux-ci sont maintenant alignés. Appelant, nom d'utilisateur, appelant. L'appelant est le même que le nom d'utilisateur en fonction de la table avec laquelle vous travaillez. Vous pouvez regarder à l'intérieur de la gestion des prompts, à l'intérieur des outils pour voir plus à ce sujet. Par exemple, appelant, je pense que j'en parle un peu ici. Je lui donne du contexte sur ce qu'est l'appelant. Bam. Garde-fous. Je vais juste laisser cela se faire. Je vais jouer ceci. Continuer. Et 16 enregistrements sont retournés pour mon utilisateur spécifique au cours des 4 derniers jours. C'est la requête KQL qu'elle a trouvée. Seulement 16 enregistrements. Vraiment, vraiment minimal. Analyse extrêmement bon marché sur celle-ci. Bien en dessous de la limite. Alors, nous pouvons dire Entrée. Faire la chasse aux menaces. Je ne sais pas si elle trouvera quelque chose. Je n'utilise pas beaucoup ce compte, mais il pourrait y avoir un voyage impossible potentiellement, mais je ne suis pas sûr. Nous verrons ce qu'elle trouve. A trouvé deux menaces potentielles après 45 secondes. Regardons. Je ne pense pas qu'il y aura un rouge. Je ne pense pas. Oh, il y en a un. Euh, aucune preuve. Donc, c'est intéressant. Aucune preuve de connexions VPN étrangères. Toute activité provenant d'une seule utilisation, un emplacement qui est l'adresse IP de la machine virtuelle avec un niveau de confiance élevé. Donc, c'est en fait intéressant. Le prompt de chasse aux menaces réel doit être ajusté. Ceci est en dehors de la portée de cette leçon, mais vous verrez qu'il est indiqué, par exemple, niveau de confiance élevé, mais ce sont censés être des menaces, mais il dit en fait que tout va bien, je crois. Il dit que tout va bien. Niveau de confiance élevé, mais cela pourrait être perçu comme une menace. Une meilleure expérience utilisateur serait de ne pas avoir cela affiché ici, puis peut-être que l'agent revienne et retourne quelque chose comme, oh, il n'y a pas eu de résultats, ou quelque chose comme ça, car cela apparaît comme si une menace s'était produite et que c'est un niveau de confiance vraiment élevé. Mais je ne pense pas que ce soit le cas. Il y a plusieurs connexions réussies depuis la même IP. Mais c'est une bonne chose, n'est-ce pas ? Cela signifie que l'utilisateur n'est pas à l'étranger. Et puis les indicateurs de compromission. Ce ne sont pas réellement des compromissions. Ce sont juste des preuves que l'utilisateur est là où il est censé être, etc. Mais cela a trouvé quelque chose et a pu faire une analyse néanmoins. Donc, je veux dire, c'est plutôt cool. Et puis qu'est-ce que ce moyen ? Je ne vais pas lire, c'est beaucoup de texte, mais vous pouvez le lire si vous voulez. Il n'y a aucun doute que le vôtre sera différent de celui-ci, évidemment, car vous savez, vous exécuterez cela à un moment différent contre un utilisateur différent. Mais c'est à peu près tout ce que je voulais montrer. Vous pouvez vraiment contrôler la façon dont l'agent se comporte et quelles informations sont retournées, etc. sur la base de ce prompt d'outils. Vous pouvez donc essayer, sur la base à la fois du prompt d'outils et du prompt système qui est utilisé pour l'initial, pour l'initial, qu'est-ce que je dis, pour cela, lorsque nous essayons de dériver les métadonnées et ces données structurées de la requête de l'utilisateur. Donc, si vous voulez, je vous recommande de modifier un peu ce prompt de sélection d'outils du prompt système, comme la section de contenu. Vous pouvez dire toutes sortes de choses ridicules ici. Je ne veux pas trop le gâcher car je vais empaqueter ce code et vous laisser l'utiliser dans la leçon. Mais je vous recommande de jouer un peu avec cela, le prompt système ainsi que les outils, car vous remarquerez, par exemple, qu'il y a un tas de tables ici, par exemple, mais la table des événements du registre de l'appareil, mais je n'ai pas spécifié les champs pour les événements du registre à retourner. Et il y a aussi, eh bien, je ne veux pas trop anticiper, mais en gros, il y a beaucoup de choses que vous pouvez faire ici et je n'ai pas inclus toutes les tables et je n'ai pas inclus tous les champs pour toutes les tables et je lui ai donné toutes sortes d'indices et de conseils sur la façon de structurer et de retourner les données. Je vous recommande donc simplement de jouer un peu avec cela et d'essayer d'obtenir une bonne compréhension et une bonne intuition de la façon dont cela fonctionne et d'essayer de le rendre logique et de le rendre plus intuitif. Mais oui, c'est, je ne sais même pas comment appeler cette leçon pour être honnête. J'ai oublié comment je l'ai appelée. Qu'est-ce que c'est ? Contexte de requête, je pense, obtenir le contexte de requête. Mais oui, c'est, c'est utiliser des outils avec le point de terminaison de l'API GPT. Et encore une fois, en récapitulatif, en gros, nous posons une question à GPT. Nous interagissons avec, ou plutôt, nous posons une question à l'agent et ensuite l'agent interagira avec ChatGPT pour obtenir plus de contexte sur ce que l'utilisateur veut réellement faire et ce qu'il faut interroger. Il répondra. Nous prendrons cette information. Nous interrogerons l'espace de travail Log Analytics avec une requête KQL structurée. Nous obtiendrons un tas de journaux et c'est ce que nous utiliserons pour réellement faire la chasse aux menaces. Mais dans cette leçon, nous avons juste obtenu l'entrée de l'utilisateur. Nous avons dérivé ces données structurées à partir de ces phrases en anglais simple de l'utilisateur. Et je sais que c'est un peu compliqué et je ne sais même pas comment appeler certaines de ces choses pour être honnête car c'est nouveau pour moi. Mais si vous êtes bloqué ou si cela n'a pas de sens ou si vous trouvez une erreur ou quelque chose que j'ai fait, allez certainement dans la communauté et publiez, faites-nous savoir. Essayez d'attirer mon attention. Je ferai de mon mieux et nous vous verrons dans la prochaine leçon. Bienvenue de retour. Dans cette leçon, nous allons couvrir les garde-fous, ou ce qu'on appelle les garde-fous pour l'IA agentique. Et les garde-fous. Ce sont juste des règles et des vérifications de sécurité qui guident les systèmes d'IA pour agir de manière responsable, s'assurer que leurs décisions restent alignées sur les objectifs, les valeurs et les limites de sécurité humaines, y compris les coûts. C'est donc juste quelque chose qui est mis en place pour s'assurer que l'agent ne fait pas quelque chose de vraiment sauvage qui cause beaucoup de dégâts ou vous fait perdre beaucoup d'argent pour une raison quelconque. Et en gros, la façon dont l'agent, je vais couvrir cela avec un diagramme très rapidement, puis nous allons plonger dans le code et parler un peu plus des garde-fous que nous avons en place. Mais je veux juste en parler un peu. Donc, actuellement, nous exécutons ce code, le code de l'agent IA agentique, sur notre ordinateur local ou notre VM ou quelle que soit la situation pour vous. Donc, nous pouvons aller directement dans le code et le modifier car nous sommes l'ingénieur, nous sommes celui qui développe l'agent, n'est-ce pas ? Nous pouvons simplement interagir directement avec lui. Mais dans une situation normale ou dans le monde réel, l'utilisateur de l'agent sera probablement un analyste SOC L1 qui n'a pas conçu l'agent et qui n'a pas d'accès direct au code pour faire des choses. Donc, normalement, peut-être que l'agent sera chez lui ou quelque chose comme ça, et il sera juste, ou désolé, normalement le SOC, l'analyste SOC ou vous savez, l'humain sera chez lui ou au bureau ou quelque chose comme ça, et il utilisera l'agent via une sorte d'interface. Ce pourrait être une application web ou ce pourrait être la ligne de commande, mais il pourrait l'utiliser à distance ou quelque chose comme ça. Ce n'est pas comme s'ils allaient avoir le code Python brut sur leur ordinateur où ils peuvent modifier le code et les choses comme ça. Alors, pourquoi cela est lié aux garde-fous, les garde-fous sont intégrés au backend et intégrés au code. Donc, lorsque l'utilisateur interagit avec, il ne peut pas simplement modifier les garde-fous et les contourner ou quoi que ce soit. Ils seront mis en place d'une manière qui n'est pas accessible à l'utilisateur, puis l'utilisateur interagira avec l'agent et l'agent sera capable de faire des choses par lui-même. Mais il y aura des garde-fous en place qui l'empêcheront de faire certaines choses. Et encore une fois, ce n'est pas comme le scénario où vous pouvez simplement aller et modifier les garde-fous car c'est protégé au backend d'une manière ou d'une autre. Nous exécutons simplement le code localement sur notre ordinateur et nous pouvons le modifier et manipuler les garde-fous à volonté. Donc, cela ne semble pas très sûr, mais c'est parce que nous sommes ceux qui avons le code entre nos mains, si cela a du sens. Donc, les garde-fous sont simplement en place. Je vais vous montrer exactement ce qu'ils sont et certains garde-fous qui manquent, mais ils sont simplement en place pour empêcher l'agent de devenir incontrôlable et de dépenser beaucoup d'argent ou de faire quelque chose qu'il n'est pas censé faire. Donc, en parlant un peu des garde-fous que nous avons réellement dans notre code. Nous allons exécuter le code et les inspecter, mais nous avons essentiellement une liste blanche de tables. Donc, lorsque vous interrogez Log Analytics pour des événements réseau d'appareils, des événements de connexion d'appareils, etc., nous avons une liste de tables autorisées. Donc, si l'agent essaie d'interroger une autre table pour une raison quelconque, il ne sera pas autorisé. Nous avons également une liste blanche de champs. Donc, par exemple, toutes les tables, voyons si je peux, un instant. Vous pouvez simplement éditer cela. Je vous dirai quand recommencer l'enregistrement. J'aurais dû ouvrir cela à l'avance. Zut. Et nous avons également une liste blanche de champs. Donc, par exemple, c'est la table des événements de connexion de l'appareil, n'est-ce pas ? Et puis ce sont tous les différents champs de la table. Donc, si l'agent essaie de retourner un champ aléatoire qui n'est pas défini dans notre garde-fous, il ne le laissera pas faire. Il générera une erreur ou il mettra fin à l'appel ou mettra fin au programme ou quelque chose comme ça. Donc, disons que dans notre garde-fous, nous n'autorisons que le nom du compte généré par le temps, le type d'action et l'ID de l'appareil, mais si l'agent essaie de retourner le nom de l'appareil ou la raison de l'échec, il ne sera pas autorisé à le faire car ceux-ci sont en dehors des garde-fous, par exemple. Je vais vous montrer exactement ce que c'est dans le code. Et puis nous avons également une liste blanche de modèles, seuls certains modèles ChatGPT que l'agent est autorisé à utiliser. Et si l'utilisateur parvient d'une manière ou d'une autre à injecter un modèle à utiliser qui n'est pas sur la liste blanche dans les garde-fous, l'agent ne pourra pas réellement utiliser ce modèle. C'est le but. Peut-être que l'utilisateur veut utiliser un modèle très cher que l'entreprise ne veut pas payer, par exemple. Et puis ce sont quelques garde-fous qui pourraient manquer dans notre code. Donc, comme une application de fenêtre de temps. Donc, actuellement, lorsque vous allez interroger ou lorsque vous allez demander à l'IA agentique, je m'inquiète pour Windows Target One, bla bla bla, veuillez regarder dans les 500 derniers jours ou quelque chose comme ça. Il devrait y avoir une sorte de garde-fous qui empêche les gens de regarder aussi loin dans le passé, car cela va, indépendamment du fait que le modèle puisse gérer autant d'enregistrements, Log Analytics continuera, l'agent ira et essaiera d'interroger Log Analytics, et c'est comme un gaspillage d'argent, car chaque fois que vous interrogez Log Analytics, cela coûte de l'argent, n'est-ce pas ? Et si vous êtes autorisé à récupérer 500 jours de journaux, même si le modèle ne peut pas les traiter, c'est juste un gaspillage de ressources. Nous pourrions donc vouloir créer des garde-fous pour la limite de temps, n'est-ce pas ? Et puis les limites de lignes/octets avant le LLM. C'est à peu près la même chose. Ce serait comme si la quantité de lignes retournées par l'espace de travail Log Analytics est évidemment trop importante pour tenir dans la fenêtre de jetons. Nous pouvons même ne pas lui permettre de contacter l'API ChatGPT car c'est évidemment trop. Et ce serait comme des choses de confidentialité. Donc, la suppression des PII avant le modèle. Donc, nous pourrions avoir une sorte de middleware entre le modèle et avant qu'il n'envoie des choses à ChatGPT pour analyse qui supprime ou masque toute information personnelle identifiable qui a été découverte. Et puis lorsque nous commencerons à faire des choses de remédiation réelles, il y aura probablement plus de considérations que nous devons avoir pour les garde-fous ici également. Oui. Nous pouvons donc passer au code. Je vous fournirai du code comme toujours pour cette leçon. Alors, allez-y et téléchargez-le et extrayez-le. Je l'ai mis sur mon bureau. Il s'appelle Garde-fous. Il sera probablement nommé quelque chose comme ceci. Alors, assurez-vous d'ouvrir ce dossier dans Visual Studio Code. Et ensuite, nous allons fermer tout cela et j'ouvrirai main. Et puis laissez-moi voir. Je vais mettre un point d'arrêt ici avant ces garde-fous, avant de valider les tables et les champs. Et je vais mettre un point d'arrêt ici avant la validation du modèle. Alors, je vais simplement exécuter ce programme une fois normalement pour que nous puissions avoir une idée de son fonctionnement. Je suis sûr que vous avez probablement déjà une idée, mais je vais utiliser cette invite d'échantillon, invite/requête à nouveau. Alors, je vais commencer à déboguer ce débogueur Python. Fichier Python. Analyste, que souhaitez-vous faire ? Je m'inquiète pour Windows Target One. Et au fait, vous pouvez utiliser une invite différente si vous le souhaitez. Je l'utilise juste parce qu'elle est très simple. Cool. Si nous ouvrons ceci, nous pouvons voir toutes les choses qui se sont passées jusqu'à présent. Il a obtenu le contexte de la requête. Il a décidé de regarder dans la table des événements de connexion de l'appareil pour cela. C'est lié à l'hôte, raisonnement. Et ensuite, il va valider, il va appeler la fonction valider les tables et les champs qui fait partie du module garde-fous. Donc, si nous regardons dans l'explorateur ici, il y a le module garde-fous et il va appeler cette fonction valider les tables et les champs et il aura des tables et des champs. Donc, il va passer le nom de la table du contexte de la requête. Donc, si nous regardons, si nous regardons ce débogueur et que nous regardons, descendons, laissez-moi réduire ceci et ceci, nous voyons notre contexte de requête et nous voyons le nom de la table du contexte de requête. Donc, le nom de la table est événements de connexion de l'appareil. Donc, il va passer événements de connexion de l'appareil ici et ensuite les champs du contexte de requête. Il va passer ces champs. Heure générée, nom du compte, nom de l'appareil, etc. Alors, nous allons entrer dans ceci. Vous voyez qu'il entre dans le module garde-fous, dans la fonction valider les tables et les champs, et nous voyons la table événements de connexion de l'appareil et les champs. Et puis nous entrons, il va imprimer validation des tables et des champs... puis il va vérifier si la table, qui est événements de connexion de l'appareil, n'est pas dans les tables autorisées. Donc, tables autorisées, c'est une variable à l'intérieur de ce module garde-fous. Donc, si nous remontons, nous voyons ces tables autorisées. Elle a la table autorisée ainsi que les champs associés qui sont autorisés. La table qui est autorisée ainsi que les champs associés qui sont autorisés. Et c'est donc ce que c'est. Donc, il va essentiellement vérifier si la table qui a été passée, événements de connexion de l'appareil, est réellement ici ou non. Et si ce n'est pas le cas, il affichera une erreur et quittera. Alors, si nous entrons dans ceci, il l'a sauté car la table qui nous a été passée, événements de connexion de l'appareil, est dans les tables autorisées. Vous pouvez voir ici, événements de connexion de l'appareil. Donc, cette ligne de code divise les champs en une liste réelle. Alors, si nous entrons dans ceci, nous voyons les champs. Maintenant, il a été transformé en une liste. Et maintenant, il va parcourir tous les champs ici un par un. Et il va voir si le champ n'est pas dans les tables autorisées, la table appropriée, si le champ n'est pas là. Par exemple, il va regarder dans cette table autorisée, événements, ou plutôt, il va regarder dans cette table autorisée, c'est un dictionnaire et il va passer le nom de la table avec laquelle nous travaillons, qui est événements de connexion de l'appareil. Donc, il va retourner, il va retourner essentiellement cette liste de champs qui font partie des événements de connexion de l'appareil et il va vérifier chaque champ qui a été passé à la fonction, s'il est ici ou non. Et s'il en trouve un qui n'est pas ici, il y aura une erreur. Donc, pour le champ et les champs, si le champ n'est pas dans la table des tables autorisées, cela semble un peu confus, mais c'est comme ça que ça marche. Donc, si le champ, par exemple, l'heure générée n'est pas dans la table des tables autorisées. Donc, la table des tables autorisées est événements de connexion de l'appareil. Donc, il va retourner comme ceci. Si le champ n'est pas ici, générer une erreur. Nous pouvons regarder et ensuite il vérifie chacun. Et vous pouvez voir que ce champ est mis à jour à chaque itération. Donc, il vérifie l'IP distante. C'était bon. Il vérifie l'appareil distant. C'est bon. Et puis toutes les tables et tous les champs sont validés car

Tout le monde et Et cela va valider tout cela euh parce qu'ils faisaient tous partie des tables et champs autorisés. Et nous disons suivant. Et nous voyons qu'il a imprimé qu'ils étaient dans les directives. Et puis suivant euh je vais juste laisser cela se dérouler. Laisser l'agent fonctionner comme d'habitude. Cool. Donc, continuez avec chat dbt5 mini. Donc, si nous disons entrer le suivant, cela va réellement valider le modèle. Donc, nous avons choisi chat dbt5 mini pour le modèle et ensuite le garde-fou va réellement valider le modèle pour s'assurer que ce modèle est autorisé à être utilisé. Donc, si l'utilisateur, vous savez, en théorie, si l'utilisateur a d'une manière ou d'une autre injecté un autre modèle qui n'est pas sur la liste autorisée, par exemple. Donc, si nous entrons dans cela, cela va aller dans les garde-fous. Valider le modèle. Valider le modèle. Et ensuite, c'est une fonction vraiment similaire. Si le modèle n'est pas dans les modèles autorisés, alors lancez une erreur. Sinon, dites que c'est bon. Donc, modèles autorisés, c'est juste une autre variable à l'intérieur du module des garde-fous. Donc, modèles autorisés GPD5 GPT5 mini 4.1 4.1 nano et notre modèle qui a été passé est GPT5 mini et si nous regardons dans les modèles autorisés, nous le voyons ici. Donc, il est ici. Donc, il imprime le modèle sélectionné est valide ou il le sera. Donc, et il le fait. Et ensuite, à partir de ce moment, la chasse aux menaces va réellement, elle va faire la chasse aux menaces et ensuite trouver toutes les menaces et les imprimer à l'écran. Mais je n'ai pas besoin de faire ça. Donc, je vais juste l'arrêter. Donc, j'espère que cela donne une idée des garde-fous. Et ensuite, suivant, nous allons réellement injecter des choses qui ne sont pas autorisées afin que nous puissions observer le garde-fou arrêter l'agent de faire quelque chose. D'accord. Euh, je suis revenu. J'ai dû quitter l'hôtel et je suis revenu et mon nez est plus bouché que jamais, d'une manière ou d'une autre. Euh, mais maintenant nous allons exécuter ce code à nouveau et nous allons réellement l'arrêter au niveau du garde-fou et nous allons injecter quelque chose, par exemple, pour la table ou quelque chose pour les champs afin de lui faire essayer de faire une action qui est en dehors de ce qui est autorisé ou quelque chose qui est en dehors des garde-fous. euh et juste pour que nous puissions observer ce qui se passe, n'est-ce pas ? Donc, si vous vous souvenez, c'est facile pour nous de faire cela parce que nous possédons réellement le code et nous pouvons l'exécuter directement, mais normalement, ce serait un peu plus difficile à faire car le code, ou plutôt l'agent, serait contrôlé par un utilisateur distant qui émettrait simplement des commandes. Donc, au lieu d'émettre des commandes normalement, nous allons déboguer le code et ensuite nous allons soit ajuster les garde-fous, soit changer les valeurs des variables au milieu de l'exécution de notre code pour vous montrer ce qui se passe si l'agent essaie de faire quelque chose qui est en dehors des paramètres ou qui est en dehors des garde-fous ou essaie de faire quelque chose que le garde-fou bloquerait. Donc, cela aura beaucoup plus de sens une fois que nous aurons réellement fait cela. Mais le premier, je vais voir, nous avons nos garde-fous qui valideront la table et les champs dans notre requête. Donc, je vais juste exécuter cela à nouveau. Je vais faire la même requête facile. N'hésitez pas à vous écarter de cela et à faire une requête différente si vous le souhaitez. Donc, je vais déboguer. Je vais juste continuer à faire ça. je suis inquiet que Windows Target One ait pu être connecté malicieusement. C'est facile de comprendre cela. Donc, que voulez-vous ? Je vais dire ça et ensuite cela va faire tout le processus. Cela va obtenir le contexte de la requête. Cela va construire tout cet objet qui donne du contexte sur les tables à interroger ou la table à interroger, les champs, est-ce que c'est à propos d'un utilisateur, etc. Vous vous souvenez de ça ? Donc, il est sorti et a décidé de tout cela. Il a décidé que nous allons regarder dans la table des événements de connexion de l'appareil. Il a décidé que ce sont les champs, etc. Et donc maintenant, la prochaine chose qu'il va faire, c'est qu'il va tenter de valider la table qu'il a décidée ici et il va tenter ou ici et ensuite il va tenter de valider les champs et la fonction qui fait cela est à l'intérieur du module des garde-fous. Donc, si je dis entrer, cette variable de table a reçu les événements de connexion de l'appareil et cette variable de champs a reçu ces champs. Ce sont ce que l'agent a décidé d'utiliser pour interroger et c'est la fonction de validation pour s'assurer que la table et les champs sont autorisés à être interrogés. Donc, la première chose qui se produit, c'est qu'il va vérifier si cette table d'événements de connexion de l'appareil est dans les tables autorisées et nous pouvons voir que c'est le cas, juste ici, événements de connexion de l'appareil, mais si vous vous souvenez, nous pouvons en fait, si nous déboguons comme ça, nous pouvons réellement modifier la valeur des variables en direct. Je vais utiliser une table différente. Je vais assigner un nom de table différent. Donc, laissez-moi réfléchir ici dans les tables autorisées. Il y a une table appelée journaux d'audit qui est dans Azure, par exemple. Je vais vous montrer. Hé, donc c'est une table réelle comme vous pouvez le voir, il y a des choses dedans. Donc, je vais en fait changer cette valeur de table, la valeur que je vais changer en journaux d'audit car c'est une table réelle mais elle n'est pas réellement dans notre liste de tables autorisées comme vous pouvez le voir. Comme vous pouvez le voir, il n'y a pas de journaux d'audit ici. Donc, si nous disons entrer, cela va évaluer. Si nous survolons une table maintenant, c'est maintenant des journaux d'audit car nous l'avons changée. Cela va regarder pour voir si elle est à l'intérieur d'ici. Et si elle n'est pas ici, ces choses vont se produire. Donc, elle n'était pas là. Donc, il a imprimé une erreur. La table journaux d'audit n'est pas dans la liste autorisée. Sortie. Nous pouvons dire entrer et ensuite il lance une erreur. Il sort avec le code d'erreur un, ce qui signifie que quelque chose de mal s'est produit. Si nous entrons à nouveau, le programme se ferme. Donc, c'est une sorte de problème "entre guillemets". Nous devrions avoir une sorte de journalisation disponible qui enregistrera quand quelque chose comme cela se produit. Par exemple, cela enregistrerait soit dans un fichier local, soit dans une base de données ou quelque chose comme ça. Et ensuite, au lieu de quitter le programme, peut-être que cela devrait retourner faux, par exemple. Et ensuite, l'agent peut avoir l'opportunité de se corriger ou quelque chose comme ça. Mais pour l'instant, le programme se termine simplement. Donc, je vais exécuter cela à nouveau. Dites démarrer le débogage. Et je vais utiliser la même invite juste parce que cela rend les choses faciles. Copiez ceci. Que souhaitez-vous faire ? La même chose. Cela va obtenir le contexte de la requête comme d'habitude. Il a obtenu tout cela. Euh, nous allons euh euh je vais en fait, d'accord, laissez-moi arrêter cela en fait. euh au lieu de modifier les variables en direct, je vais aller dans les garde-fous et ensuite je vais changer l'un des garde-fous. Donc, euh parce que j'utilise la même invite, cela va essayer de valider la table et ensuite cela va valider les champs pour cette table. Donc, au lieu de l'heure générée, laissez-moi voir. Euh, je vais en fait supprimer le champ heure générée des événements de connexion de l'appareil. Donc, pour le rendre non autorisé. Donc, maintenant, l'heure générée n'est plus un champ autorisé pour la table des événements de connexion de l'appareil. Et ensuite, nous pouvons voir ce qui se passe avec cela. Donc, je vais exécuter cela à nouveau. Démarrer le débogage. Je vais coller ceci. Je suis inquiet. Cela va obtenir le contexte de la requête, puis le code va planter ici juste avant de valider les tables et les champs. Donc, nous allons entrer dans cela et cela entrera dans la fonction de validation de table et de champs. Donc, c'est une table, événements de connexion de l'appareil, et ensuite les champs, vous pouvez voir qu'il essaie de valider si ces champs sont autorisés, comme l'heure générée, le nom du compte, etc. Donc, si nous entrons, cela va valider la table. Donc, événements de connexion de l'appareil, c'est ici. C'est à l'intérieur des tables autorisées, événements de connexion de l'appareil. Donc, si nous devrions passer par-dessus, puis cela va euh transformer les champs. C'est essentiellement une chaîne. Cela va transformer cette chaîne brute en une liste. Donc, nous voyons cela maintenant, c'est une liste. Et ensuite, maintenant, cela va parcourir chaque champ et ensuite vérifier si ce champ est dans la liste des champs autorisés qui se trouve dans cette variable de tables autorisées. Donc, c'est un dictionnaire. Ces tables autorisées sont un dictionnaire et nous lui passons la clé des événements de connexion de l'appareil. Donc, ce que cela signifie, c'est qu'il va regarder dans les tables autorisées, puis la clé des événements de connexion de l'appareil, puis il va retourner cette liste de propriétés ou de champs, puis il va essayer de vérifier si chacun de ceux-ci est dans la liste des champs autorisés pour ce dictionnaire de tables autorisées. Donc, si nous disons suivant, la première chose qu'il va vérifier est l'heure générée. L'heure générée est-elle à l'intérieur des tables autorisées sous événements de connexion de l'appareil ? Elle n'est pas ici. Donc, nous disons entrer et ensuite il commence immédiatement à imprimer l'erreur car une table ou un champ essaie d'être traité qui n'existe pas réellement dans notre garde-fou. Dit erreur, le champ heure générée n'est pas dans la liste des champs autorisés pour la table événements de connexion de l'appareil et ensuite il sort. Nous pouvons dire suivant, suivant et ensuite il sort. C'est parce que nous l'avons effectivement supprimé des événements de connexion de l'appareil. Donc, je vais remettre cela. Et nous pouvons faire cela d'une autre manière aussi, comme nous pouvons changer le nom de l'un d'eux. Donc, quand il essaie de valider le nom du compte, c'est le nom du compte qui n'est pas ici car le nom du compte x est ici et cela échouera. Donc, je vais juste remettre cela. Et ensuite, la prochaine chose que nous allons valider est le modèle réel qui est ici, ou je vais le casser. Je vais injecter un modèle qui n'est pas dans la liste autorisée. Donc, je vais exécuter cela une fois de plus. Je vais utiliser ceci. Je vais coller. Je vais le laisser valider les tables. Donc, je vais juste passer par-dessus cela car cela va valider. C'est bon. Les champs et les tables ont été validés et sont conformes aux directives autorisées. Et ensuite, maintenant, la requête va s'exécuter contre log analytics. Elle va rassembler tous les journaux trouvés, 300. Et ensuite, à ce stade, c'est là que nous disons le modèle que nous voulons utiliser. Donc, je vais vous montrer quelque chose d'intéressant ici. euh continuez avec GPT5 mini. euh nous pouvons soit taper un nom de modèle, soit lister les modèles autorisés. Donc, je vais dire par exemple, je vais essayer d'utiliser comme GBT 40 par exemple parce que c'est un modèle légitime. Il n'est juste pas sur notre liste. Donc, je vais dire GBT40 et ensuite il dit appuyez sur entrée pour continuer. Tapez un nom de modèle valide. D'accord. Donc, ce n'est pas autorisé, cela ne me permet pas de le faire. Oui. Donc, je vais dire GPT5 mini. Appuyez sur OK. Donc, je vais dire que j'appuie sur entrée pour continuer avec ce modèle. Et ensuite, maintenant le garde-fou va commencer, plutôt l'agent va vérifier s'il est autorisé à le faire. Et les garde-fous vont l'arrêter si nous avons injecté, ou plutôt si nous essayons d'utiliser un modèle qui n'est pas autorisé. Donc, ce garde-fou encore, c'est un module de garde-fou qui est ici et ensuite il va utiliser la fonction de validation du modèle. Donc, garde-fous et ensuite il y a une fonction de validation du modèle ici. Elle est ici. Donc, si nous retournons à cela et que nous entrons dans cela, nous pouvons voir qu'il essaie de valider GPT5 mini et il va vérifier si GPT5 mini est dans les modèles autorisés, ce qui est le cas. S'il, désolé, s'il n'est pas là, il va imprimer un message d'erreur, mais s'il est là, il va dire oh d'accord, c'est valide et ensuite il laissera le programme continuer. Donc, actuellement, le modèle est réglé sur GPT5 mini. Donc, si je change directement cela, si je vais déboguer, n'est-ce pas, je peux changer cela en GPT40 au lieu de GPT5 mini, comme ceci. Et ensuite, maintenant, si je dis entrer, le modèle est maintenant GBT40. Et cela signifie qu'il n'est pas dans les modèles autorisés car nous ne voyons pas 40 ici. Donc, il va juste imprimer le message d'erreur, puis il va sortir comme ceci. Modèle GBT4 n'est pas autorisé. Je peux dire suivant et ensuite terminer. Donc, c'est tout pour les garde-fous. euh bien sûr, il y a beaucoup plus de choses que vous pouvez faire. Vous pouvez mettre des garde-fous autour de pratiquement n'importe quoi. euh encore une fois, comme les informations personnellement identifiables, nous pouvons créer une sorte de fonctionnalité qui empêche ces choses d'être soumises au modèle. euh ou nous pouvons faire quelque chose qui empêche l'utilisateur d'interroger trop de journaux, trop loin dans l'historique, comme vous savez, si nous essayons de dire comme un mois ou trois mois en arrière ou quelque chose comme ça, car nous savons que la plupart du temps, ce sera trop de journaux à fournir à l'agent ou au modèle, n'est-ce pas ? Et cela va gaspiller de l'argent en interrogeant log analytics. Donc, il y a beaucoup d'autres choses que nous pouvons faire. euh mais j'espère que cela vous donne une idée de ce que sont les garde-fous. C'est juste quelque chose en place pour empêcher l'agent de faire quelque chose que vous jugez qu'il ne devrait pas faire. Que ce soit pour garder l'utilisateur physiquement en sécurité ou pour empêcher l'entreprise de dépenser trop d'argent, etc. Donc, je pourrais vous encourager à jouer avec ce module de garde-fous. Et ensuite, si vous voulez devenir aventureux, vous pouvez y ajouter des modèles. Donc, par exemple, laissez-moi voir si je peux trouver ceci. Comparaison de modèles OpenAI, par exemple. Je pense que c'est ici. Donc, il y a une tonne de modèles que vous pouvez utiliser. Donc, par exemple, je pense que GPT5 Nano, nous ne l'utilisons pas. Donc, vous pouvez obtenir GPT5 Nano et ensuite vous pouvez en fait, laissez-moi mettre ceci, je vais mettre ce lien dans le code pour vous. Si vous le souhaitiez, vous pourriez ajouter une autre entrée ici pour GPT5 Nano et ensuite vous pouvez expérimenter un peu avec cela. Donc, vous faites comme, vous savez, virgule, entrée, et essentiellement juste comme coller une autre de celles-ci essentiellement. Donc, et ensuite supprimez la dernière virgule. Et ensuite, vous voulez juste vous assurer de remplir tout cela pour que ce soit approprié et que ce soient les bonnes données et tout. Je vais effacer ceci. Je voulais juste montrer que, par exemple, vous pourriez faire cela ou vous pourriez ajouter, par exemple, vous pourriez ajouter les journaux d'audit et ensuite les champs autorisés. Ensuite, vous devrez ajuster la variable des outils avec laquelle nous avons travaillé dans la leçon précédente et tout, mais je ne sais pas. Je vais juste parcourir ceci et ensuite essayer de jouer avec les garde-fous juste pour avoir une meilleure intuition. Et oui, encore une fois, je sais que cela devient un peu compliqué. Donc, si vous rencontrez des problèmes ou si vous avez des questions, allez absolument dans la communauté et demandez tout ce que vous voulez. Mais oui, nous vous verrons dans la prochaine leçon. Bienvenue de retour. Dans cette leçon, nous allons nous concentrer très fortement sur l'ingénierie des invites, spécifiquement pour l'invite qui est utilisée pour exécuter la chasse aux menaces, comme fouiller dans les journaux, puis construire le rapport de chasse aux menaces réel qui sort. Et précédemment, nous avons survolé jusqu'à environ ici où nous avons pris l'entrée normale de l'utilisateur. Nous avons dérivé un tas de données structurées à partir de cela, puis nous avons pu interroger log analytics workspace avec ces données. Et ensuite, à partir de cette leçon, nous allons prendre les journaux de log analytics workspace que la requête a retournés. Et ensuite, nous allons passer pas mal de temps à montrer comment l'invite réelle est construite qui est utilisée pour faire la chasse aux menaces. Donc, nous allons examiner comment l'invite utilisateur est construite. Nous allons examiner l'invite système réelle qui est utilisée pour la chasse aux menaces. Et ensuite, nous allons réellement exécuter la chasse dans cette leçon. Ensuite, nous allons terminer à partir de là. Mais la majorité de cette leçon et la priorité de cette vidéo est de couvrir comment cette invite utilisateur est réellement construite, car ce n'est pas compliqué, mais il y a beaucoup de pièces mobiles. Donc, avant de passer au code, je vais juste l'expliquer un peu ici. Donc, comme toujours, pas toujours, mais la plupart du temps, lorsque nous envoyons une invite à chat GBT, nous avons le message système et ensuite le message utilisateur. Et ensuite, je vais expliquer cela à nouveau car c'est peut-être bien de l'entendre. Mais en gros, le message système est la façon dont nous voulons que chat GPT se comporte et lui donner du contexte sur ce qu'il est censé faire. Et ensuite, le message utilisateur est comme les instructions spécifiques que nous voulons que chatb fasse ou les choses, oui, les instructions ou les choses auxquelles nous voulons qu'il se réfère lorsqu'il essaie de faire la chose que nous lui demandons. Donc, message système, nous allons couvrir tout cela dans le code, mais le message système, c'est en gros, nous disons que vous êtes une IA de chasse aux menaces en cybersécurité, entraînée pour soutenir les analystes SOC en identifiant les mauvaises choses dans les données de journal de Defender for Endpoint, Azure Active Directory, Azure Resource Logs. Vous êtes censé faire ceci et cela. Et il y a beaucoup de choses ici, mais nous allons regarder cela dans le code un peu plus tard. Donc, c'est le message système. Nous donnons juste au modèle le contexte sur la façon dont nous voulons qu'il se comporte et ce que nous voulons qu'il fasse. Et ensuite, le message utilisateur, c'est la partie compliquée entre guillemets. Vous voyez qu'il y a beaucoup de parties différentes ici. C'est assez représentatif de cela. Mais en gros, il y a quatre parties. La première partie est la demande. C'est la chose que l'analyste SOC humain dit à l'agent. Par exemple, je suis inquiet que Windows Target 1 ait pu être connecté malicieusement ou je suis inquiet que notre locataire Active Directory ait pu être compromis la semaine dernière ou quelque chose comme ça. Ces instructions humaines et ensuite ces instructions spécifiques à la table. Ce sont des instructions spécifiques de chasse aux menaces pour quelle que soit la table dans laquelle se trouvent les journaux et quelle que soit la table qui a été décidée d'utiliser pour la chasse, comme des instructions spécifiques sur la façon de chasser avec cette table. Et ensuite, cette section est la façon dont nous voulons qu'il formate les données lorsqu'il renvoie la réponse. Comme lorsqu'il renvoie les informations de chasse aux menaces, les choses qu'il a découvertes. C'est comme le schéma ou le format des données. Et ensuite, la quatrième partie de cette invite sont les journaux réels qui sont revenus d'un espace de travail log analytics, comme les journaux d'événements de connexion de l'appareil, les journaux d'événements de processus de l'appareil ou quoi que ce soit d'autre. Et ces deux choses énormes ensemble, le message système et ensuite le message utilisateur. Cela sera combiné en une liste, puis envoyé au modèle. Et ensuite, c'est la chose où les jetons peuvent être trop gros. En gros, dans les leçons précédentes, lorsque nous vérifions le quota et la taille des jetons et tout, cette invite est gigantesque, en gros, ou elle peut être gigantesque en fonction de ce que vous interrogez. Mais oui, c'est ce que nous allons faire. Je pense que ce n'est pas aligné. Cool. Donc, comme toujours, j'inclurai le code pour cela. Donc, décompressez-le simplement et placez-le sur votre bureau ou où vous voulez. Je l'ai mis sur mon bureau. il sera appelé ingénierie des invites ou quelque chose de très similaire. Donc, si vous avez quelque chose d'ouvert ici déjà, vous pouvez dire fermer le dossier. Ceci est VS code et ensuite nous irons fichier puis ouvrir le dossier et ensuite le mien est sur le bureau et ensuite c'est celui de l'ingénierie des invites. Ensuite, comme toujours, assurez-vous d'avoir vos clés ici, votre clé API. Si vous n'en avez pas ou si elle a expiré, vous pouvez toujours en obtenir une autre ici. Et ensuite, comme toujours, et ensuite, comme toujours, assurez-vous simplement que vous êtes connecté à une connexion. Donc, ouvrez le terminal si vous êtes sur Mac ou l'invite de commande ou la ligne de commande si vous êtes sur Windows. Et nous dirons une connexion juste pour nous assurer que nous sommes connectés. Et vous vous connecterez avec votre identifiant de cyber-plage. Prenez l'abonnement et nous devrions être prêts. D'accord, donc pour récapituler, nous allons nous concentrer principalement sur la récupération des journaux, puis nous plongerons dans la partie du code qui construit les invites et envoie les invites à GPT. Donc, nous irons dans main. Ouvrez main. Et ensuite, voyez où les invites sont construites. Donc, je vais juste l'arrêter ici. C'est juste après que les journaux aient été récupérés de log analytics workspace. Donc, je vais juste l'arrêter ici. Mettez un point d'arrêt ici. Et ensuite, nous allons exécuter et ensuite déboguer le débogueur Python. par le fichier et ensuite je vais faire défiler vers le haut et ensuite je vais continuer à utiliser cette invite. Vous pouvez utiliser votre propre machine virtuelle pour cette invite au lieu de Windows target one. J'utilise juste cela pour des raisons de facilité et pour je suis plus intéressé par la compréhension du flux de travail et la compréhension du code derrière l'agent. Donc, je ne mets pas beaucoup d'invites différentes. J'utilise juste celle-ci car elle a tendance à avoir du sens pour la plupart des gens, mais vous pouvez en utiliser une différente si vous le souhaitez. Donc, je vais juste exécuter cela et ensuite cela devrait planter ici. Cela a planté. Et ensuite, je vais juste jeter un œil à ce contexte de requête et métadonnées. 4 jours, 96 heures. Ce truc de justification. Et c'est la requête KQL qu'il a construite. Et ensuite, nous sommes un nombre d'enregistrements. Donc, je vais passer par-dessus cela. Passer par-dessus cela. Passer par-dessus cela. Et ensuite cette partie, ce code ici est ceci. Et ceci aussi. C'est la même chose. Donc, c'est en fait ce module de message utilisateur de chasse aux menaces. Ce module a cette fonction en lui. Donc, construire l'invite de chasse aux menaces dans le cadre du module de gestion des invites. Et ensuite, après que cette fonction, oh mon dieu, et ensuite après que cette fonction s'exécute. Oh mon dieu, cette chose me dérange. Il suffit de supprimer cette modification ou de la modifier. Qui que ce soit qui édite cela. Donc, après que cette fonction s'exécute, tout ce message utilisateur, cette partie verte, sera assignée à cette variable après que la fonction s'exécute. Donc, au lieu de passer par-dessus ou au lieu de passer par-dessus, nous allons entrer et ensuite regardons juste ce qui se passe ici, très rapidement. Donc, cette fonction prend trois arguments. Donc, l'argument de l'invite utilisateur, le nom de la table et ensuite les données du journal. Et ensuite, cette invite utilisateur, nous pouvons regarder ce qu'elle est. Je suis inquiet pour Windows target one. C'est juste essentiellement le message de l'utilisateur. Le nom de la table du contexte de requête. C'est la table que GPT a décidé que nous devions interroger. Et ensuite, ces résultats de journal, enregistrements de résultats de requête de journal. Ce sont toutes les données du journal. Donc, ce sera une chaîne énorme à l'intérieur d'ici. Comme une chaîne énorme de tous les journaux qui ont été trouvés si nous, c'est juste beaucoup de données de journal. Donc, nous pouvons dire entrer, entrer, entrer, puis encore une fois. Et ensuite, maintenant, vous avez remarqué si nous cliquons sur explorer, nous avons déménagé dans la gestion des invites. Je vais double-cliquer dessus, le module de gestion des invites et ensuite nous sommes à l'intérieur de construire l'invite de chasse aux menaces. Donc, si nous passons, nous descendons, construisant les instructions d'invite de chasse aux menaces. Donc, la première chose, il va récupérer les instructions et ce sont des instructions de chasse aux menaces spécifiques à la table qui a été utilisée. Donc, il va regarder dans cette variable d'invites de chasse aux menaces et récupérer les instructions spécifiques pour ce nom de table, événements de connexion de l'appareil. Donc, instructions d'invite de chasse aux menaces, c'est juste un membre de ce module de gestion des invites. Donc, nous pouvons le trouver quelque part ici. Laissez-moi le trouver, invites. Je vais copier ceci. D'accord, donc c'est ici et c'est un grand dictionnaire. Ça ne ressemble pas vraiment, mais c'est parce que c'est la clé et ensuite c'est la valeur et la valeur est énorme. C'est pourquoi. Donc, je vais le réduire et ensuite celui que nous allons interroger est les événements de connexion de l'appareil ou la table que nous utilisons. Donc, je peux réduire ces paires clé-valeur et ensuite nous allons regarder les instructions des événements de connexion de l'appareil. Donc, c'est la clé en fait pour les événements de connexion de l'appareil, les instructions de chasse aux menaces, et ensuite c'est la valeur. C'est juste une chaîne de plusieurs lignes, très grande. Donc, ces instructions spécifiques de chasse aux menaces que nous allons envoyer à chat GBT dans notre cas. Donc, vous pouvez le lire. Vous êtes une IA experte en chasse aux menaces analysant spécifiquement les événements de connexion des appareils MDE. Et ensuite, il dit comme se concentrer sur le comportement d'authentification anormal et le mouvement latéral. Donc, nous pourrions ajouter plus de choses ici car c'est ce qui donne à GBT le contexte de ce que nous voulons qu'il fasse. Et c'est un peu limité. Cela pourrait être beaucoup plus grand pour être honnête. Cette invite, car ce ne sont pas les seules choses qui peuvent se produire dans la table des événements de connexion de l'appareil, mais ce sont les choses principales ou générales qui peuvent se produire. Détecter des types de connexion inhabituels. connexion locale d'utilisateurs distants, échecs répétés, etc. Donc, cela donne juste à GPD le contexte de ce qu'il doit faire. Donc, si nous retournons à, je vais dire entrer. Donc, nos instructions contiennent maintenant ceci, les instructions spécifiques à la table des événements de connexion de l'appareil. Et ensuite, ceci ici, cela construit l'invite complète réelle pour notre chasse aux menaces. Donc, cette variable, elle contiendra ceci. Donc, l'utilisateur, c'est juste construire une grande invite. Donc, elle obtient la demande de l'utilisateur et ensuite c'est quelle que soit cette invite utilisateur. Je suis inquiet pour Windows target one et ensuite les instructions de chasse aux menaces. Elle utilisera ces instructions ici. Ce sont les instructions spécifiques de chasse aux menaces spécifiques à la table. Et ensuite, les instructions de formatage sont ici. C'est juste comment nous voulons que GPT formate ou structure les données qui sont retournées. Donc, si nous cliquons sur ces instructions de formatage, je vais copier ceci. C'est juste une autre variable à l'intérieur de ce module. Donc, je vais rechercher les instructions de formatage et nous pouvons le voir ici. euh, ce sont des instructions pour GPT. Retournez vos découvertes dans le format suivant et c'est un dictionnaire. C'est une clé. Et ensuite, la valeur est un tableau de découvertes ou une liste de découvertes. Et nous lui disons s'il n'y a pas de découvertes, retournez un tableau vide comme ceci. Et ensuite, c'est important, voici le schéma que vous devez utiliser. Le schéma signifie juste la structure des données. Donc, vous pouvez le changer comme vous le souhaitez. Mais c'est ainsi que j'ai trouvé pour formater les menaces que j'ai trouvées. Donc, découvertes, n'est-ce pas ? Et ensuite, c'est le début de la liste. Et ensuite, c'est comme la première découverte. Ensuite, nous avons comme un titre, une description, des informations MITER comme le cadre d'attaque MITER. Donc, il listera les tactiques, les techniques, les sous-techniques, etc. Et ensuite, ce sont les lignes spécifiques, les lignes de journal que GPT a trouvées qui étaient considérées comme pertinentes pour cette menace. Et ensuite, le niveau de confiance, nous pouvons dire faible, moyen, élevé. Et nous pouvons ajouter quelque chose ici aussi comme un, par exemple, extrêmement faible, extrêmement faible. Et ensuite, je peux dire comme, vous savez, je montre juste que c'est vraiment flexible ou c'est un LLM, n'est-ce pas ? Donc, vous pouvez y mettre littéralement n'importe quoi. vous n'avez pas à faire cela, je l'ajoute juste pour voir ce qui se passe. Et ensuite, les recommandations. Ce sont les recommandations pour qu'il en trouve. Je les ai codées en dur ici. Donc, si vous voulez ajouter une autre recommandation si c'est trop bas, vous savez, nous pouvons dire ignorer. Oh, c'est déjà là. C'est tellement drôle. Je peux ajouter quelque chose, par exemple, quelque chose comme ceci. Et ensuite, les indicateurs de compromission. Ce sont les IoC réels que le modèle a trouvés. Donc, cela pourrait être une ligne de journal spécifique ou quelque chose comme ça ou quelque chose qui l'a déclenché à penser que c'est la chose qui a causé la compromission ou c'est l'activité malveillante. Cela pourrait être un journal ou une série de journaux. Et ensuite, les balises pertinentes. Nous pouvons ajouter plus de choses ici. et ensuite toutes les notes que toutes les notes qu'il veut inclure. Donc, c'est juste le schéma pour la façon dont les données doivent être sorties par chat GPT et vous pouvez changer cela à nouveau et ensuite ici. Donc, si nous disons entrer, tout ce que cela fait, c'est de mettre ensemble une grande chaîne. Donc, par exemple, il met juste Oh, cette chose est hors de contrôle parce que j'ai ajouté Oh mon dieu. Laissez-moi annuler cela. Cela perturbe les lignes. Donc, c'est l'invite réelle, comme l'invite utilisateur. Tout ce grand truc ici est cette partie verte. Donc, si nous disons entrer, cela va le retourner. Nous disons entrer et ensuite tout cela a été retourné à ce message utilisateur de chasse aux menaces. Il a juste été formaté dans le format de message entre guillemets qui est envoyé à chat GBT. Donc, il dit comme utilisateur et ensuite le contenu. Et c'est notre énorme invite qui a été créée. Et ensuite, le prochain, l'invite système va être créée. L'invite système est simplement ceci. C'est assez simple. Donc, si nous regardons dans le module de gestion des invites et ensuite le système d'invite de chasse aux menaces. Donc, nous pouvons double-cliquer sur la gestion des invites et ensuite nous pouvons rechercher cela. C'est juste ceci pour donner à chat GPT le contexte sur la façon dont nous voulons nous comporter et ce que c'est. Donc, vous pouvez prendre le temps de lire ceci si vous le souhaitez. Votre IA de chasse aux menaces en cybersécurité. Vous êtes censé faire ces choses. Votre ton doit être ceci. Évitez ce qui suit. Et ensuite, vous assistez des analystes qualifiés, pas des utilisateurs finaux. Et cela donne juste du contexte sur la façon dont nous voulons qu'il se comporte. Donc, nous retournons à main. Nous disons suivant. Entrez dans ceci. Maintenant, le système, le système d'invite est stocké ici. Et ensuite, ce message de chasse aux menaces sera une combinaison des deux. Donc, c'est comme une liste avec le message système et le message utilisateur. Donc, nous pouvons dire suivant. Et ensuite, le reste de ces choses, cela va compter les jetons et ensuite sélectionner le modèle et tout le reste. Donc, je me demande si je devrais, je vais juste laisser cette chasse se terminer. Mais avant cela, je veux réellement exécuter cela dans le chat GBT, comme la version réelle du navigateur, pour que nous puissions l'observer. Donc, par exemple, cliquez sur ce débogage, puis allez réduire ceci, réduire ceci et ce qui a été fait, cette chasse aux menaces. Donc, je vais obtenir le message système et ensuite le message utilisateur et je vais les mettre à l'intérieur de la version navigateur de GPT juste pour vous montrer ce qui se passe réellement en arrière-plan. Donc, le message système de chasse aux menaces est ici et ensuite je vais obtenir le contenu. Donc, vous pouvez double-cliquer dessus et le copier et ensuite je vais aller à chat GBT et ensuite le coller. Bien que je vais effacer les guillemets de début et de fin. Donc, tout cela est le message système. euh et encore une fois, lorsque vous utilisez la version web de chat DPD, il y a déjà un message système en arrière-plan utilisé. Je colle juste ceci ici pour plus de contexte. Et ensuite, je vais obtenir le message utilisateur réel, comme le long, qui est ici. Donc, le message utilisateur de chasse aux menaces et ensuite le contenu est ici. Maintenant, je vais copier ceci, revenir et je vais le coller et supprimer les guillemets et vous pouvez voir ce que c'est. Donc, rappelez-vous, nous venons de coller ces choses, le message système, puis le message utilisateur, et ensuite le message utilisateur est composé de l'invite initiale, des instructions spécifiques à la table, comment nous voulons qu'il soit formaté, puis les journaux réels et nous pouvons les voir reflétés ici. Donc, c'est le message système ici. Message système, puis c'est le message utilisateur ici, puis ce sont les instructions de chasse aux menaces. Ce sont des instructions spécifiques à la table, puis il devrait y avoir le format. Oh, voici les instructions de formatage qui sont ici. Et ensuite, la dernière chose sont les journaux qui sont, vous pouvez clairement voir qu'ils commencent ici, journaux ci-dessous. Donc, je vais copier ceci de GPT et ensuite je vais le coller dans Claude également. Donc, je vais juste exécuter cela et je vais exécuter cela et pendant que cela se passe, je vais retourner à notre code et je vais juste reprendre le code. Donc, tout ce que cette chose a fait, c'est qu'elle a juste créé une grande invite à mettre dans chat GBT, mais tout se passe programmatiquement en arrière-plan. Donc, je vais appuyer sur entrée pour qu'il sélectionne ce modèle. Donc, cette chasse cognitive est en cours. La chasse est en cours. Donc, si je retourne à notre version navigateur et que je regarde ce qui se passe. euh, le navigateur GPT analyse toujours les modèles d'attaque. Nous pouvons cliquer dessus probablement et voir ce qu'il pense. Et ensuite, Claude fait quelque chose de très intéressant. Donc, cela s'est terminé, il a trouvé trois résultats et nous pouvons dire entrer. Et ensuite, peut-être que dans une leçon future, je couvrirai comment les menaces sont réellement formatées. Donc, mais pour l'instant, je vais juste dire entrer et laisser les jeter à l'écran. Nous faisons défiler vers le haut et nous pouvons voir les menaces potentielles. Et ensuite, je ne vais pas, je ne passerai pas de temps à vraiment regarder ceux-ci, mais vous pouvez faire défiler les vôtres un peu. Je vais les faire défiler et vous pouvez prendre le temps de les regarder. euh, et vous pouvez voir en fait, si vous vous souvenez, désolé de sauter partout, allez dans la gestion des invites très rapidement et ensuite recherchez le formatage. Donc, si vous voyez ces instructions de formatage où nous lui avons dit comment nous voulons que le schéma soit, la structure des menaces, c'est l'objet qui est créé en arrière-plan. Mais la chose qui est jetée à l'écran est formatée d'une manière plus conviviale, avec laquelle nous traiterons dans une leçon future. Mais je veux vous montrer quelque chose. Donc, c'est le format de la menace, n'est-ce pas ? Les données. Donc, si nous allons dans notre explorateur, ce threats.jsonl contient en fait toutes les menaces qui ont été trouvées lors de nos chasses précédentes. Et le formatage de ces données ici, ces objets JSON, sera conforme à ces instructions de formatage. Ce threats.json L est un peu difficile à voir comme ça, mais vous pouvez juste me faire confiance, je suppose, c'est juste un grand objet JSON formaté de la manière que nous avons spécifiée. Donc, si nous retournons, nous pouvons regarder notre GBT et cette chose est toujours en cours. Je me demande si elle fait littéralement encore quelque chose. Il semble que oui. Et c'est la sortie de GPT. Il semble qu'il n'ait trouvé qu'une seule chose. Je ne sais pas si c'est parce que la version navigateur de chat GPT fait quelque chose d'étrange. Je ne suis pas vraiment sûr, mais il semble qu'il ait trouvé une chose. et il l'a juste jetée à l'écran comme ça. Et vous pouvez la regarder. C'est probablement similaire à ce qui a été trouvé ici. Et ensuite, vous pouvez voir les lignes de journal, les lignes de journal spécifiques dont il parlait, les indicateurs de compromission, comme ce sont les mauvaises adresses IP qu'il a trouvées. euh les comptes ciblés, le type d'action de l'appareil. Et ensuite, si nous regardons Claude, il l'a un peu mieux formaté pour nous. Oh, il est toujours en cours. C'est vraiment intéressant. Mais oui, mon point avec ceci est que je veux juste vous montrer qu'en fait, ce que GPT, notre agent plutôt, fait, c'est juste qu'il construit une grande invite comme celle-ci. Il construit juste cette invite avec le message système pour le contexte et il fournit autant de contexte que possible avec ce que l'utilisateur veut, comment chasser dans cette table spécifique, comment formater la sortie, puis les journaux réels pour plus de contexte. Il crée juste une invite géante, puis la jette dans GPT. Et ensuite, GPT analysera diligemment les journaux en fonction de nos invites, puis sortira les données en fonction de notre schéma ou de notre format que nous avons fourni. Oui, vous n'avez pas à utiliser Claude, d'ailleurs. Je voulais juste vous montrer, je voulais juste vous montrer ça. euh, mais si vous voulez, je recommanderais de le faire. euh, il y a beaucoup de choses qui ont été utilisées dans cette chose de gestion des invites pour formuler réellement ces invites. Donc, par exemple, les invites générales de chasse aux menaces comme les événements réseau des appareils, toutes celles-ci peuvent être affinées et améliorées, n'est-ce pas ? Donc, par exemple, nous pouvons copier ceci, par exemple, puis nous pouvons ouvrir une nouvelle instance de chat GBT et nous pouvons dire quelque chose comme, cette invite peut-elle être améliorée ou complétée de quelque manière que ce soit ? Je veux m'assurer que je ne limite pas le LLM d'aucune manière. Juste pour exemple, comme n'importe laquelle de celles-ci peut être améliorée. Ai-je pris la bonne ? Non, ce n'est pas le cas. Oups. Laissez-moi aller aux événements de connexion de l'appareil, c'est ce que je voulais obtenir. Je veux dire, je suppose que ça n'a pas d'importance, mais nous utilisons généralement beaucoup celui-ci car il est facile à comprendre. Laissez-moi, événements de connexion de l'appareil. D'accord, donc nous pouvons faire ceci, par exemple. Mais encore une fois, le problème est que plus votre invite est verbeuse et robuste, en théorie, meilleure sera la sortie. Mais vous devez juste trouver un équilibre entre, vous savez, utiliser trop de jetons et comme, je suppose, la verbosité et la concision. Si c'est plus verbeux, vous pouvez lui dire plus de choses à faire, mais cela utilisera plus de jetons. euh, mais si l'invite est vraiment serrée et concise, elle utilisera moins de jetons, mais bien sûr, vous savez, elle peut ne pas être aussi complète, je suppose. Donc, c'est un excellent début. Voici une invite plus forte et plus complète prête à être copiée. Blah blah blah invite à déposer améliorée. Donc, à peu près, je suppose que nous pouvons copier ceci. euh, ceci n'est pas vraiment bon car il essaie de spécifier des délais et des choses qui ne sont pas vraiment, le délai est géré en dehors de cette invite, je pense, n'est-ce pas, lorsque nous collectons les journaux en premier lieu. Donc, vous pourriez vouloir affiner cela un peu. Donc, eh bien, en tout cas, dans le format de sortie, bien sûr, donc nous n'avons pas besoin de spécifier le format de sortie car nous le faisons déjà ailleurs. Donc, juste pour être, je suppose, conscient de ce que vous collez dans vos instructions de chasse aux menaces, mais je vais juste, juste pour le plaisir, je vais juste copier ceci et je vais aller à l'intérieur et je vais juste coller ceci juste pour le plaisir. Et ensuite, je vais exécuter cela à nouveau juste pour voir si quelque chose est légèrement différent et ensuite nous terminerons la leçon. Donc, je vais faire ceci. Eh bien, je vais regarder quelques choses de plus avant de terminer, mais j'espère que cela a du sens. euh, comme spécifiquement, c'est comment chasser la table des événements de connexion de l'appareil. C'est comment chasser la table des événements réseau des appareils, etc. Et vous savez, mieux votre invite est, mieux GPT ou le modèle sera capable de faire ce que vous voulez. Donc, je vais juste laisser cela se terminer. Cela dira entrer. Devrait être la chasse aux menaces de la table des événements de connexion de l'appareil. Je pense que oui. Oui, c'est le cas. Donc, il utilise notre nouvelle invite. euh, laissez-moi en faire une de plus après celle-ci en fait. Pendant que cela se passe, je vais vérifier ce que Claude a trouvé. Regardez ici. toujours en train de faire quelque chose. Découvertes titre lignes de journal deux. Il a trouvé un deuxième. Trouvé un troisième. Trouvé un quatrième. Penser que cela va fonctionner. Bon sang. Ça prend une éternité. Ça prend une éternité cependant. Je vais dire entrer. C'est avec notre nouvelle invite de table d'événements de connexion de l'appareil, je suppose, et nous pourrions prendre le temps de comparer et de contraster ces journaux et de les affiner et tout, mais j'espère que vous avez compris l'idée. euh, d'accord. Chacun, chaque table que nous chassons, la façon dont nous, la façon dont j'ai conçu cela, je suppose que ce n'est pas le meilleur, mais la façon dont je l'ai conçu, c'est que chaque table a des instructions de chasse spécifiques. Et ensuite, modifions le message système un peu. Donc, j'ajouterai quelque chose de ridicule ici. Par exemple, je dirai lorsque vous renverrez quoi que ce soit à l'utilisateur, veuillez parler comme une fille de la vallée de la fin des années 90. Je veux juste voir s'il respecte cela et le fait réellement. Donc, je vais faire une chasse aux menaces de plus. Donc, en gros, pour vous donner une idée, j'ai changé ceci ici pour parler comme une fille de la vallée de la fin des années 90. Je l'ai juste mis dans le message système. Donc, il devrait, il devrait renvoyer quelque chose qui sonne comme une fille de la vallée de la fin des années 90. Mais, vous savez, nous verrons quand la chasse aux menaces réelle sera terminée, comme lorsqu'elle jettera les informations sur les menaces, c'est là qu'elle devrait parler comme une fille de la vallée. Donc, nous verrons ce qui se passe. Je vais utiliser la même invite. Je vais supprimer les points d'arrêt. Ils entrent pour choisir ce modèle. Il exécute la chasse aux menaces. Super. Il a terminé. Oh wow. Ça a marché. D'accord. Okay. Donc, menace potentielle un description. Oh mon dieu. Comme c'est certainement bruyant. Windows Target One a vu une rafale concentrée de tentatives de connexion échouées. Connexion échouée contre les événements. Des tonnes de tentatives automatisées. D'accord. Il a un peu abandonné, je suppose. Parler comme une fille de la vallée. Notes comme. Donc, écoutez la confiance numérique. C'est tellement drôle. Mais de toute façon, j'espère que cela a du sens et que vous avez compris l'idée. Je passerais juste du temps à regarder ceci et à comprendre ce que le message système, le message système ou le système d'invite, ainsi que le message utilisateur, et quelles sont les parties de celui-ci et ce qu'elles font. C'est essentiellement juste un énorme créateur d'invites, n'est-ce pas ? C'est comme donner autant de contexte que possible à chat db, puis lui dire comment se comporter. Donc, je parcourrais, vous savez, juste pour avoir une meilleure idée et peut-être augmenter votre compréhension. Je pourrais parcourir et ensuite ajuster les invites de chasse aux menaces individuelles ou au moins une autre, par exemple. euh, essayez de voir si vous pouvez améliorer celle de la table des journaux de connexion. Ou quelque chose comme ça. C'est celle qui garde une trace de quand les gens essaient de se connecter à Azure ou à ID, alias Azure Active Directory, comme ce sont les instructions actuelles que j'ai pour la chasse aux menaces, mais cela peut certainement être amélioré. C'est assez court comme vous pouvez le voir. euh, et vous devez juste utiliser GPT pour lui donner plus de contexte sur ce que vous voulez faire. Comme vous voulez l'affiner, mais vous ne voulez pas qu'il essaie de contraindre les choses pour le temps car nous gérons le temps ailleurs. euh, etc. Mais oui, faites-moi savoir si vous avez des questions à ce sujet. euh, juste comme toujours, postez dans la communauté et taguez-moi. euh, j'y arriverai ou mon personnel y arrivera ou quelqu'un d'autre le verra avant que nous y arrivions. Mais oui, j'espère que cela vous aidera. Je sais que c'est un peu compliqué, mais plus vous pratiquez avec, plus votre intuition s'améliore.

devrait augmenter avec le temps. Mais oui, euh merci d'avoir regardé et nous vous retrouverons dans la prochaine leçon. Bienvenue de retour. Dans cette leçon, nous allons aborder l'isolation des VM. C'est-à-dire que si des menaces sont trouvées sur une machine virtuelle et que la confiance est élevée, nous serons en mesure de mettre en œuvre une isolation automatique de la machine virtuelle pour l'isoler dans Defender pour Endpoint. Et encore une fois, il est très important que vous ayez suivi le cours SecOps avant celui-ci, sinon certaines choses n'auront pas de sens. Mais je vais y aller directement. Euh, alors allez-y et dans la leçon, euh, si vous descendez et téléchargez le fichier zip comme d'habitude, cela contient le code mis à jour. Alors téléchargez-le, extrayez-le, puis placez-le sur votre bureau ou où vous voulez. J'ai extrait le mien sur le bureau. Il s'appelle Il ressemble à ceci : Isolation VM. Ensuite, ouvrez ce dossier dans VS Code. Donc, comme d'habitude, vous savez, vous pouvez fermer tout ce qui est ouvert, comme fermer le dossier, puis ouvrir le dossier. Et puis je suis allé sur le bureau et j'ai ouvert ce dossier ici. Et c'est ce que c'est, ce main.py. Pour faire ce laboratoire, vous pouvez soit créer votre propre machine virtuelle et ouvrir le NSG et le pare-feu Windows afin qu'elle soit découverte sur Internet. Et ensuite, nous voulons que beaucoup de gens essaient de forcer votre machine virtuelle ou d'essayer d'y entrer. Alternativement, vous pouvez utiliser Windows target one ou Linux target one pour faire ce laboratoire car ils sont probablement déjà en ligne et ils sont attaqués par force brute. Et techniquement parlant, vous pouvez utiliser, vous pouvez utiliser les machines virtuelles d'autres personnes également. Mais ce laboratoire, nous allons isoler les VM. Alors gardez cela à l'esprit, ne pas isoler les machines virtuelles d'autres personnes, puis oublier de les retirer de l'isolation ou quelque chose comme ça, car si vous isolez une machine virtuelle, vous ne pouvez pas, je ne pense pas que vous puissiez la désisoler tant qu'elle n'est pas rallumée et que vous n'êtes pas autorisé à rallumer les machines virtuelles d'autres personnes. Je ne crois pas. Donc, par exemple, si une machine virtuelle est éteinte, vous pouvez l'isoler, puis lorsque la machine virtuelle revient en ligne, elle sera automatiquement isolée et vous ne pourrez pas l'annuler à moins que la machine virtuelle ne soit allumée. Donc, à mon avis, ou pas mon avis, vous devriez vous concentrer sur l'utilisation de vos propres machines virtuelles ou de ces deux VM. Donc, si vous voulez, vous pouvez mettre cela en pause et configurer votre propre machine virtuelle, la rendre en direct et tout ça. Sinon, vous pouvez utiliser Windows target one et Linux target one. Donc, dans ce code, nous allons ajouter trois nouvelles fonctions dans le module exeutor, puis nous les examinerons lorsque le code s'exécutera, mais je vous les montrerai maintenant et j'en parlerai un peu. Il y a donc une fonction get bearer token, un bearer token. Oh, c'est juste une fonction qui obtient une clé de connexion, alias bearer token, d'Azure. C'est essentiellement comme un mot de passe, et ce bearer token/mot de passe sera utilisé lorsque nous appellerons l'API qui isole la machine virtuelle. Donc, c'est la fonction get bearer token, en fait, je vais vous la montrer. Donc, si vous ouvrez les fichiers du projet ou le fichier du projet, allez dans exeutor, c'est ici, get bearer token. Et la fonction suivante, celle qui a été ajoutée au module exeutor, est get MDE workstation ID from name. Cette fonctionBasically, elle recherchera l'ID de la machine dans Defender pour Endpoint, étant donné le nom d'hôte. Et c'est nécessaire car lorsque nous appelons la fonction d'isolation ou de mise en quarantaine de la machine virtuelle, elle nécessite l'ID de la machine virtuelle, pas le nom. Donc, par exemple, si nous allons à, c'est le portail Defender pour Endpoint. Donc, comme security.microsoft.com et je recherche, par exemple, Windows target one et j'ouvre cette machine virtuelle. Il devrait y avoir un ID quelque part ici. Oh, je pense que c'est cet ID de périphérique. Donc, la fonction prendra le nom et utilisera ce nom pour rechercher l'ID du périphérique, puis cet ID du périphérique sera utilisé pour isoler le périphérique. Tout cela va se passer par programmation dans le code. Donc, get MDE workstation ID from name, c'est ici, cette fonction, elle prend le bearer token qui est comme le mot de passe et elle prendra le nom de l'appareil, par exemple Windows target one, et vous ferez un appel API à l'API Defender pour Endpoint. Certaines choses se produiront, des choses seront renvoyées, puis l'ID de la machine sera extrait de cet objet, puis renvoyé. Et puis la troisième fonction, c'est la fonction quarantine virtual machine. elle prendra l'ID de la machine virtuelle ou le oui, l'ID de la machine, puis elle la mettra en quarantaine dans Defender pour Endpoint, et c'est simplement ici. Elle utilise le bearer token, utilise l'ID de la machine, elle crée une requête API, certains objets pour une requête API, envoie la requête API à Defender pour Endpoint, puis si le code d'état est 2011 ou 200, cela signifie que la machine a été isolée avec succès, sinon elle ne l'a pas été. C'est tout. Et nous avons également ajouté une logique dans le script principal après avoir affiché les menaces. Donc, si vous vous souvenez, à la fin du script, toutes les menaces seraient affichées. Nous avons ajouté une logique supplémentaire ici pour prendre des décisions quant à savoir si nous voulons isoler la machine virtuelle ou non. Donc, si nous allons au script principal, nous allons tout à la fin. Donc, c'est là que le script se terminait auparavant. Il déversait toutes les menaces à l'écran. Et puis maintenant, pour cette partie, pour ce code particulier, nous avons ajouté ceci pour obtenir notre bearer token à partir de notre session de connexion. Nous avons défini des variables ici. Nous avons défini d'autres variables concernant le contexte de la requête. Si la requête initiale concerne un hôte individuel ou si la requête initiale concernait un utilisateur individuel, etc., nous initialisons les machines isolées à false. Et puis, en gros, nous allons parcourir chaque menace qui était dans les résultats. Et puis nous allons dire, nous allons déterminer si la confiance de la menace était élevée. Nous allons passer par là dans une seconde, mais je l'explique maintenant. Pour chaque menace, nous allons déterminer si la confiance de la menace est élevée via ceci. Et nous stockerons cela dans une variable. Et puis nous dirons, si la requête concerne un hôte individuel, cela signifie qu'elle a le potentiel d'être isolée. Et puis nous dirons, si la confiance de la menace particulière est élevée et que la machine n'est pas déjà isolée, elle notifiera, elle notifiera l'utilisateur. OK. Une menace de haute confiance a été détectée. C'est la menace. Voulez-vous, voulez-vous isoler l'hôte ? Oui ou non. Et puis, en gros, si l'utilisateur dit oui, le processus d'isolation va commencer. Donc, si l'utilisateur dit oui, il veut l'isoler, cette fonction va s'exécuter pour obtenir d'abord l'ID de la station de travail. Donc, l'ID de la station de travail sera récupéré et stocké ici. Et puis cette fonction exécutera la mise en quarantaine de la machine virtuelle et elle passera le token et l'ID de la machine, et alors la machine sera isolée si tout se passe comme prévu, et puis si elle est isolée, nous imprimerons à l'écran OK, la machine a été isolée et puis un rappel pour s'il vous plaît, libérer la VM de l'isolation et alors nous montrons le lien ici vers où vous pouvez aller pour libérer l'isolation, etc. Et puis ce script n'est pas parfait. Il peut y avoir beaucoup de problèmes avec lui, mais je vais peut-être laisser cela pour une activité d'internat pour le corriger. Donc, voici quelques choses qui ne vont pas. Par exemple, il n'y a pas vraiment de gestion des erreurs dans les nouvelles fonctions qui ont été ajoutées au cas où le token serait mauvais ou si un autre problème survenait. Donc, et aussi la validation, si l'utilisateur tape par exemple, voudriez-vous isoler cette VM maintenant, si vous tapez le mot "yeet" par exemple, ou "yellow" parce qu'il commence par Y, elle sera isolée, donc je veux dire que ce n'est pas, vous savez, ça devrait être mieux et encore une fois, il n'y a pas de journalisation ou quoi que ce soit et vous savez, ce sont juste des choses, nous rappelons à l'utilisateur d'isoler la machine virtuelle, mais en réalité, nous devrions avoir une sorte de mécanisme pour, vous savez, appuyer sur I pour, comme, ou appuyer sur U pour désisoler, vous savez, quelque chose comme ça, appuyer sur R pour libérer et le script est généralement incomplet, mais il fonctionnera pour ce que nous voulons qu'il fasse en supposant que tout est configuré correctement. Donc, encore une fois, nous allons simplement continuer et exécuter cela. Je vais utiliser cette invite juste pour la facilité. Si vous voulez utiliser votre propre machine virtuelle, vous pouvez le faire. Mais je vais copier cette invite. Je vais aller dans exécuter et je vais dire, en fait, avant de déboguer cela, je veux casser cela vers la fin. Oh, je vais casser ici, juste avant que le nouveau code ne commence à se produire, et je vais exécuter et je vais déboguer. Je suis un peu inquiet pour Windows Tracker One. Ça marche. Nous dirons oui pour ce modèle. Cool. Et la menace est terminée. Nous pouvons appuyer sur entrée. Il déversera toutes les menaces à l'écran. Trouvé, trouvé trois menaces. Celle-ci est de haute confiance. Celle-ci est moyenne. Celle-ci est haute. Les vôtres seront sans aucun doute différentes. Droit. Vous pouvez, vous pouvez mettre cela en pause et lire si vous voulez, mais vous pouvez voir que notre script s'est arrêté ici. Ensuite, nous allons obtenir le bearer token. Donc, si nous disons "step into", il va entrer dans l'exeutor. Donc, si je vais dans l'explorateur de fichiers, il va entrer dans le module exeutor, puis commencer à exécuter la fonction get bearer token. trophy step into, nous avançons, nous avançons et nous pouvons voir notre token, il est ici avec la date d'expiration et la chaîne de token réelle. Donc, si nous avançons, nous avons maintenant notre token comme ça, et nous allons initialiser ces VM, machine isolée et compte utilisateur désactivé. Nous n'utilisons pas cela actuellement, celui du compte utilisateur, c'est pour le prochain module futur. Et puis nous allons définir ces variables en fonction des éléments qui se trouvent dans notre contexte de requête. Et vous vous souvenez que le contexte de requête est tous ces métadonnées qui ont été générées en fonction de la demande initiale de l'utilisateur. Donc, rappelez-vous, nous avons dit que je suis inquiet que quelqu'un se soit connecté à Windows target one, puis ces éléments en ont été dérivés, comme le nom de la table à rechercher, le nom de l'appareil à rechercher, la période de temps par défaut à 96, et si la requête concernait un utilisateur individuel est faux, concerne un hôte, ce qui est vrai, car nous avons dit que nous nous inquiétions de Windows target one, etc. Nous pouvons passer par-dessus cela. Ce sont juste des affectations à ces variables pour être utilisées plus tard. Machine isolée. Oh, c'est comme un doublon. Je n'avais pas besoin d'avoir ça ici. Donc, nous pouvons dire "step" et alors maintenant c'est une boucle géante. Elle va parcourir toutes les menaces qui ont été trouvées. Donc, si nous disons "step into", et alors cela va évaluer si la confiance de la menace. Ce sont toutes les menaces, n'est-ce pas ? Et puis c'est la première menace dans le groupe ou dans la liste des menaces. Donc, la confiance de la menace est élevée. Donc, si la confiance est égale à élevée, cela sera défini sur vrai. Donc, si nous passons par-dessus cela, c'est défini sur vrai. Donc, si je vais dans le débogage ici, la confiance est élevée, et alors si la requête concerne un hôte individuel. Donc, rappelez-vous, c'est d'ici que nous l'avons obtenu du contexte de requête, et la requête concerne un hôte individuel. Donc, maintenant, nous allons réfléchir à savoir si nous voulons isoler la machine virtuelle. Donc, si nous avançons, nous allons dire, si la confiance est élevée, ce qui est vrai, et que la machine n'est pas isolée. Donc, machine isolée est faux. Donc, pas faux va, tout cela va s'évaluer à vrai. Donc, nous, ce qui signifie que cela va s'évaluer à vrai. Donc, nous avançons et alors maintenant, il va imprimer des choses pour nous à l'écran. Donc, si nous descendons ici, une menace de haute confiance détectée sur Windows target one. Tentatives de brute force de pulvérisation de mots de passe à haut volume à partir d'une seule IP. C'est le titre de la menace qui s'est produite. Donc, oops. Si nous remontons ici à la menace numéro un, nous la voyons ici. Tentatives de brute force de pulvérisation de mots de passe à haut volume à partir d'une seule IP. C'est donc la menace en question, et elle est de haute confiance. Donc, si nous avançons, il dit, voulez-vous isoler cette VM ? Nous pouvons dire O pour oui ou N pour non. Donc, je vais juste dire, je vais juste dire non pour celui-ci. Et alors il va dire, si la réponse commence par Y, il va faire les choses d'isolation. Sinon, il va dire qu'il a sauté. Donc, nous avançons, nous avons dit non. Donc, il saute ici et alors il dit qu'il a sauté et alors il passe à la menace suivante, comme ça. Donc, nous allons vérifier la confiance de la menace de la menace suivante. Donc, la confiance de la menace est moyenne. Donc, [renifle] moyenne n'est pas égale à élevée. Moyenne n'est pas égale à élevée. Donc, cela va être défini sur faux. Comme ça, faux. Si la requête concerne un hôte, c'est le cas. Donc, nous allons entrer. Donc, si la confiance de la menace est élevée et que la machine n'est pas isolée, la confiance de la menace n'est pas élevée. Donc, tout cela va être évalué à faux et il saute simplement à la menace suivante. Donc, nous passons à la suivante. Nous allons vérifier la menace suivante. Confiance de la menace. Celle-ci est élevée. Donc, cela va s'évaluer à vrai. Comme ça, c'est vrai. La requête concerne un hôte. C'est vrai. Si la confiance de la menace est élevée et que la machine n'est pas isolée, elle ne l'est pas. Donc, cela va s'évaluer à vrai et alors il va entrer dans la logique d'isolation. Donc, voulez-vous isoler cette VM ? Je veux juste vous montrer par exemple, il suffit de commencer par Y et ce [renifle] va, cela va, vous savez, évaluer à tort comme oui, mais c'est bon, je veux isoler, mais je montre juste le fait que si "confirm" commence par Y, ce qui est le cas maintenant, il va utiliser, il va entrer dans le module exeutor, puis utiliser la fonction get MDE workstation ID from name. Donc, si nous entrons ici, nous sommes à l'intérieur de exeutor, puis nous sommes à l'intérieur de get MDE workstation ID. Il va construire l'en-tête de la requête. Ceci, j'oublie ce que cela fait en fait, mais il y avait un, il y a un problème avec, par exemple, Windows, les ordinateurs Linux auront un nom assez long, et j'ai dû, d'une manière ou d'une autre, en tenir compte avec ceci. J'oublie, j'oublie ce que ce code fait réellement, mais laissez-moi avancer et voir. Oh, d'accord. Donc, l'URL utilisée pour la requête API, elle a besoin d'un filtre ou autre chose pour l'aider à récupérer la machine virtuelle dont nous parlons ou la machine dont nous parlons. Donc, cette ligne de code formate simplement notre nom d'ordinateur d'une manière qui se transforme en un filtre pour l'URL. Donc, je vais vous montrer si nous passons par-dessus cela. Ce n'est pas quelque chose que j'ai mémorisé du tout, pour être honnête, évidemment par la façon dont j'en parle. Donc, si nous regardons cette URL, elle est ici en fait. Donc, je pense que je peux copier cette valeur. Je ne sais pas ce que cela va faire, mais cela a essentiellement créé cette URL qui est utilisée pour trouver la machine virtuelle Windows target one dans Defender pour Endpoint. Je ne pense pas que quelque chose se produira si je clique simplement dessus. Mais pour une raison quelconque, elle doit être formatée comme ceci. C'est juste une partie des règles pour l'API. Je pense que je l'ai trouvée dans la documentation de l'API ou quelque chose comme ça, mais nous avons notre URL construite et les en-têtes construits. Donc, nous allons envoyer une requête API à l'API Defender pour Endpoint. Et nous avons obtenu notre réponse, puis il va extraire la valeur de la réponse. Je crois que c'est quelque part dans ce texte. Voyez, cette valeur est ici. Il va extraire ceci. C'est l'ID de la machine. Ce B18 blah blah blah D4 à la fin. Donc, par exemple, si nous allons ici, nous voyons B18 blah blah blah, puis D4 à la fin. C'est l'ID de la machine pour Windows target one. Donc, nous l'extrayons. Oh, et puis si aucune machine virtuelle n'est trouvée, cela s'exécutera. Mais il a trouvé une VM. Il va extraire les machines de l'élément zéro des machines, puis l'ID, qui est un ID Windows target one, puis il va le renvoyer. Donc, nous sommes de retour à la fonction principale. Et alors nous avons notre ID de machine ici, B18, etc. Et alors maintenant, nous allons appeler, dans le module exeutor, nous allons appeler la fonction de mise en quarantaine de la machine virtuelle en passant notre token, que nous avons obtenu plus tôt, ainsi que l'ID de la machine que nous venons d'obtenir. Donc, si nous entrons ici, étape par étape, nous sommes dans le module exeutor à nouveau, à l'intérieur de la fonction de mise en quarantaine de la machine virtuelle. Et alors encore une fois, il va construire un en-tête de requête API ainsi que la charge utile. Donc, l'en-tête, c'est le bearer token. Et alors la charge utile, c'est juste comme un commentaire qui apparaîtra dans le portail Defender pour Endpoint. Et alors c'est comme l'URL, l'en-tête et la charge utile. Et alors c'est là que l'API est appelée. Donc, si nous avançons étape par étape, et alors c'est là que l'API est appelée, et alors la machine devrait être en train de s'isoler maintenant, vous savez, à moins que quelque chose ne se soit passé. Le code de réponse est 2011, ce qui signifie que l'isolation devrait avoir pris effet. Donc, si je retourne à Defender pour Endpoint, c'est Windows target one, n'est-ce pas ? Si je clique ici, nous pouvons voir que "isoler l'appareil" est toujours actif. Mais si je, si je rafraîchis la page et que je clique ici, vous pouvez voir qu'il est passé à "libérer l'appareil de l'isolation" ou "libérer de l'isolation" parce que cette chose a été isolée. Nous pouvons le voir ici aussi. Elle a été isolée en arrière-plan avec l'API, avec ce code qui s'exécute en ce moment même. Donc, si nous disons "stay next", nous pouvons dire, si la machine est isolée, cela sera vrai si la mise en quarantaine de la machine virtuelle renvoie vrai. Donc, c'est vrai. Si la machine est isolée, nous allons dire des choses à l'utilisateur. VM isolée avec succès. Rappel : veuillez libérer la VM de l'isolation en temps voulu à cette URL. Donc, vous pouvez cliquer sur contrôle ou commande, peu importe si vous utilisez Mac ou PC. Nous disons "next" et alors les menaces ont fini de boucler et alors notre programme est terminé et alors la machine a été isolée. Donc, rappelez-vous toujours de retourner et de retirer cela de l'isolation car je ne peux pas simplement isoler un tas de machines virtuelles car c'est l'une de ces choses où vous avez assez de pouvoir pour gâcher l'environnement pour les gens et je n'ai pas eu à inclure cela, mais je voulais que ce soit réaliste, vous savez, parce qu'au travail, vous pouvez faire toutes sortes de choses qui ne sont pas bonnes, n'est-ce pas ? Alors rappelez-vous de la libérer de l'isolation, surtout si vous isolez la machine virtuelle de quelqu'un d'autre. Donc, je vais, et au fait, si la machine virtuelle est éteinte, ces commandes d'isolation et de suppression d'isolation ne s'exécuteront bien sûr que lorsque la machine virtuelle sera rallumée manuellement. Donc, je vais rafraîchir cette page. Assurez-vous qu'elle n'est plus isolée. Elle ne l'est pas. Vous pouvez le voir ici. Aussi ici. Isoler l'appareil signifie qu'il n'est pas isolé. Donc, je vais revenir ici et alors nous allons exécuter cela une fois de plus. Mais je vais vous montrer quelque chose si je peux. J'espère que cela fonctionnera correctement. Donc, copiez ceci ou pas, cela fonctionne correctement. Je veux vous montrer ce qui se passe si vous isolez la machine virtuelle et ensuite elle continue d'évaluer les menaces et trouve une autre menace élevée. Donc, je vais commencer à déboguer cela. Dites entrer pour cela. Je vais juste commencer. Allez-y, c'est fait. Dites entrer. Et voyons. Il a trouvé un élevé. Trouvé un autre élevé. Et trois élevés. Super. C'est ce que je voulais. Donc, je vais faire défiler cela jusqu'en bas et alors je vais supprimer ce point d'arrêt et je vais juste en ajouter un, voyons, j'en ajouterai un peut-être ici. Je vais dire "continue". Donc, les requêtes concernent un hôte individuel, vrai. Donc, je vais dire "continue". Donc, la confiance de la menace est élevée et la machine n'est pas isolée. Donc, cela va faire la logique d'isolation. Donc, je vais passer par cela et je vais dire oui initialement. L'isolation, [renifle] la logique commence. Et je vais dire "step over" parce que je n'ai pas besoin de regarder à nouveau cette fonction entière. Nous savons qu'elle obtient l'ID de la machine. Je vais dire "step over". Et alors c'est là que la machine va être isolée. Donc, je vais passer par cela. Et alors la machine est isolée. Donc, Windows target one est maintenant isolé. Donc, nous allons passer par cela. Isolée avec succès. Et alors il va passer à la menace suivante dans la liste. Donc, vous vous souvenez qu'il y avait trois élevés ici. Donc, nous allons dire "step into", c'est la menace suivante. La confiance est élevée car elles étaient toutes élevées. Donc, nous allons dire "step", la requête concerne un hôte individuel. C'est le cas. Donc, c'est la partie intéressante. Si la confiance de la menace est élevée et que la machine n'est pas isolée, mais que la machine est isolée parce qu'elle a déjà été isolée. Donc, maintenant, toute cette logique va être sautée et alors il passe simplement à la menace suivante. Même chose si la confiance est élevée, ce qui est le cas, et que la machine n'est pas déjà isolée, ce qui est le cas car elle a déjà été isolée, elle saute et alors il n'y a plus de menaces et alors le programme se termine. Donc, encore une fois, il y a beaucoup de choses qui peuvent être améliorées ici. Je crée juste un MVP basique, un produit minimum viable, parce que je veux que les gens réfléchissent à la façon de l'améliorer et d'utiliser chat GPT et des choses comme ça pour le rendre meilleur. Mais je vais couvrir cela plus tard, probablement à la fin de ceci, lorsque nous aborderons comment obtenir des crédits de stage. Mais assurez-vous d'aller et de retirer la machine virtuelle de l'isolation, quelle que soit la machine virtuelle que vous avez isolée. Donc, nous allons retirer ceci comme ça. [renifle] Oui, c'est l'isolation agentique de la machine virtuelle et nous pouvons la rendre vraiment agentique dans le sens où elle ne confirme pas avec l'utilisateur s'il faut l'isoler ou non. Comme si elle n'est pas isolée et que la confiance est élevée, nous pouvons l'isoler automatiquement. Donc, par exemple, nous allons juste retirer ceci, retirer ceci et alors, oops, et alors, ramener ceci dans un, et alors boom, nous avons, oh oui, ce n'est pas nécessaire non plus, et alors boom, nous avons une véritable isolation agentique, mais il est toujours bon, surtout au début lorsque vous créez quelque chose comme ceci, c'est une très bonne idée de laisser cela, vous savez, laisser le script demander à l'utilisateur s'il veut faire quelque chose de potentiellement catastrophique ou non. Mais lorsque vos processus sont vraiment au point et que la logique est bonne et que vous savez, vous savez avec certitude que cela fera ce que vous voulez, alors peut-être que vous pouvez, vous savez, le rendre véritablement agentique. Parce que, eh bien, je ne veux pas donner de mauvaises idées à qui que ce soit, mais je pense que si quelqu'un regarde ceci jusqu'à la fin, il ne fera probablement pas cela, mais en théorie, vous pourriez créer un script qui parcourt et boucle à travers toutes les machines de l'inventaire des appareils et isole simplement toutes. C'est une chose possible que vous pouvez faire. Et la base pour faire cela est déjà là. Il vous suffit de trouver un moyen d'obtenir la liste complète des machines virtuelles dans Defender pour Endpoint, car c'est possible. Il est possible de faire ce genre de dégâts ici et au travail. Alors ne le faites pas ici et essayez de ne pas le faire au travail. Mais j'espère que cela a du sens. Si vous avez des questions ou quoi que ce soit, faites-le moi savoir dans les forums. Sinon, nous vous retrouverons dans la prochaine leçon. Donc, aucune pression évidemment, mais si vous êtes sérieux au sujet de la cybersécurité ou si vous voulez une expérience pratique réelle et non simulée avec de vrais outils d'entreprise sur un réseau partagé en direct, vous pouvez obtenir tout cela dans le cyber-range. Au cours de la dernière année, nous avons effectué environ 100 vérifications d'emploi. Ce sont de vrais employeurs qui nous contactent pour confirmer l'expérience de personnes de la communauté qui ont réellement trouvé des emplois. Lorsque vous rejoignez la communauté, vous recevrez des identifiants pour accéder au réseau réel de notre entreprise, qui est un environnement d'entreprise réel et en direct avec plus de 200 utilisateurs et une pile de sécurité d'entreprise entièrement sous licence avec des plateformes comme Tenable Vulnerability Management, Microsoft Defender pour Endpoint et Microsoft Sentinel. Et tout comme dans un vrai travail de sécurité, nous fournirons une formation couvrant tout ce que vous rencontrerez, de la gestion des vulnérabilités d'entreprise à la chasse aux menaces en passant par les opérations de sécurité générales. Et vous obtiendrez une expérience et une formation meilleures que si vous étiez embauché comme analyste junior de SOC en entreprise. Chaque semaine, nous organisons également une chasse aux menaces de cybersécurité et un défi capture du drapeau où vous pouvez concourir pour des prix en espèces tout en acquérant une expérience légitime pour votre CV. Et ce n'est pas une simulation. C'est une infrastructure réelle avec de vrais utilisateurs, de vraies attaques et des journaux organiques auxquels vous aurez un accès direct. Donc, si vous êtes intéressé, consultez le lien dans la description, et nous vous retrouverons dans la prochaine vidéo. Au revoir.