Plusieurs fois, lors de la génération de messages à montrer à l'utilisateur, le message contiendra un certain nombre de choses que je souhaite informer le client.
Je vais donner un exemple: le client a sélectionné un certain nombre d'articles de 1 et plus, et a cliqué sur supprimer. Maintenant, je veux donner un message de confirmation au client, et je veux mentionner le nombre d'articles qu'il a sélectionnés pour minimiser le risque qu'il fasse une erreur en sélectionnant un groupe d'articles et en cliquant sur supprimer lorsqu'il ne veut supprimer qu'un des leur.
Une façon est de rendre le message générique comme ceci:
int noofitemsselected = SomeFunction();
string message = "You have selected " + noofitemsselected + " item(s). Are you sure you want to delete it/them?";
Le "problème" ici est le cas où noofitemselected
est 1, et nous devons écrire item et it à la place des items et eux .
Ma solution normale sera quelque chose comme ça
int noofitemsselected = SomeFunction();
string message = "You have selected " + noofitemsselected + " " + (noofitemsselected==1?"item" : "items") + ". Are you sure you want to delete " + (noofitemsselected==1?"it" : "them") + "?";
Cela devient assez long et assez désagréable très rapidement s'il y a beaucoup de références à la pluralité de nombres dans le code et que le message réel devient difficile à lire.
Mes questions sont donc simples. Existe-t-il de meilleures façons de générer des messages comme celui-ci?
ÉDITER
Je vois que beaucoup de personnes ont été très accrochées dans le cas où j'ai mentionné que le message devrait être affiché dans une boîte de message, et a simplement donné une réponse sur la façon d'éviter d'utiliser la boîte de message du tout, et c'est très bien .
Mais rappelez-vous que le problème de la pluralisation s'applique également aux textes à d'autres endroits du programme en plus des boîtes de message. Par exemple, une étiquette à côté d'une grille affichant le nombre de lignes sélectionnées dans la grille aura le même problème de pluralisation.
Donc, cela s'applique fondamentalement à la plupart du texte qui est produit d'une manière ou d'une autre à partir de programmes, et la solution n'est pas aussi simple que de simplement changer le programme pour ne plus afficher de texte :)
la source
Réponses:
S'il y a une chance, aussi petite soit-elle, que cette application doive être traduite dans d'autres langues, les deux sont fausses. La bonne façon de procéder est:
En effet, différentes langues gèrent la pluralité différemment. Certains comme le malais n'ont même pas de pluriel syntaxique, donc les chaînes seraient généralement identiques. La séparation des deux chaînes facilite la prise en charge ultérieure d'autres langues.
Sinon, si cette application est destinée à être utilisée par le grand public et qu'elle est censée être conviviale, la deuxième méthode est préférable. Désolé mais je ne connais pas vraiment une manière plus courte de faire cela.
Si cette application est destinée à être utilisée uniquement en interne par votre entreprise, faites le raccourci
"item(s)"
. Vous n'avez pas vraiment besoin d'impressionner qui que ce soit lorsque vous écrivez un code d'entreprise. Mais je déconseille de faire cela pour une application consommée publiquement, car cela donne l'impression que le programmeur est paresseux et diminue ainsi son opinion sur la qualité de l'application. Croyez-moi, de petites choses comme ça comptent.la source
noofitemsselected
dans cet exemple pour la première option; puisque vous savez qu'il est 1.Vous pouvez éviter toute cette pluralité désordonnée en supprimant simplement les éléments sans aucun message et en donnant à l'utilisateur une très bonne fonction d'annulation. Les utilisateurs ne lisent jamais rien . Vous devriez quand même créer une bonne fonction d'annulation dans le cadre de votre programme.
Vous obtenez en fait 2 avantages lorsque vous créez une fonction d'annulation complète. Le premier avantage facilite la vie de l'utilisateur en lui permettant d'inverser les erreurs et de minimiser la lecture. Le deuxième avantage est que votre application reflète la vie réelle en permettant l'inversion d'un flux de travail non trivial (pas seulement des erreurs).
Une fois, j'ai écrit une application sans utiliser une seule boîte de dialogue ou un seul message de confirmation. Il a fallu une réflexion sérieuse et était beaucoup plus difficile à mettre en œuvre que l'utilisation de messages de type confirmation. Mais le résultat final était plutôt agréable à utiliser selon ses utilisateurs finaux.
la source
Que diriez-vous simplement:
De cette façon, vous éliminez les difficultés d'accord de nombre et vous vous retrouvez avec un message d'erreur encore plus court et plus précis pour l'utilisateur en prime. Nous savons tous que les utilisateurs ne lisent pas les messages d'erreur de toute façon . Plus ils sont courts, plus ils sont susceptibles de jeter au moins un coup d'œil sur le texte.
Ou, armé de cette connaissance que les utilisateurs ne lisent pas les messages d'erreur, vous pouvez aborder cela d'une manière différente. Ignorez complètement le message de confirmation et fournissez simplement une fonction d'annulation qui fonctionne parfaitement, indépendamment de ce qui a été supprimé. La plupart des utilisateurs sont déjà habitués à annuler une opération lorsqu'ils remarquent que ce n'était pas ce qu'ils voulaient, et trouveront probablement ce comportement plus naturel que d'avoir à gérer une autre fenêtre contextuelle ennuyeuse.
la source
Qu'en est-il de ce que Java a depuis des années: java.text.MessageFormat et ChoiceFormat? Voir http://download.oracle.com/javase/1.4.2/docs/api/java/text/MessageFormat.html pour plus d'informations.
Dans votre cas, vous voulez quelque chose d'un peu plus simple:
L'avantage de cette approche est qu'elle fonctionne bien avec les bundles i18n, et vous pouvez fournir des traductions correctement pour les langues (comme le japonais) qui n'ont pas de concept de mots au pluriel ou au singulier.
la source
J'irais sans coder en dur le message, mais en fournissant deux messages dans un fichier de ressources séparé. Comme
puis les alimenter dans String.
Je pense que cette approche est plus facile à localiser et à maintenir. Tous les messages de l'interface utilisateur seraient à un seul endroit.
la source
Vous pouvez contourner le problème entièrement en formulant le message différemment.
la source
La première chose que je suggérerais est: utiliser
string.Format
. Cela vous permet de faire quelque chose comme ceci:De plus, dans les applications WPF, j'ai vu des systèmes dans lesquels une chaîne de ressources serait délimitée par un tube pour avoir deux messages: un message singulier et un message pluriel (ou même un message zéro / unique / plusieurs). Un convertisseur personnalisé pourrait ensuite être utilisé pour analyser cette ressource et utiliser la chaîne appropriée (formatée), donc votre Xaml est quelque chose comme ceci:
la source
Pour l'anglais, beaucoup de réponses ci-dessus. Pour d'autres langues, c'est plus difficile, car les pluriels dépendent du sexe du nom et de la fin du mot. Quelques exemples en français:
Masculin régulier:
Féminin régulier
Masculin irrégulier (se termine par 's')
Le même problème existe dans la plupart des langues latines et s'aggrave en allemand ou en russe, où il y a 3 genres (maculine, féminin et neutre).
Vous devrez faire attention si votre objectif est de gérer plus que juste l'anglais.
la source
Pour pouvoir disposer de messages pluralisés qu'il sera possible de localiser correctement, mon avis est qu'il serait judicieux de créer d'abord une couche d'indirection entre le numéro et un message.
Par exemple, utilisez une constante quelconque pour spécifier le message que vous souhaitez afficher. Récupérez le message en utilisant une fonction qui masquera les détails de l'implémentation.
Ensuite, créez un dictionnaire qui contient les messages et les variantes possibles, et faites savoir aux variantes quand elles doivent être utilisées.
Maintenant, vous pouvez simplement trouver la clé qui correspond à
quantity
et interpoler la valeur dequantity
avec ce message.Cet exemple simpliste et naïf, mais je ne vois pas vraiment d'autre moyen sensé de le faire et de pouvoir fournir un bon support pour L10N et I18N.
la source
Vous devrez traduire la fonction ci-dessous de VBA en C #, mais votre utilisation changerait en:
J'ai une fonction VBA que j'utilise dans MS Access pour faire exactement ce dont vous parlez. Je sais que je vais être piraté en morceaux pour avoir publié VBA, mais ici va quand même. L'algorithme doit être apparent à partir des commentaires:
L'utilisation a été un peu coupée dans les commentaires de code ci-dessus, je vais donc le répéter ici:
Oui, cette solution ignore les langues qui ne sont pas l'anglais. Que cela compte dépend de vos besoins.
la source
Vous pouvez générer le pluriel automatiquement, voir par exemple. générateur pluriel .
Pour les règles de génération de pluriel, voir wikipedia
la source
Que diriez-vous d'une manière plus générique. Évitez la pluralisation dans la deuxième phrase:
Je découvre que faire de cette façon met le nombre à la fin de la ligne qui est vraiment facile à repérer. Cette solution fonctionnerait avec la même logique dans n'importe quelle langue.
la source
Number
(je répondais en berçant mon bébé pour qu'il s'endorme).Mon approche générale est d'écrire une "fonction simple / plurielle", comme ceci:
Ensuite, dans le corps du message, j'appelle cette fonction:
Ce n'est pas beaucoup mieux, mais au moins ça, (a) met la décision dans une fonction et donc désencombre un peu le code, et (b) est assez flexible pour gérer les pluriels irréguliers. c'est-à-dire qu'il est assez facile de dire un nom (n, "enfant", "enfants") et autres.
Bien sûr, cela ne fonctionne que pour l'anglais, mais le concept est facilement extensible aux langues avec des terminaisons plus complexes.
Il me vient à l'esprit que vous pourriez rendre le dernier paramètre facultatif pour le cas facile:
la source
Internationalisation
Je suppose que vous voulez une prise en charge de l'internationalisation, auquel cas différentes langues ont des modèles différents pour les pluriels (par exemple une forme plurielle spéciale pour 2 de quelque chose, ou des langues plus compliquées comme le polonais), et vous ne pouvez pas compter sur l'application d'un modèle simple à votre chaîne réparer.
Vous pouvez utiliser la
ngettext
fonction de GNU Gettext et fournir deux messages en anglais dans votre code source. Gettext fournira l'infrastructure pour choisir parmi d'autres messages (potentiellement plus) lorsqu'ils seront traduits dans d'autres langues. Voir http://www.gnu.org/software/hello/manual/gettext/Plural-forms.html pour une description complète du support pluriel de GNU gettext.GNU Gettext est sous la LGPL.
ngettext
est nomméGettextResourceManager.GetPluralString
dans le port C # de Gettext.(Si vous n'avez pas besoin de support de localisation et que vous ne voulez pas utiliser Gettext tout de suite, écrivez votre propre fonction qui fait cela pour l'anglais, et passez-lui deux messages complets , de cette façon si vous avez besoin de l10n plus tard, vous pouvez ajouter en réécrivant une seule fonction.)
la source
Que diriez-vous d'écrire une fonction comme
.. et l'utiliser quand vous en avez besoin?
la source
Pour le premier problème, je veux dire Pluralize, vous pouvez utiliser Inflector .
Et pour le second, vous pouvez utiliser une extension de représentation sous forme de chaîne avec un nom tel que ToPronounString.
la source
J'ai eu cette même question qui m'a été posée hier par un membre de notre équipe.
Depuis qu'il est revenu ici sur StackOverflow, j'ai pensé que l'univers me disait de me donner une chance de produire une solution décente.
J'ai rapidement rassemblé quelque chose et ce n'est en aucun cas parfait, mais cela pourrait être utile ou susciter une discussion / développement.
Ce code est basé sur l'idée qu'il peut y avoir 3 messages. Un pour zéro article, un pour un article et un pour plus d'un article qui suivent la structure suivante:
singlePropertyName
singlePropertyName_Zero
singlePropertyName_Plural
J'ai créé une classe interne avec laquelle tester afin d'imiter la classe de ressources. Je n'ai pas encore testé cela en utilisant un fichier de ressources réel, donc je n'ai pas encore vu le résultat complet.
Voici le code (actuellement, j'ai inclus des génériques dans lesquels je sais que j'aurais pu spécifier le troisième paramètre simplement en tant que type et le deuxième paramètre est une chaîne, je pense qu'il existe un moyen de combiner ces deux paramètres en quelque chose de mieux mais je '' J'y reviendrai quand j'aurai un moment libre.
Classe de ressources de test:
et ma méthode d'exécution rapide
la source
singlePropertyName_All
le rendre encore plus évident.De mon point de vue, votre première solution est la plus adaptée. Pourquoi je dis cela, au cas où vous auriez besoin de l'application pour prendre en charge plusieurs langues, la deuxième option peut être laborieuse. Avec la première approche, il est facile de localiser le texte sans trop d'effort.
la source
Vous pouvez opter pour un message plus générique comme «Êtes-vous sûr de vouloir supprimer les éléments sélectionnés».
la source
Je dépend de la gentillesse du message que vous voulez avoir. Du plus simple au plus difficile:
Réécrivez votre message d'erreur pour éviter la pluralisation. Pas aussi agréable pour votre utilisateur, mais plus rapide.
Utilisez un langage plus général tout en incluant le (s) nombre (s).
Utilisez un système de «pluralisation» et d'inflecteurs comme Rails, pour que vous puissiez dire
pluralize(5,'bunch')
et obtenir5 bunches
. Les rails ont un bon modèle pour cela.Pour l'internationalisation, vous devez examiner ce que fournit Java. Cela prendra en charge une grande variété de langues, y compris celles qui ont différentes formes d'adjectifs avec 2 ou 3 éléments. La solution "s" est très centrée sur l'anglais.
L'option choisie dépend de vos objectifs de produit. - ndp
la source
Pourquoi voudriez-vous présenter un message que les utilisateurs peuvent réellement comprendre? Cela va à l'encontre de 40 ans d'histoire de la programmation. Nooooo, nous avons une bonne chose en cours, ne la gâchez pas avec des messages compréhensibles .
(j / k)
la source
Faites-le comme dans World of Warcraft:
la source
Cela devient un peu plus court avec
la source
Une approche que je n'ai pas vue mentionnée serait l'utilisation d'une balise de substitution / sélection (par exemple quelque chose comme "Vous êtes sur le point d'écraser {0} [? I ({0} = 1): / cactus / cacti /]". (en d'autres termes, une expression de format spécifie la substitution en fonction du fait que l'argument zéro, pris comme entier, est égal à 1). J'ai vu de telles balises utilisées dans les jours précédant .net; je n'en connais aucune standard pour eux en .net, et je ne connais pas la meilleure façon de les formater.
la source
Je penserais hors de la boîte pendant une minute, toutes les suggestions ici sont soit faire la pluralisation (et s'inquiéter de plus d'un niveau de pluralisation, genre, etc.) ou ne pas l'utiliser du tout et fournir une belle annulation.
J'irais de la manière non linguale et utiliserais des files d'attente visuelles pour cela. Par exemple, imaginez une application Iphone que vous sélectionnez des éléments en essuyant votre doigt. avant de les supprimer à l'aide du bouton de suppression principal, il "secouera" les éléments sélectionnés et vous montrera un point d'interrogation intitulé boîte avec un bouton V (ok) ou X (annuler) ...
Ou, dans le monde 3D de Kinekt / Move / Wii - imaginez sélectionner les fichiers, déplacer votre main vers le bouton de suppression et être invité à déplacer votre main au-dessus de votre tête pour confirmer (en utilisant les mêmes symboles visuels que ceux mentionnés précédemment. de vous demander de supprimer 3 fichiers? il vous montrera 3 fichiers avec un X rouge à moitié transparent et vous dira de faire quelque chose pour confirmer.
la source