Suite

Comment appliquer des messages d'erreur à une boîte à outils python qui empêchent mon outil de s'exécuter avec de mauvais paramètres ?


Ceci est la suite de ma question ici: Point et Polyline J'ai essayé de rendre cette question plus facile à suivre.

Mon outil accepte deux paramètres principaux : une ligne centrale continue et une table (ou une classe d'entités avec une table attributaire) avec des entités polylignes comprenant l'ID d'itinéraire et les mesures. Si l'utilisateur choisit une table, je ne peux pas vérifier si la table a des polylignes. Je vais faire confiance qu'ils chargent les données correctes. Cependant, je PEUX vérifier si la classe d'entités est une polyligne ou non.

J'ai essayé de le faire dans updateParameter avec un filtre. Je pense que j'ai une mauvaise idée de la façon dont cela fonctionne cependant:

def updateParameters(self, parameters): """ Je ne suis pas convaincu que cela doit même être ici. J'ai envisagé d'utiliser une case à cocher à la place. """ if parameters[2].altered and parameters[2].hasBeenValidated : if parameters[2].dataType == 'Feature': parameters[2].filter.list = 'Polyline' return

Lors de mes tests unitaires, j'ai pu sélectionner une caractéristique ponctuelle et elle échoue (bien). Lorsque je l'exécute dans ArcMap, il accepte les points (mauvais) et s'exécute sans erreur. Je veux pouvoir faire apparaître un message d'erreur dans la fenêtre de la boîte à outils et empêcher l'utilisateur de cliquer sur ok.

Mon updateMessages ressemble à ceci :

def updateMessages(self, parameters): """ Pour les instances où une classe d'entités est entrée pour param2 et il s'agit d'une classe d'entités ponctuelles La messagerie doit empêcher l'exécution de l'outil. """ # Erreur lors de l'analyse des arguments pour Describe if parameters[ 0].altered et parameters[0].hasBeenValidated : desc = arcpy.Describe(parameters[0].valueAsText) si desc.shapeType n'est pas dans 'Polyline' : arcpy.AddError("{0} a le mauvais type de données." ) lever arcpy.ExecuteError si parameters[2].altered et parameters[2].hasBeenValidated: desc = arcpy.Describe(parameters[2].valueAsText) if desc.datatype == 'Feature' et desc.shapeType pas dans 'Polyline ': arcpy.AddError("{2} a le mauvais type de données.") raise arcpy.ExecuteError return

J'ai pris la moitié de ce code directement de la documentation d'ESRI Writing Messages in Scripts

Je pourrais aussi bien vous montrer le getParameterInfo pour que vous ayez une vue d'ensemble :

def getParameterInfo(self): """ Définir les définitions de paramètres """ params = list() param0 = arcpy.Parameter(displayName="Centerline Layer", name="param0", datatype="GPFeatureLayer", parameterType="Required" , direction="Input") param0.filter.list = ['Polyline'] params.append(param0) param1 = arcpy.Parameter(displayName="Centerline ID", name="param1", datatype="Field", parameterType ="Required", direction="Input") param1.parameterDependencies = [param0.name] params.append(param1) param2 = arcpy.Parameter(displayName="Polyline Compare", name="param2", datatype="GPTableView" , # table ou table attributaire parameterType="Required", direction="Input") params.append(param2) param3 = arcpy.Parameter(displayName="Polyline Compare ID", name="param3", datatype="Field", paramètreType="Required", direction="Input") param3.parameterDependencies = [param2.name] params.append(param3) renvoie les paramètres

Comme vous pouvez le voir, le Centerline (param0) était plus facile à faire. Je viens de l'inclure dans le code afin qu'il crée toujours une erreur s'il est appelé. Je pourrais mettre une déclaration d'erreur dans la méthode d'exécution comme ceci:

desc = arcpy.Describe(param0.value) if desc.shapeType != 'Polyline': raise arcpy.ExecuteError("Type de données incorrect : sélectionnez une polyligne.") desc = arcpy.Describe(param2.value) if desc.dataType == 'Feature Class' et desc.shapeType != 'Polyline': raise arcpy.ExecuteError("Type de données incorrect : sélectionnez une polyligne.")

Pour le moment, les messages d'erreur n'apparaissent tout simplement pas. J'ai parcouru toutes les boîtes à outils python étiquetées avec des articles pertinents. Celui-ci a besoin d'une réponse aussi! Quelqu'un dans la pile peut-il aider avec celui-ci ?


Une chose à retenir, toutes les actions qui impliquent le paramètre doivent être en dehors de l'objet paramètre ; donc utiliseparameters[n].setErrorMessage(msg)à la place dearcpy.AddError(msg).Ajouter une erreurest utilisé pour ajouter des messages d'erreur dans les messages d'exécution de l'outil,setErrorMessageconsiste à ajouter une erreur au paramètre qui bloquera l'exécution de l'outil. Vous n'avez donc pas non plus besoin de lever d'exceptions.

Quelques autres problèmes, et quelque chose comme ci-dessous devraient faire ce que vous avez décrit.

def updateMessages(self, parameters): """Modifier les messages créés par validation interne pour chaque paramètre d'outil. Cette méthode est appelée après validation interne.""" polyline_compare = parameters[2].valueAsText if polyline_compare: desc = arcpy.Describe (polyline_compare) if desc.datasettype in ['FeatureClass', 'FeatureLayer']: if desc.shapetype != 'Polyline': parameters[2].setErrorMessage('Seules les polylignes et les tableaux sont acceptés') return

Erreurs courantes de certificat SSL et comment les corriger

Note de l'éditeur : ce blog a été publié à l'origine en septembre 2016. Il a été examiné pour plus de clarté et d'exactitude par le chef de produit GlobalSign, Sebastian Schulz, et mis à jour en conséquence.

Parfois, même les vétérans de l'ICP ont du mal à commander ou à installer des certificats SSL/TLS. Cela ne suggère pas un manque de connaissances et plutôt, ces processus peuvent générer des erreurs inédites. Commander le bon certificat, créer un CSR, le télécharger, l'installer et le tester pour s'assurer qu'il n'y a pas de problèmes sont autant de domaines où l'on peut rencontrer des erreurs.

Nous voulons aider à rendre le processus aussi simple que possible du début à la fin. Pour cette raison, nous avons rassemblé nos principales requêtes et problèmes auxquels les clients peuvent être confrontés lors de la commande ou de l'installation. Nous espérons que ce blog vous aidera à éviter ces pièges et à rationaliser votre temps d'achèvement, mais si vous rencontrez un problème que vous ne pouvez pas résoudre en utilisant ce blog, vous pouvez toujours consulter la base de connaissances du support GlobalSign ou envoyer un ticket.


HtmlUnit ne fonctionne pas bien avec JavaScript. Il lancera fréquemment des erreurs se plaignant de variables ou de fonctions non définies.

Dans ce sens, vrai vie les navigateurs (FireFox, Internet Explorer, Chrome, etc) sont beaucoup plus flexibles. Cela signifie qu'ils autoriseront des morceaux de HTML et de JavaScript syntaxiquement incorrects (par exemple, ne pas définir de fonctions ou ne pas terminer les balises HTML).

HtmlUnit s'attend à ce que tout soit (presque) parfait. Bien que cela corrige certaines balises HTML de fin manquantes, en général, il s'attend à ce que le code dans les pages ne contienne aucun type d'erreur. De plus, même si tout semble correct, HtmlUnit peut même se plaindre.

Voici quelques éléments auxquels vous devez penser :

  • Le plus important est de basculer entre les différentes versions de navigateur. Vous pouvez les définir lors de la création de l'objet WebClient. Internet Explorer (ironiquement) s'est avéré me donner les meilleurs résultats en matière d'interprétation de JavaScript
  • Assurez-vous que votre code HTML et JavaScript sont corrects
  • Évitez d'utiliser de complexe bibliothèques (jQuery semble être correctement pris en charge)
  • Essayez d'utiliser des versions non minimisées des bibliothèques
  • Si vous utilisez jQuery (ou d'autres bibliothèques similaires), évitez les méthodes jQuery complexes (par exemple : ajouter dynamiquement des événements aux éléments)

Bien sûr, ces commentaires s'appliqueraient si vous contrôlez le code source que vous récupérez du serveur. Parfois, ce n'est pas le cas. Dans cette situation, vos mains sont encore plus liées.

Une option serait de supprimer l'exception avec :

Bien que cela vous permette de surmonter l'exception, aucune erreur JavaScript ne sera corrigée. Cela signifie que si le morceau de code JS qui lève cette exception s'avère crucial dans votre logique, je veux dire, vous dépendez absolument du résultat de l'exécution de ce code, vous ne pouvez pas laisser HtmlUnit gérer votre JS. Si cela s'avère être le résultat d'une requête AJAX, vous pouvez émettre la requête vous-même manuellement au lieu de laisser HtmlUnit le faire.

D'un autre côté, si le code JS qui vous pose problème n'est pas critique dans votre logique, je veux dire, il peut simplement masquer un élément ou changer une couleur dont vous ne vous souciez pas, alors supprimer l'exception serait le marche à suivre.


1 réponse 1

Oui, l'API d'espionnage est passée de Jasmine 1.3.1 à Jasmine 2.0. Il n'y a pas de version "correcte". Si vous pouvez trouver la prise en charge de l'outil pour Jasmine 2.0, je vous recommande la mise à niveau.

Je mentionne le support des outils car il semble que ce soit le problème que vous rencontrez. Jasmine 2.0 n'est sorti que depuis quelques mois (au moment de la rédaction). La prise en charge de Jasmine 2.0 dans Karma, en comparaison, est disponible depuis quelques semaines (je ne suis pas sûr des autres outils).

Pour résoudre votre problème, recherchez les outils que vous utilisez pour exécuter des tests et voyez si l'un d'entre eux prend en charge Jasmine 2.0. Si tous le font, optez pour la mise à niveau. Sinon, rétrogradez les tests de votre navigateur vers Jasmine 1.3.1 et attendez que la prise en charge de l'outil soit meilleure. Assurez-vous simplement que vous êtes cohérent dans tous les domaines.


C'est une idée fausse commune que l'entrée de l'utilisateur peut être filtrée. PHP a même une "fonctionnalité" (maintenant obsolète), appelée magic-quotes, qui s'appuie sur cette idée. C'est n'importe quoi. Oubliez le filtrage (ou le nettoyage, ou peu importe comment les gens l'appellent).

Ce que vous devez faire, pour éviter les problèmes, est assez simple : chaque fois que vous intégrez une donnée dans un code étranger, vous devez la traiter selon les règles de formatage de ce code. Mais vous devez comprendre que de telles règles pourraient être trop compliquées pour essayer de toutes les suivre manuellement. Par exemple, en SQL, les règles pour les chaînes, les nombres et les identifiants sont tous différents. Pour votre commodité, dans la plupart des cas, il existe un outil dédié pour une telle intégration. Par exemple, lorsque vous devez utiliser une variable PHP dans la requête SQL, vous devez utiliser une instruction préparée, qui prendra en charge tout le formatage/traitement approprié.

Un autre exemple est HTML : si vous insérez des chaînes dans le balisage HTML, vous devez l'échapper avec htmlspecialchars . Cela signifie que chaque instruction echo ou print doit utiliser htmlspecialchars .

Un troisième exemple pourrait être les commandes shell : si vous allez intégrer des chaînes (telles que des arguments) à des commandes externes et les appeler avec exec , vous devez utiliser escapeshellcmd et escapeshellarg .

JSON est également un exemple très convaincant. Les règles sont si nombreuses et compliquées que vous ne pourriez jamais toutes les suivre manuellement. C'est pourquoi vous ne devez jamais créer une chaîne JSON manuellement, mais utilisez toujours une fonction dédiée, json_encode() qui formatera correctement chaque bit de données.

Le seulement cas où vous devez filtrer activement les données, c'est si vous acceptez une entrée préformatée. Par exemple, si vous laissez vos utilisateurs publier un balisage HTML, que vous prévoyez d'afficher sur le site. Cependant, vous devriez être prudent d'éviter cela à tout prix, car peu importe à quel point vous le filtrez, ce sera toujours une faille de sécurité potentielle.


  1. Cette combinaison de itertools.chain et itertools.repeat créera un itérateur qui produira des chaînes "Enter a number : " once, et "Pas a number ! Essayez à nouveau : " un nombre infini de fois :
  2. réponses = map (entrée, invites) - ici, map appliquera toutes les chaînes d'invite de l'étape précédente à la fonction d'entrée. Par exemple.:
  3. Nous utilisons filter et str.isdigit pour filtrer les chaînes qui ne contiennent que des chiffres : Et pour obtenir uniquement la première chaîne de chiffres uniquement, nous utilisons next .

Méthodes de chaîne : Bien sûr, vous pouvez utiliser d'autres méthodes de chaîne comme str.isalpha pour obtenir uniquement des chaînes alphabétiques, ou str.isupper pour obtenir uniquement des majuscules. Voir la documentation pour la liste complète.

Test d'adhésion :
Il y a plusieurs façons différentes de l'exécuter. L'un d'eux consiste à utiliser la méthode __contains__ :

Comparaison des nombres :
Il existe des méthodes de comparaison utiles que nous pouvons utiliser ici. Par exemple, pour __lt__ ( < ):

Ou, si vous n'aimez pas utiliser les méthodes dunder (dunder = double-underscore), vous pouvez toujours définir votre propre fonction ou utiliser celles du module opérateur.

Existence du chemin :
Ici, on peut utiliser la bibliothèque pathlib et sa méthode Path.exists :


La meilleure technique consiste à augmenter le niveau d'avertissement de votre compilateur. Il vous avertira ensuite de l'affectation potentielle dans le conditionnel if.

Assurez-vous de compiler votre code sans aucun avertissement (ce que vous devriez faire de toute façon). Si vous voulez être pédant, configurez votre compilateur pour qu'il traite les avertissements comme des erreurs.

L'utilisation de conditions Yoda (en mettant la constante sur le côté gauche) était une autre technique qui était populaire il y a environ une décennie. Mais ils rendent le code plus difficile à lire (et donc à maintenir en raison de la manière non naturelle dont ils lisent (sauf si vous êtes Yoda)) et n'offrent pas plus d'avantages que d'augmenter le niveau d'avertissement (qui présente également des avantages supplémentaires liés à davantage d'avertissements).


Remarque avant de commencer :

Cette fonctionnalité dépend à la fois de votre matériel et de votre logiciel. Si votre matériel ne prend pas en charge les contrôles de vitesse des ventilateurs ou ne les montre pas au système d'exploitation, il est très probable que vous ne puissiez pas utiliser cette solution. Si c'est le cas, mais que le logiciel (aka kernel) ne sait pas comment le contrôler, vous n'avez pas de chance.

Installez les packages lm-sensors et fancontrol.

Configurer capteurs lm comme suit:

Dans le terminal, tapez sudo sensor-detect et répondez OUI à toutes les questions OUI/non.
(Potentiellement, cela peut endommager votre système ou provoquer une panne du système. Pour beaucoup de systèmes, c'est sûr. Il n'y a aucune garantie que ce processus n'endommagera pas votre système de façon permanente, je pense simplement que la chance d'une telle défaillance critique est vraiment vraiment bas. Sauvegarder tout votre travail pour d'éventuels plantages/gels/redémarrages avant de gérer la configuration du système est toujours une bonne idée. Si vous n'êtes pas sûr, lisez les commentaires et essayez de rechercher sur le Web et d'obtenir un aperçu de haut niveau avant de tout OUI, peut-être qu'être sélectif avec votre OUI sera toujours suffisant)

A la fin de la détection des capteurs, une liste des modules qui doivent être chargés sera affichée. Tapez "yes" pour que les capteurs-detect insèrent ces modules dans /etc/modules, ou modifiez vous-même /etc/modules.

Exécutez sudo service kmod start Cela lira les modifications que vous avez apportées à /etc/modules à l'étape 3 et insère les nouveaux modules dans le noyau.

  • Noter: Si vous exécutez Ubuntu 12.04 ou une version antérieure, cette commande de 3ème étape doit être remplacée par sudo service module-init-tools restart

Configurer contrôle du ventilateur

  1. Dans le terminal, tapez sudo pwmconfig . Ce script arrêtera chaque ventilateur pendant 5 secondes pour savoir quels ventilateurs peuvent être contrôlés par quelle poignée PWM. Une fois que le script a parcouru tous les ventilateurs, vous pouvez configurer quel ventilateur correspond à quelle température.
  2. Vous devrez spécifier quels capteurs utiliser. C'est un peu délicat. Si vous n'avez qu'un seul ventilateur, assurez-vous d'utiliser un capteur de température pour votre noyau sur lequel baser la vitesse de contrôle du ventilateur.
  3. Parcourez les invites et enregistrez les modifications dans l'emplacement par défaut.
  4. Faites des ajustements pour affiner /etc/fancontrol et utilisez sudo service fancontrol restart pour appliquer vos modifications. (Dans mon cas, j'ai réglé l'intervalle sur 2 secondes.)

Installation contrôle du ventilateur service

  1. Exécutez sudo service fancontrol start . Cela permettra également au service fancontrol de s'exécuter automatiquement au démarrage du système.

Dans mon cas /etc/fancontrol pour CPU j'ai utilisé :

Paramètres pour hwmon0/device/pwm2 :
(Dépend de hwmon0/device/temp2_input) (Contrôle hwmon0/device/fan2_input)


13 réponses 13

Il est important de distinguer ici entre instances uniques et le modèle de conception Singleton.

Instances uniques sont simplement une réalité. La plupart des applications ne sont conçues que pour fonctionner avec une configuration à la fois, une interface utilisateur à la fois, un système de fichiers à la fois, etc. S'il y a beaucoup d'états ou de données à maintenir, alors vous voudriez certainement n'avoir qu'une seule instance et la garder en vie aussi longtemps que possible.

le célibataire design pattern est un très spécifique taper d'instance unique, en particulier celle qui est :

  • Accessible via un champ d'instance global et statique
  • Créé soit à l'initialisation du programme, soit au premier accès
  • Pas de constructeur public (impossible d'instancier directement)
  • Jamais explicitement libéré (implicitement libéré à la fin du programme).

C'est à cause de ce choix de conception spécifique que le motif introduit plusieurs problèmes potentiels à long terme :

  • Incapacité à utiliser des classes abstraites ou d'interface
  • Incapacité de sous-classer
  • Couplage élevé à travers l'application (difficile à modifier)
  • Difficile à tester (ne peut pas simuler/se moquer dans les tests unitaires)
  • Difficile à paralléliser en cas d'état mutable (nécessite un verrouillage poussé)
  • etc.

Aucun de ces symptômes n'est en fait endémique à des instances uniques, juste le modèle Singleton.

Que pouvez-vous faire à la place ? N'utilisez tout simplement pas le modèle Singleton.

Citant la question :

L'idée était d'avoir cet endroit dans l'application qui conserve les données stockées et synchronisées, puis tout nouvel écran ouvert peut simplement interroger la plupart de ce dont ils ont besoin à partir de là, sans faire de demandes répétitives pour diverses données de support du serveur. Demander constamment au serveur prendrait trop de bande passante - et je parle de milliers de dollars de factures Internet supplémentaires par semaine, donc c'était inacceptable.

Ce concept a un nom, comme vous le faites allusion, mais que vous semblez incertain. C'est ce qu'on appelle un cache. Si vous voulez faire preuve de fantaisie, vous pouvez l'appeler un "cache hors ligne" ou simplement une copie hors ligne des données distantes.

Un cache n'a pas besoin d'être un singleton. Il mai doit être une instance unique si vous voulez éviter de récupérer les mêmes données pour plusieurs instances de cache, mais cela ne signifie pas que vous devez réellement tout exposer à tout le monde.

La première chose que je ferais est de séparer les différents domaines fonctionnels du cache dans des interfaces distinctes. Par exemple, supposons que vous créiez le pire clone YouTube au monde basé sur Microsoft Access :

Ici vous avez plusieurs interfaces décrivant le spécifique types de données auxquels une classe particulière peut avoir besoin d'accéder - supports, profils utilisateur et pages statiques (comme la page d'accueil). Tout cela est mis en œuvre par un méga-cache, mais vous concevez vos classes individuelles pour accepter les interfaces à la place, de sorte qu'elles ne se soucient pas du type d'instance dont elles disposent. Vous initialisez l'instance physique une fois, au démarrage de votre programme, puis commencez simplement à transmettre les instances (transtypées vers un type d'interface particulier) via des constructeurs et des propriétés publiques.

C'est ce qu'on appelle l'injection de dépendances, d'ailleurs vous n'avez pas besoin d'utiliser Spring ou un conteneur IoC spécial, tant que votre conception de classe générale accepte ses dépendances de l'appelant à la place de en les instanciant tout seul ou alors référencement de l'état global.

Pourquoi devriez-vous utiliser la conception basée sur l'interface ? Trois raisons :

Cela rend le code plus facile à lire que vous pouvez clairement comprendre à partir des interfaces exactement quelles données dont dépendent les classes dépendantes.

Si et quand vous réalisez que Microsoft Access n'était pas le meilleur choix pour un back-end de données, vous pouvez le remplacer par quelque chose de mieux - disons SQL Server.

Si et quand vous réalisez que SQL Server n'est pas le meilleur choix pour les médias Plus précisément, vous pouvez diviser votre implémentation sans affecter aucune autre partie du système. C'est là qu'intervient le vrai pouvoir de l'abstraction.

Si vous voulez aller plus loin, vous pouvez utiliser un conteneur IoC (cadre DI) comme Spring (Java) ou Unity (.NET). Presque chaque framework DI fera sa propre gestion de la durée de vie et vous permettra spécifiquement de définir un service particulier en tant qu'instance unique (souvent l'appelant "singleton", mais c'est seulement pour la familiarité). Fondamentalement, ces frameworks vous évitent la plupart du travail de singe de passer manuellement les instances, mais ils ne sont pas strictement nécessaires. Vous n'avez pas besoin d'outils spéciaux pour mettre en œuvre cette conception.

Par souci d'exhaustivité, je dois souligner que la conception ci-dessus n'est vraiment pas idéale non plus. Lorsque vous avez affaire à un cache (comme vous l'êtes), vous devriez en fait avoir un couche. En d'autres termes, un design comme celui-ci :

L'avantage de ceci est que vous n'avez même jamais besoin de briser votre instance de cache si vous décidez de refactoriser, vous pouvez changer la façon dont le média est stocké simplement en lui fournissant une implémentation alternative de IMediaRepository . Si vous réfléchissez à la façon dont cela s'emboîte, vous verrez qu'il ne crée toujours qu'une seule instance physique d'un cache, vous n'avez donc jamais besoin de récupérer les mêmes données deux fois.

Rien de tout cela ne veut dire que chaque logiciel dans le monde doit être conçu selon ces normes rigoureuses de cohésion élevée et de couplage lâche, cela dépend de la taille et de la portée du projet, de votre équipe, de votre budget, des délais, etc. Mais si vous demandez quel est le meilleur design (à utiliser à la place d'un singleton), alors c'est tout.


Le "problème XY" comme spécialisation du "comportement d'hypothèse erronée"

Vous voulez résoudre la vraie question-X, et vous pensez en termes de contexte Y, et essayez d'utiliser la question-Y. Au lieu de poser des questions sur le contexte X , vous posez des questions sur le contexte Y .
(comme @Gnome l'a remarqué ci-dessus, mais en utilisant d'autres mots)

Alors, "Problème XY" n'est qu'un autre terme (plus spécialisé) pour dire "Utilisation d'une hypothèse de travail erronée".

Éviter le problème XY

Je soutiens que vous ne pouvez pas l'éviter. Non sans simplement lancer vos exigences de programme à SO et leur demander de faire votre conception pour vous (non recommandé).

Je soutiens cela parce que le processus de conception de tous les logiciels est basé sur un ensemble d'exigences de départ « A ». À partir de là, vous dites "Je peux atteindre A si je fais B et C". À partir de là, vous dites "Je peux atteindre B si je fais D et E et je peux atteindre C si je fais F et G". Et cela continue au point où nous disons que "je peux atteindre X si je fais Y". Nous le faisons habituellement si vite que nous ne pensons même pas au processus.

Ainsi, le problème majeur avec le problème XY est que Y n'est pas possible, mais vous ne savez pas quelle partie de votre conception vous devez dérouler pour revenir au X qui est possible. En général, vous ne savez même pas que Y est impossible sans le demander. Vous ne savez pas ce que vous ne savez pas. Il est donc inévitable

Poser des questions là où vous risquez de tomber dans XY

La meilleure chose que vous puissiez faire à propos du problème XY est de vous en prémunir lorsque vous posez des questions. Posez toujours la même question mais donnez autant pertinent informations possibles :

  • Exposez votre problème
  • Dites ce que vous essayez d'atteindre
  • Indiquez comment il s'intègre dans votre conception plus large

Cela aidera les gens à identifier que c'est XY et vous aidera beaucoup plus rapidement.

IMPORTANT : donner des réponses aux problèmes XY

À mon avis, le plus gros problème avec les questions XY est les réponses (souvent) inutiles qu'elles provoquent. Nous n'arrêterons jamais les gens de poser ces questions, le mieux est donc de comprendre comment nous pouvons y répondre rapidement et efficacement.

Ironiquement, beaucoup de ces mauvaises réponses et réponses sont données par ceux qui veulent être les plus utiles et peuvent être données par certaines des personnes les plus réputées du forum / SO.

J'ai découvert une méthode pour répondre à ces questions qui semble aider à contourner la psychologie associée aux problèmes XY et à conduire l'OP d'une question à une solution de travail. La méthode prend un peu plus de temps à répondre dans un premier temps mais ferme la boucle Q/A beaucoup plus rapidement.

Je vous suggère de répondre à la question en trois parties et de les donner dans l'ordre suivant.

Répondez à la question de l'OP. Même si le PO a probablement besoin d'autre chose, ne négligez jamais de répondre à la question qu'il a réellement posée en premier et non à la question à laquelle vous pensez qu'il souhaite une réponse. Dans certains cas, cette réponse peut être "O n'est pas possible". Trop souvent, je vois des réponses (commentaires) demandant "Pourquoi avez-vous besoin de cela?". Cela ne donne rien à l'OP. Si tu le dis « Cela va être très difficile. Expliquez pourquoi vous en avez besoin, nous pourrons peut-être vous aider » alors dans de nombreux cas, un PO prendra simplement le "Y est vraiment dur" et retournez à la planche à dessin. C'est bien parce que vous avez répondu à leur question et ils pourraient bien revenir avec la question X eux-mêmes.

Discuter de la tentative de solution du PO. Ce bit est délicat et demande un peu de réflexion. Mais je ne peux pas souligner à quel point c'est important. Si le PO a demandé Y et que vous pensez qu'il veut X, après avoir répondu à sa question (1), continuez à parler de Y (PAS X). A quoi est censé servir Y ? En quoi cela ne s'applique-t-il pas à X ? L'essentiel est de continuer à parler de la question mais de passer de la réponse à la fourniture d'informations utiles. Parce qu'après tout, c'est ce dont vous pensez que l'OP a besoin. Des informations utiles et non la réponse à leur question.

Résoudre X C'est ce que vous aviez envie de faire et c'est tout l'intérêt de votre réponse après tout. Vous avez rencontré le PO selon ses conditions et répondu à sa question. Vous les avez aidés à comprendre les failles de leur question et pourquoi résoudre Y n'est pas la chose à faire. alors maintenant vous êtes tout à fait justifié d'expliquer une solution à X.

La plupart des gens sont ici pour apprendre, donc les parties 1 et 2 de cette réponse sont aussi importantes que la partie 3. Mais trop souvent, la partie 3 est donnée seule et c'est extrêmement frustrant et condescendant pour l'OP sans parler de beaucoup d'OP. accepter la réponse.

Donner cette réponse évite également l'embarras lorsque vous pensez que l'OP a un problème XY alors qu'en fait ce n'est pas le cas. Tout ce que vous avez fait est de donner quelques informations supplémentaires. Le simple fait de donner la partie 3 risque de donner l'impression de ne pas avoir lu la question.

Incidemment. Relisez la question et lisez cette réponse. remarquez les trois parties?