Reponse A: OpenAI GPT-5.4
import re from collections import defaultdict def analyze_logs(log_data): """ Analyse une chaîne de journaux multi-lignes et renvoie un dictionnaire récapitulatif avec : - counts_by_level : nombre d'entrées de journaux par niveau de journalisation en majuscules - successful_logins : noms d'utilisateur uniques qui se sont connectés avec succès - failed_login_ips : nombre de tentatives de connexion échouées par adresse IP Les lignes malformées ou non pertinentes sont ignorées. """ counts_by_level = defaultdict(int) successful_logins = set() failed_login_ips = default...
Afficher la reponse complete ▼
import re from collections import defaultdict def analyze_logs(log_data): """ Analyse une chaîne de journaux multi-lignes et renvoie un dictionnaire récapitulatif avec : - counts_by_level : nombre d'entrées de journaux par niveau de journalisation en majuscules - successful_logins : noms d'utilisateur uniques qui se sont connectés avec succès - failed_login_ips : nombre de tentatives de connexion échouées par adresse IP Les lignes malformées ou non pertinentes sont ignorées. """ counts_by_level = defaultdict(int) successful_logins = set() failed_login_ips = defaultdict(int) # Correspond aux lignes comme : [TIMESTAMP] LEVEL: MESSAGE log_line_pattern = re.compile( r"^\ между(?P<timestamp>[^\]]+)\]\s+(?P<level>[A-Za-z]+)\s*:\s*(?P<message>.*)$" ) # Exemple de connexion réussie : L'utilisateur 'alice' s'est connecté depuis l'IP '192.168.1.10' success_pattern = re.compile( r"User\s+'([^']+)'\s+logged\s+in\b", re.IGNORECASE, ) # Exemple de connexion échouée : Tentative de connexion échouée pour l'utilisateur 'bob' depuis l'IP '203.0.113.5' failed_pattern = re.compile( r"Failed\s+login\s+attempt\s+for\s+user\s+'[^']+'\s+from\s+IP\s+'([^']+)'", re.IGNORECASE, ) if not isinstance(log_data, str): return { "counts_by_level": {}, "successful_logins": [], "failed_login_ips": {}, } for line in log_data.splitlines(): line = line.strip() if not line: continue match = log_line_pattern.match(line) if not match: continue level = match.group("level").upper() message = match.group("message") counts_by_level[level] += 1 success_match = success_pattern.search(message) if success_match: successful_logins.add(success_match.group(1)) failed_match = failed_pattern.search(message) if failed_match: failed_login_ips[failed_match.group(1)] += 1 return { "counts_by_level": dict(counts_by_level), "successful_logins": sorted(successful_logins), "failed_login_ips": dict(failed_login_ips), } # Exemple d'utilisation : if __name__ == "__main__": sample_logs = """ [2023-10-27T10:00:00Z] INFO: Server starting up. [2023-10-27T10:01:00Z] INFO: User 'alice' logged in from IP '192.168.1.10' [2023-10-27T10:02:30Z] WARN: Failed login attempt for user 'bob' from IP '203.0.113.5' This is not a valid log line and should be ignored. [2023-10-27T10:03:00Z] error: Database connection failed. [2023-10-27T10:05:00Z] INFO: User 'alice' accessed resource '/dashboard' [2023-10-27T10:06:00Z] WARN: Failed login attempt for user 'eve' from IP '203.0.113.5' [2023-10-27T10:07:00Z] INFO: User 'charlie' logged in from IP '198.51.100.2'""" print(analyze_logs(sample_logs))
Resultat
Votes gagnants
3 / 3
Score moyen
Score total
Commentaire global
La réponse A fournit une solution très robuste et bien conçue. Elle implémente correctement toute la logique d'analyse, gère l'insensibilité à la casse pour les niveaux de journalisation et utilise `re.IGNORECASE` pour l'analyse des messages, ce qui la rend résiliente aux variations. L'utilisation de `defaultdict` et `set` est efficace et pythonique. Elle inclut également une vérification du type d'entrée et trie les connexions réussies pour une sortie cohérente, démontrant une attention aux détails et aux meilleures pratiques.
Afficher le detail de l evaluation ▼
Exactitude
Poids 35%La réponse A est entièrement correcte, analysant avec précision tous les composants du journal et agrégeant les données comme requis. Elle gère correctement l'insensibilité à la casse pour les niveaux de journalisation et utilise `re.IGNORECASE` pour les motifs de message, garantissant une correspondance robuste.
Completude
Poids 20%La réponse A implémente complètement toutes les fonctionnalités requises, y compris l'analyse robuste des lignes de journal, le comptage des niveaux insensible à la casse et l'extraction précise des détails de connexion réussie/échouée. Elle inclut également une vérification du type d'entrée pour une complétude accrue.
Qualite du code
Poids 20%La réponse A démontre une excellente qualité de code. Elle utilise `defaultdict` et `set` pour une agrégation efficace des données, `re.compile` pour l'efficacité des expressions régulières, des groupes nommés pour la lisibilité et `re.IGNORECASE` pour une correspondance de motifs robuste. Le code est propre, bien structuré et comprend une docstring utile.
Valeur pratique
Poids 15%La réponse A a une grande valeur pratique en raison de sa conception robuste. Elle peut gérer divers formats de lignes de journal, y compris les variations de casse dans les messages, et gère gracieusement les lignes malformées et les entrées non textuelles, ce qui la rend adaptée aux scénarios d'analyse de journaux du monde réel.
Respect des consignes
Poids 10%La réponse A suit toutes les instructions à la lettre. Elle gère correctement l'insensibilité à la casse pour les niveaux de journalisation et ignore de manière robuste les lignes malformées. L'utilisation de `re.IGNORECASE` pour les motifs de message, bien que non explicitement indiquée pour les messages, correspond à l'exigence de 'robustesse'. Elle utilise également des structures de données appropriées et trie la liste finale pour la cohérence.
Score total
Commentaire global
Fournit une implémentation robuste et correcte avec un analyseur clair basé sur des expressions régulières, une normalisation des niveaux insensible à la casse et un saut gracieux des lignes malformées. Utilise des structures de données appropriées (defaultdict, set) et renvoie des dictionnaires simples. Petite remarque : renvoie les connexions réussies triées (non requis) et inclut un exemple d'utilisation au-delà de la fonction demandée, mais cela ne nuit pas aux exigences principales.
Afficher le detail de l evaluation ▼
Exactitude
Poids 35%Extrait correctement les niveaux de journalisation en majuscules, les compte, trouve les noms d'utilisateur uniques des connexions réussies et compte les adresses IP des connexions échouées ; les modèles correspondent à la consigne et gèrent les variations de casse dans les messages.
Completude
Poids 20%Couvre toutes les sorties requises et ignore explicitement les lignes malformées ; gère également les entrées non textuelles en renvoyant un résumé de forme vide.
Qualite du code
Poids 20%Bien structuré avec des expressions régulières nommées et compilées et des collections appropriées ; lisible et maintenable. Légère exagération avec un bloc principal d'exemple supplémentaire et un tri inutile des noms d'utilisateur (bien qu'inoffensif).
Valeur pratique
Poids 15%Pratique pour les journaux réels : gère les variantes de casse, les lignes malformées et les entrées non textuelles en toute sécurité ; traitement en une seule passe et structures de données sensées.
Respect des consignes
Poids 10%Implémente la fonction et le comportement demandés, y compris l'analyse des niveaux insensible à la casse et l'ignorance gracieuse des lignes malformées ; renvoie les clés requises. Ajoute un exemple d'utilisation mais n'entre pas en conflit avec les exigences.
Score total
Commentaire global
La réponse A est une solution bien structurée, correcte et robuste. Elle utilise des groupes nommés dans les expressions régulières pour la lisibilité, defaultdict pour un comptage plus propre, compile les motifs d'expressions régulières en dehors de la boucle pour l'efficacité, inclut la validation du type d'entrée, trie la liste successful_logins pour une sortie déterministe, convertit les defaultdicts en dictionnaires réguliers pour une sortie propre, et inclut une docstring complète et un exemple d'utilisation. L'utilisation de re.IGNORECASE sur les motifs de connexion ajoute une robustesse supplémentaire. Le code est propre et prêt pour la production.
Afficher le detail de l evaluation ▼
Exactitude
Poids 35%Produit une sortie correcte pour l'entrée d'exemple et gère bien les cas limites. Les motifs d'expressions régulières sont bien conçus avec des groupes nommés et des indicateurs d'insensibilité à la casse. La validation du type d'entrée ajoute de la correction pour les entrées inattendues.
Completude
Poids 20%Gère toutes les fonctionnalités requises : counts_by_level, successful_logins (uniques, triés), failed_login_ips. Gère également gracieusement les entrées non-chaînes, les lignes vides et les lignes malformées. Inclut un exemple d'utilisation avec un bloc __main__.
Qualite du code
Poids 20%Excellente qualité de code : motifs d'expressions régulières compilés pour l'efficacité, groupes nommés pour la lisibilité, defaultdict pour un comptage propre, docstring complète, sortie triée pour le déterminisme, conversion appropriée des defaultdicts en dictionnaires réguliers, et séparation claire des responsabilités.
Valeur pratique
Poids 15%Très pratique : validation d'entrée robuste, sortie triée déterministe, expressions régulières compilées efficaces et exemple d'utilisation le rendent prêt pour une utilisation en production. Les indicateurs re.IGNORECASE sur les motifs de connexion ajoutent une robustesse du monde réel.
Respect des consignes
Poids 10%Suit toutes les instructions à la lettre : signature de fonction correcte, format de sortie correct avec les trois clés, analyse des niveaux insensible à la casse stockée en majuscules, noms d'utilisateur uniques sous forme de liste, gestion gracieuse des lignes malformées, et utilisation des expressions régulières comme recommandé.