«Entre x et y» doit-il être commutatif?

26

Dans mon application, il existe des modèles d'expression prédéfinis qui peuvent être utilisés pour filtrer les données. L'un d'eux est " between x and y". Un ingénieur QA affirme qu'il y a un défaut dans sa définition, car " between 100 and 200" donne des résultats différents de " between 200 and 100". L'expression est traduite en interne par " value >= x and value <= y", donc il n'y a évidemment aucun résultat lorsque la deuxième limite est inférieure à la première. J'ai vérifié que le même comportement est en SQL - " between x and y" suppose que y> = x ou il n'y a aucun résultat. Cela signifie que l'opérateur n'est pas commutatif, du moins en SQL.

Donc, le QA a-t-il raison de dire que " between x and y" devrait être commutatif?

pkalinow
la source
11
Non, mais peut-être que votre interface utilisateur devrait devenir rouge lorsque quelqu'un la remplit mal.
Ewan
3
aussi, l'un de ceux-ci> = <= devrait être exclusif afin que vous puissiez enchaîner 100-> 200 200-> 300 etc. sans obtenir de chevauchements
Ewan
23
Il n'est pas clair si betweendoit inclure ou exclure les valeurs inférieures et supérieures. La personne chargée de l'assurance qualité peut être pédante, mais tant qu'il y a de l'incertitude, quelqu'un doit clarifier les histoires / exigences des utilisateurs. Il pourrait s'avérer que la façon dont cela se fait est de savoir comment cela est censé être, mais une décision doit être prise.
Bent
11
Ce n'est pas un cas de bien ou de mal. Il s'agit de ... comment l'entreprise souhaite-t-elle que l'application se comporte? La réponse est quelle fonctionnalité est attendue. Les débats techniques ne déterminent pas la fonctionnalité requise. La fonctionnalité requise anime les débats techniques et, espérons-le, inspire la meilleure solution pour l'entreprise.
Brad Thomas
2
Cette question concerne davantage ce que l'utilisateur attend que ce à quoi s'attend un programmeur. En tant que tel, il serait plus approprié sur l'expérience utilisateur .
Makyen

Réponses:

32

Si votre spécification actuelle laisse cela indéfini, le comportement est complètement arbitraire, il n'y a pas de définition "correcte" ou "incorrecte". Donc, si votre ingénieur QA ne peut pas vous indiquer le paragraphe exact de la spécification où ce comportement est défini, vous pouvez probablement refuser sa demande (bien que cela ne semble pas être une exigence qui nécessite beaucoup d'efforts pour l'implémenter). Si vous ne parvenez pas tous les deux à trouver un consensus, une personne de votre équipe doit prendre une décision plus importante dans le contexte de la candidature:

  • en suivant au plus près le standard SQL
  • ne pas le suivre en raison de l'ergonomie, des cas d'utilisation spécifiques ou d'autres exigences

Quelle que soit la décision prise par votre équipe, ce pourrait être une bonne idée de documenter le comportement et la raison pour laquelle la décision a été prise.

Doc Brown
la source
57
vous pouvez probablement refuser sa demande => je dirais en fait que le comportement doit être défini avant tout. Ensuite, vous pouvez remercier le responsable de l'assurance qualité pour avoir signalé le problème et dire qu'il est maintenant spécifié de fonctionner de <manière spécifique> (et assurez-vous que le code correspond à la spécification).
Matthieu M.
1
@MatthieuM. Je pense que c'est une réponse distincte qui devrait avoir 33 propres votes positifs. ;)
jpmc26
1
Convertissez le bogue en amélioration et laissez-le dans le backlog pour la perpétuité. Merci à QA pour sa diligence.
Sandy Chapman
1
@MatthieuM. oui, dans un monde idéal, il y aurait une exigence claire pour chaque détail. Dans un tel cas, je n'aurais pas besoin de poser de questions sur Stack Exchange :)
pkalinow
@pkalinow: Je pense que vous avez mal compris mon commentaire. Mon point était qu'avant de fermer le bogue, vous devriez (1) remercier le responsable de l'assurance qualité pour avoir signalé un morceau de code non spécifié et (2) s'asseoir avec toute personne intéressée pour réellement spécifier le comportement. Cela peut impliquer d'attribuer le rapport d'AQ à quiconque est en charge de la rédaction des spécifications, au propriétaire du produit si vous avez de telles choses, etc. ou pas. Peut-être que cela signifiera changer le logiciel, peut-être que cela signifiera fermer le rapport ...
Matthieu M.
13

Il s'agit d'une question de convivialité ou d'expérience utilisateur. Le comportement de SQL ou de tout autre système est sans importance, la question est de savoir ce qui est le plus logique du point de vue des utilisateurs.

Le comportement actuel n'a pas de sens du point de vue de l'utilisateur. Soit x et y doivent être interchangeables, soit il ne doit pas être autorisé à sélectionner un x plus grand que y. Autoriser x plus grand que y mais renvoyer un ensemble vide introduit une possibilité inutile d'erreurs sans aucun avantage.

Donc l'ingénieur QA a raison il y a un défaut, mais la solution proposée n'est pas forcément la meilleure. Vous devez effectuer des tests d'utilisabilité pour en décider, ou au moins demander à certains utilisateurs représentatifs ce qui leur semble le plus naturel.

Alternativement, vous pouvez poser la question sur /ux// . Les gens là-bas connaissent en fait une chose ou deux sur l'expérience utilisateur.

JacquesB
la source
11

Il y a quelques choix judicieux, et lequel choisir dépend du reste du système et des attentes de vos utilisateurs.

Comme le souligne l'ingénieur QA, vous pouvez simplement rendre l'expression commutative, puis la traduction serait

between x and y => value >= min(x, y) and value <= max(x, y)

Vous pouvez restreindre l'utilisation valide à x <= y, ce qui nécessite plutôt que votre interface utilisateur puisse afficher "ce n'est pas une expression valide" le plus tôt possible.

Comme variation de ce qui précède, la restriction x < ysi vous avez une expression equals xet préférez celle à l'évaluationvalue >= x and value <= x

Caleth
la source
Remarque: veuillez ne pas faire la déclaration elle-même value >= min(x, y) and value <= max(x, y). Précalculez ce que vous pouvez pour enregistrer le travail de votre serveur de base de données, surtout s'il est redondant comme ça (vous pouvez effectuer les opérations pertinentes une fois et définir les deux résultats en conséquence). Cela peut ne pas avoir d'importance, selon le serveur de base de données et les valeurs spécifiques que vous alimentez, mais un serveur SQL mal écrit pourrait bien exécuter le minet maxpour chaque enregistrement si vous les mettez dans le where, et si vous pouvez éliminer cet effort , il n'y a aucune raison de ne pas le faire.
Fund Monica's Lawsuit
6
Veuillez ne pas écouter QPaysTaxes - optimiser les choses sans jamais mesurer la nécessité est exactement ce que Knuth a appelé "l'optimisation prématurée étant la racine de tout mal". Les chances sont élevées dans la plupart des codes du monde réel, vous ne remarquerez pas de différence de vitesse si Min et Max sont calculés pour chaque enregistrement, mais le précalcul des valeurs (et donc l'introduction de code supplémentaire et de redondance supplémentaire) rendra le programme beaucoup moins maintenable.
Doc Brown
@DocBrown Je suis d'accord pour dire que nous ne devrions pas apporter de modifications aux gains de performances potentiels sans mesurer, mais contrairement à votre affirmation, je trouverais des limites précalculées plus lisibles qu'une ligne unique, et donc plus maintenables.
Jacob Raihle
@JacobRaihle: cela peut être subjectif, mais à mon goût value >= min(x, y) and value <= max(x, y)est aussi lisible que value >= minXY and value <= maxXY, où minXYet maxXYsont les limites précalculées. Cependant, pour ce dernier, il faudra écrire du code pour ajouter ces deux nouvelles variables au système, les remplir au préalable, n'oubliez pas de mettre à jour ces valeurs lorsque x et y changent, etc. Les données redondantes présentent toujours un certain risque d'erreurs.
Doc Brown
5

Dans un cadre non interactif, où vos limites sont créées par un script, il est généralement logique de les exiger dans l'ordre. Cela crée une vérification de validation en moins, a plus de sens sémantiquement et est trivial à gérer.

Dans un cadre interactif, vous souhaitez aider l'utilisateur. Si possible, créez une interface graphique qui n'autorise pas la saisie des plages permutées, ou du moins facilite la saisie des plages dans l'ordre. Si vous entrez les plages par texte, prenez une page de vim, ce modèle de convivialité, et invitez l'utilisateur à permuter automatiquement les plages inversées:

Backwards range given, OK to swap (y/n)?

Si votre ingénieur QA n'avait rien sur le chemin de l'UX pour lui montrer qu'une plage inversée serait indésirable, alors il a fait une hypothèse raisonnable.

Karl Bielefeldt
la source
2

Franchement? N'utilisez pas "entre". Du tout.

Premièrement, le terme est incroyablement ambigu, surtout en anglais. Est-ce commutatif? Les termes sont-ils exclusifs? Compris?

Deuxièmement, si vous faites une interface séparée du backend, ne vous inquiétez pas du comportement du backend; et ne laissez pas non plus vos utilisateurs adopter un comportement hérité. Bien sûr, SQL définit son BETWEENcomme inclusif, mais ce n'est presque jamais le comportement souhaité (par exemple - Si vous faites quelque chose comme rows BETWEEN :start and :start + :stridevous allez obtenir des stride + 1lignes).

Au lieu de cela, vous devez répertorier explicitement les comparaisons pour les points de terminaison. "Supérieur ou égal à x". "Avant aujourd'hui". Cela supprime l'ambiguïté. Cela permet également d'écrire du code plus propre et d'éviter certaines erreurs insidieuses. L'exemple de lignes du précédent est essentiellement le post de Djikstra sur l'indexation . Et autoriser SQL à utiliser une limite supérieure inclusive sur certains types peut entraîner la sélection de données incorrectes .

Clockwork-Muse
la source
Eh bien, ça vaut la peine d'y penser. Et merci pour les liens. Le post de Dijkstra n'est probablement pas très pertinent, mais intéressant :)
pkalinow
Cela ne répond pas vraiment à la question OP, au contraire, cela ajoute à la confusion.
Roland Tepp
1

Il n'est pas productif de discuter avec votre AQ pour savoir qui a «raison» et qui a «tort». Vous avez interprété la spécification différemment qu'eux. Cela signifie que la spécification est suffisamment ambiguë pour qu'elle nécessite des éclaircissements.

Si l'interface utilisateur est la spécification et que ce n'est pas le comportement que le contrôle qualité attend, ce ne sera pas le comportement au moins auquel certains utilisateurs s'attendent. Cela indique un problème de convivialité (même si vous voulez argumenter PEBKAC). Travaillez avec votre AQ pour trouver une solution satisfaisante à cela.

En règle générale, faites attention aux mots comme «entre» qui semblent clairs, mais qui ne le sont pas. Mis à part votre désaccord sur l'opportunité de faire la navette, ce sont des problèmes d'inclusivité à chaque extrémité et peuvent signifier intuitivement des choses différentes sur différents domaines (par exemple, "entre vendredi et lundi" signifiera quelque chose de différent pour la plupart des gens que "entre lundi et Vendredi")

Martijn
la source
1

Je bifurquerai un principe UNIX qui parle d'interfaces simples.

Partout où il y a une interface que vous offrez au monde extérieur, gardez la chose la moins surprenante possible!

Maintenant que j'ai réduit l'énoncé du problème à un énoncé plus pragmatique, je pense qu'il ne vous faudra que quelques instants pour réaliser que lors de la spécification des plages de nombres, il est évident de *** garder le plus petit comme l'ancien ***. Si c'est encore une énigme, pensez comme ceci - Combien de fois avez-vous utilisé la façon inverse de représenter deux nombres tout en disant aux enfants comment les comparer?

Si votre ingénieur QA appelle cela un bug, dites-lui poliment que vous vous attendez à de vrais bugs, et non à des moyens de transmettre une énergie coûteuse sur des choses triviales.

an4
la source
0

Faites en sorte que votre code de débogage renvoie une condition d'erreur ou enregistrez un avertissement chaque fois que les valeurs sont transmises dans le mauvais ordre. De cette façon, le code appelant peut vérifier et échanger des paramètres, si nécessaire. De cette façon, les utilisateurs de cette «fonctionnalité» deviendront conscients et feront la bonne chose (que vous ne connaissez pas au préalable).

Grimaldi
la source