Pluralidad en los mensajes de usuario


Muchas veces, al generar mensajes para mostrar al usuario, el mensaje contendrá un número de algo del que quiero informar al cliente.

Voy a dar un ejemplo: El cliente ha seleccionado un número de elementos de 1 en adelante, y ha hecho clic en eliminar. Ahora quiero dar un mensaje de confirmación al cliente, y quiero mencionar el número de artículos que ha seleccionado para minimizar la posibilidad de que cometa un error seleccionando un montón de artículos y haciendo clic en eliminar cuando solo quiere borrar uno de ellos.

Una forma es hacer el mensaje genérico como este:

int noofitemsselected = SomeFunction();
string message = "You have selected " + noofitemsselected + " item(s). Are you sure you want to delete it/them?";

El "problema" aquí es el caso donde noofitemselected es 1, y tenemos que escribir item y it en lugar de items y them.

Mi solución normal será algo como esto

int noofitemsselected = SomeFunction();
string message = "You have selected " + noofitemsselected + " " + (noofitemsselected==1?"item" : "items") + ". Are you sure you want to delete " + (noofitemsselected==1?"it" : "them") + "?";

Esto se vuelve bastante largo y bastante desagradable realmente rápido si hay muchas referencias a la pluralidad de números dentro del código, y el mensaje real se vuelve difícil Leer.

Así que mis preguntas son simples. ¿Hay alguna forma mejor de generar mensajes como este?

EDITAR

Veo que muchas personas se han colgado mucho en el caso de que mencioné que el mensaje debe mostrarse dentro de un cuadro de mensaje, y simplemente ha dado una respuesta de cómo evitar el uso del cuadro de mensaje en absoluto, y eso es todo bueno.

Pero recuerde que el problema de la pluralización también se aplica a los textos de otros lugares en el programa, además de cajas de mensajes. Por ejemplo, una etiqueta junto a una cuadrícula que muestra el número de líneas seleccionadas en la cuadrícula tendrá el mismo problema con respecto a la pluralización.

Así que esto básicamente se aplica a la mayoría del texto que se genera de alguna manera de los programas, y entonces la solución no es tan simple como simplemente cambiar el programa para que ya no genere texto:)

Author: Øyvind Bråthen, 2010-11-23

25 answers

Si alguna vez hay alguna posibilidad, no importa lo pequeña que sea, de que esta aplicación necesite ser traducida a otros idiomas, entonces ambos están equivocados. La forma correcta de hacer esto es:

string message = ( noofitemsselected==1 ?
  "You have selected " + noofitemsselected + " item. Are you sure you want to delete it?":
  "You have selected " + noofitemsselected + " items. Are you sure you want to delete them?"
);

Esto se debe a que los diferentes lenguajes manejan la pluralidad de manera diferente. Algunos como malayos ni siquiera tienen plurales sintácticos por lo que las cadenas generalmente serían idénticas. Separar las dos cadenas hace que sea más fácil soportar otros idiomas más adelante.

De lo contrario, si esta aplicación está destinada a ser consumido por el público en general y se supone que es fácil de usar, entonces el segundo método es preferible. Lo siento, pero no conozco una forma más corta de hacer esto.

Si esta aplicación está destinada a ser consumida solo internamente por su empresa, entonces haga el atajo "item(s)" cosa. Realmente no tienes que impresionar a nadie cuando escribes código de empresa. Pero yo aconsejaría no hacer esto para la aplicación de consumo público porque esto da la impresión de que el programador es perezoso y por lo tanto bajar su opinión de la calidad de la app. Confía en mí, pequeñas cosas como esta importan.

 53
Author: slebetman,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2010-11-23 08:57:00

Puede evitar toda esta pluralidad desordenada simplemente eliminando los elementos sin ningún mensaje y dando al usuario una muy buena facilidad de deshacer. Los usuarios nunca leen nada. Usted debe construir una buena facilidad de Deshacer como parte de su programa de todos modos.

En realidad obtienes 2 beneficios cuando creas un servicio integral de Deshacer. El primer beneficio hace que la vida del usuario sea más fácil al permitirle revertir los errores y minimizar la lectura. El segundo beneficio es que su aplicación es reflejando la vida real permitiendo la reversión del flujo de trabajo no trivial (no solo errores).

Una vez escribí una aplicación sin usar un solo diálogo o mensaje de confirmación. Tomó un poco de pensamiento serio y fue significativamente más difícil de implementar que el uso de mensajes de tipo de confirmación. Pero el resultado final fue bastante agradable de usar de acuerdo con sus usuarios finales.

 94
Author: RoadWarrior,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2010-11-26 11:41:25

¿Qué tal simplemente:

string message = "Are you sure you want to delete " + noofitemsselected + " item(s)?"

De esa manera, se eliminan las dificultades de acuerdo de números, y se termina con un mensaje de error aún más corto y más preciso para el usuario como un bono. Todos sabemos que los usuarios no leen los mensajes de error de todos modos. Cuanto más cortos son, más probable es que al menos miren el texto.

O, armado con este conocimiento de que los usuarios no leen mensajes de error, podría abordar esto de una manera diferente. Omitir el mensaje de confirmación en conjunto, y solo proporciona una función de deshacer que Simplemente Funciona, independientemente de lo que se eliminó. La mayoría de los usuarios ya están acostumbrados a deshacer una operación cuando notan que no era lo que querían, y es probable que encuentren este comportamiento más natural que tener que lidiar con otra ventana emergente molesta.

 39
Author: Cody Gray,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2010-11-23 08:49:11

Qué pasa con lo que Java ha tenido durante años: java.texto.MessageFormat y ChoiceFormat? Véase http://download.oracle.com/javase/1.4.2/docs/api/java/text/MessageFormat.html para más información.

MessageFormat form = new MessageFormat("The disk \"{1}\" contains {0}.");
form.applyPattern(
   "There {0,choice,0#are no files|1#is one file|1<are {0,number,integer} files}.");

Object[] testArgs = {new Long(12373), "MyDisk"};

System.out.println(form.format(testArgs));

// output, with different testArgs
output: The disk "MyDisk" are no files.
output: The disk "MyDisk" is one file.
output: The disk "MyDisk" are 1,273 files.

En tu caso quieres algo algo más simple:

MessageFormat form = new MessageFormat("Are you sure you want to delete {0,choice,1#one item,1<{0,number.integer} files}?");

La ventaja de este enfoque es que funciona bien con los paquetes i18n, y puede proporcionar traducciones adecuadas para idiomas (como el japonés) que no tienen el concepto de palabras plurales o singulares.

 20
Author: Berin Loritsch,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2010-11-23 13:53:46

Yo iría con no hardcoding el mensaje, pero proporcionar dos mensajes en un archivo de recursos separado. Como

string DELETE_SINGLE = "You have selected {0} item. Are you sure you want to delete it?";
string DELETE_MULTI = "You have selected {0} items. Are you sure you want to delete them?";

Y luego alimentarlos en Cadena.Formato como

if(noofitemsselected == 1)
    messageTemplate = MessageResources.DELETE_SINGLE;
else
    messageTemplate = MessageResources.DELETE_MULTI;

string message = String.Format(messageTemplate, noofitemsselected)

Creo que este enfoque es más fácil de localizar y mantener. Todos los mensajes de la interfaz de usuario estarían en una sola ubicación.

 12
Author: Jens,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2010-11-23 09:00:05

Puede esquivar el problema por completo redactando el mensaje de manera diferente.

string message = "The number of selected items is " + noofitemsselected + ". Are you sure you want to delete everything in this selection?";
 11
Author: gdejohn,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2010-11-23 09:37:16

Lo primero que sugeriría es: use string.Format. Eso le permite hacer algo como esto:

int numOfItems = GetNumOfItems();
string msgTemplate;
msgTemplate = numOfItems == 1 ? "You selected only {0} item." : "Wow, you selected {0} items!";
string msg = string.Format(msgTemplate, numOfItems);

Además, en las aplicaciones WPF, he visto sistemas donde una cadena de recursos estaría delimitada por tuberías para tener dos mensajes: un mensaje singular y un mensaje plural (o un mensaje cero/simple/muchos, incluso). Un convertidor personalizado podría usarse para analizar este recurso y usar la cadena relevante (formateada), por lo que su Xaml es algo como esto:

<TextBlock Text="{Binding numOfItems, Converter={StaticResource c:NumericMessageFormatter}, ConverterParameter={StaticResource s:SuitableMessageTemplate}}" />
 10
Author: Dan Puzey,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2010-11-23 08:53:06

Para el inglés, muchas respuestas arriba. Para otros idiomas es más difícil, ya que los plurales dependen del género del sustantivo y la terminación de la palabra. Algunos ejemplos en francés:

Regular masculino:

Vous avez choisi 1 compte. Voulez-vous vraiment le supprimer.
Vous avez choisi 2 comptes. Voulez-vous vraiment les supprimer.

Femenino regular

Vous avez choisi 1 table. Voulez-vous vraiment la supprimer.
Vous avez choisi 2 tables. Voulez-vous vraiment les supprimer.

Masculino irregular (termina con 's')

Vous avez choisi 1 pays. Voulez-vous vraiment le supprimer.
Vous avez choisi 2 pays. Voulez-vous vraiment les supprimer?

El mismo problema existe en la mayoría de las lenguas latinas y empeora en alemán o ruso, donde hay 3 géneros (maculina, femenino y neutro).

Tendrás que tener cuidado si tu objetivo es manejar algo más que el inglés.

 7
Author: smirkingman,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2010-11-24 19:57:49

Para poder tener mensajes pluralizados que serán posibles de localizar correctamente, mi opinión es que sería prudente crear primero una capa de indirección entre el número y un mensaje.

Por ejemplo, use una constante de algún tipo para especificar qué mensaje desea mostrar. Obtenga el mensaje usando alguna función que ocultará los detalles de la implementación.

get_message(DELETE_WARNING, quantity)

A continuación, cree un diccionario que contenga los posibles mensajes y variaciones, y haga que las variaciones se conozcan cuándo deben usarse.

DELETE_WARNING = {
   1: 'Are you sure you want to delete %s item',
   >1: 'Are you sure you want to delete %s items'
   >5: 'My language has special plural above five, do you wish to delete it?'
}

Ahora puedes simplemente encontrar la clave que corresponde a quantity e interpolar el valor de quantity con ese mensaje.

Este ejemplo simplificado e ingenuo, pero realmente no veo ninguna otra forma sensata de hacer esto y ser capaz de proporcionar un buen soporte para L10N e I18N.

 5
Author: Davor Lucic,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2010-11-23 16:30:50

Tendrá que traducir la función a continuación de VBA a C#, pero su uso cambiaría a:

int noofitemsselected = SomeFunction();
string message = Pluralize("You have selected # item[s]. Are you sure you want to delete [it/them]?", noofitemsselected);

Tengo una función de VBA que uso en MS Access para hacer exactamente lo que está hablando. Sé que me cortarán en pedazos por publicar VBA, pero aquí va de todos modos. El algoritmo debe ser evidente a partir de los comentarios:

'---------------------------------------------------------------------------------------'
' Procedure : Pluralize'
' Purpose   : Formats an English phrase to make verbs agree in number.'
' Usage     : Msg = "There [is/are] # record[s].  [It/They] consist[s/] of # part[y/ies] each."'
'             Pluralize(Msg, 1) --> "There is 1 record.  It consists of 1 party each."'
'             Pluralize(Msg, 6) --> "There are 6 records.  They consist of 6 parties each."'
'---------------------------------------------------------------------------------------'
''
Function Pluralize(Text As String, Num As Variant, Optional NumToken As String = "#")
Const OpeningBracket = "\["
Const ClosingBracket = "\]"
Const DividingSlash = "/"
Const CharGroup = "([^\]]*)"  'Group of 0 or more characters not equal to closing bracket'
Dim IsPlural As Boolean, Msg As String, Pattern As String

    On Error GoTo Err_Pluralize

    If IsNumeric(Num) Then
        IsPlural = (Num <> 1)
    End If

    Msg = Text

    'Replace the number token with the actual number'
    Msg = Replace(Msg, NumToken, Num)

    'Replace [y/ies] style references'
    Pattern = OpeningBracket & CharGroup & DividingSlash & CharGroup & ClosingBracket
    Msg = RegExReplace(Pattern, Msg, "$" & IIf(IsPlural, 2, 1))

    'Replace [s] style references'
    Pattern = OpeningBracket & CharGroup & ClosingBracket
    Msg = RegExReplace(Pattern, Msg, IIf(IsPlural, "$1", ""))

    'Return the modified message'    
    Pluralize = Msg
End Function

Function RegExReplace(SearchPattern As String, _
                      TextToSearch As String, _
                      ReplacePattern As String) As String
Dim RE As Object

    Set RE = CreateObject("vbscript.regexp")
    With RE
        .MultiLine = False
        .Global = True
        .IgnoreCase = False
        .Pattern = SearchPattern
    End With

    RegExReplace = RE.Replace(TextToSearch, ReplacePattern)
End Function

El uso se cortó un poco en los comentarios de código anteriores, así que lo repetiré aquí:

Msg = "There [is/are] # record[s]. [It/They] consist[s/] of # part[y/ies] each."

Pluralize(Msg, 1) --> "There is 1 record.  It consists of 1 party each."
Pluralize(Msg, 6) --> "There are 6 records.  They consist of 6 parties each."

Sí, esta solución ignora lenguajes que no son Ingl. Si eso importa depende de sus requisitos.

 5
Author: mwolfe02,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2010-11-23 22:05:09

Usted podría generar el plural automáticamente, véase eg. generador plural.

Para reglas de generación de plural ver wikipedia

string msg = "Do you want to delete " + numItems + GetPlural(" item", numItems) + "?";
 4
Author: thumbmunkeys,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2010-11-23 08:44:21

¿Qué tal una forma más genérica. Evitar la pluralización en la segunda oración:

Number of selected items to be deleted: noofitemsselected.
Are you sure?

Me entero de que hacerlo de esta manera pone el número al final de la línea que es muy fácil de detectar. Esta solución funcionaría con la misma lógica en cualquier idioma.

 4
Author: Danosaure,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2010-11-23 16:02:39

Mi enfoque general es escribir una "función simple / plural", así:

public static string noun(int n, string single, string plural)
{
  if (n==1)
    return single;
  else
    return plural;
}

Luego en el cuerpo del mensaje llamo a esta función:

string message="Congratulations! You have won "+n+" "+noun(n, "foobar", "foobars")+"!";

Esto no es mucho mejor, pero al menos, (a) pone la decisión en una función y así ordena un poco el código, y (b) es lo suficientemente flexible como para manejar plurales irregulares. es decir, es bastante fácil decir sustantivo (n, "niño", "niños") y similares.

Por supuesto, esto solo funciona para el inglés, pero el concepto es fácilmente extensible a lenguajes con terminaciones más complejas.

Se me ocurre que podría hacer que el último parámetro opcional para el caso fácil:

public static string noun(int n, string single, string plural=null)
{
  if (n==1)
    return single;
  else if (plural==null)
    return single+"s";
  else
    return plural;
}
 4
Author: Jay,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2010-11-23 22:22:23

Internacionalización

Asumo que desea soporte de internacionalización, en cuyo caso diferentes idiomas tienen diferentes patrones para plurales (por ejemplo, una forma plural especial para 2 de algo, o idiomas más complicados como el polaco), y no puede confiar en aplicar algún patrón simple a su cadena para arreglarlo.

Puede usar la función ngettext de GNU Gettext y proporcionar dos mensajes en inglés en su código fuente. Gettext proporcionará la infraestructura para elegir entre otros (potencialmente más) mensajes cuando se traducen a otros idiomas. Véase http://www.gnu.org/software/hello/manual/gettext/Plural-forms.html para una descripción completa del soporte plural de GNU gettext.

GNU Gettext está bajo la LGPL. ngettext se llama GettextResourceManager.GetPluralString en el puerto C# de Gettext.

(Si no necesita soporte de localización y no desea usar Gettext de inmediato, escriba su propia función que haga esto para inglés y pase dos mensajes completos a él, de esa manera si necesita l10n más tarde, puede agregar reescribiendo una sola función.)

 4
Author: Ken Bloom,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2010-11-24 15:00:11

¿Qué tal escribir una función como

string GetOutputMessage(int count, string oneItemMsg, string multiItemMsg)
{
 return string.Format("{0} {1}", count, count > 1 ? multiItemMsg : oneItemMsg);
}

.. y usarlo siempre que lo necesite?

string message = "You have selected " + GetOutputMessage(noofitemsselected,"item","items") + ". Are you sure you want to delete it/them?";
 3
Author: Pavel Morshenyuk,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2010-11-23 08:47:39

Para el primer problema , quiero decir Pluralizar, puedes usar Inflector.

Y para el segundo, puede usar una extensión de representación de cadena con un nombre como ToPronounString.

 3
Author: Yogesh,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2010-11-23 08:48:12

Ayer me hizo esta misma pregunta un miembro de nuestro equipo.

Desde que surgió de nuevo aquí en StackOverflow pensé que el universo me estaba diciendo que tuviera una fiesta en la producción de una solución decente.

Rápidamente he juntado algo y de ninguna manera es perfecto, sin embargo, podría ser útil o provocar alguna discusión/desarrollo.

Este código se basa en la idea de que puede haber 3 mensajes. Uno para cero artículos, uno para un artículo y uno para más de un elemento que sigue la siguiente estructura:

SinglePropertyName
singlePropertyName_Zero
singlePropertyName_Plural

He creado una clase interna para probar con el fin de imitar la clase de recurso. Todavía no he probado esto usando un archivo de recursos real, así que aún no he visto el resultado completo.

Aquí está el código (actualmente he incluido algunos genéricos donde sé que podría haber especificado el tercer parámetro simplemente como un Tipo y también el segundo parámetro es una cadena, Creo que hay una manera de combinar estos dos parámetros en algo mejor, pero volveré a eso cuando tenga un momento libre.

    public static string GetMessage<T>(int count, string resourceSingularName, T resourceType) where T : Type
{
    var resourcePluralName = resourceSingularName + "_Plural";
    var resourceZeroName = resourceSingularName + "_Zero";
    string resource = string.Empty;
    if(count == 0)
    {
        resource = resourceZeroName;
    }
    else{
        resource = (count <= 1)? resourceSingularName : resourcePluralName;
    }
    var x = resourceType.GetProperty(resource).GetValue(Activator.CreateInstance(resourceType),null);

    return x.ToString();
}

Clase de recurso de prueba:

internal class TestMessenger
{
    public string Tester{get{
    return "Hello World of one";}}
    public string Tester_Zero{get{
    return "Hello no world";}}
    public string Tester_Plural{get{
    return "Hello Worlds";}}
}

Y mi método de ejecución rápida

void Main()
{
    var message = GetMessage(56, "Tester",typeof(TestMessenger));
    message.Dump();
}
 3
Author: Jamie Dixon,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2010-11-23 16:25:25

Desde mi punto de vista, tu primera solución es la más adecuada. Por eso digo que es, en caso de que necesite la aplicación para soportar varios idiomas, la segunda opción puede ser minuciosa. Con el primer enfoque es fácil localizar el texto sin mucho esfuerzo.

 2
Author: Illuminati,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2010-11-23 08:40:58

Usted podría ir para un mensaje más genérico como '¿Está seguro de que desea eliminar el elemento seleccionado(s)'.

 2
Author: Peter,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2010-11-23 08:41:51

Depende de lo bonito que sea el mensaje que quieras tener. De más fácil a más difícil:

  1. Vuelva a escribir el mensaje de error para evitar la pluralización. No tan agradable para su usuario, pero más rápido.

  2. Use un lenguaje más general pero aún incluya los números.

  3. Utilice un sistema de "pluralización" y de inflector ala Rails, para que pueda decir pluralize(5,'bunch') y obtener 5 bunches. Rails tiene un buen patrón para esto.

  4. Para la internacionalización, es necesario mirar lo que Java proporcionar. Eso soportará una amplia variedad de idiomas, incluyendo aquellos que tienen diferentes formas de adjetivos con 2 o 3 elementos. La solución " s " está muy centrada en el inglés.

La opción que elija depende de los objetivos de su producto. - ndp

 2
Author: ndp,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2010-11-23 15:44:30

¿Por qué querría presentar un mensaje que los usuarios realmente puedan entender? Va en contra de 40 años de historia de programación. Nooooo, tenemos algo bueno pasando, no lo estropees con mensajes comprensibles .


(j/k)

 2
Author: ja72,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2010-11-24 05:26:43

Hazlo como se hace en World of Warcraft:

BILLING_NAG_WARNING = "Your play time expires in %d |4minute:minutes;";
 2
Author: Andreas Bonini,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2010-11-24 08:24:01

Se hace un poco más corto con

string message = "Are you sure you want to delete " + noofitemsselected + " item" + (noofitemsselected>1 ? "s" : "") + "?";
 0
Author: Jonas Elfström,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2010-11-23 08:43:30

Un enfoque que no he visto mencionado sería el uso de una etiqueta de sustitución / selección (por ejemplo, algo como " Estás a punto de aplastar {0} [?i ({0} = 1): / cactus / cacti/]". (en otras palabras, tenga una expresión similar al formato que especifique la sustitución en función de si el argumento cero, tomado como un entero, es igual a 1). He visto tales etiquetas usadas en los días anteriores a. net; no conozco ningún estándar para ellas en. net, ni sé la mejor manera de formatearlas.

 0
Author: supercat,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2010-11-23 18:22:44

Pensaría fuera de la caja por un minuto, todas las sugerencias aquí son hacer la pluralización (y preocuparse por más de 1 nivel de pluralización, género, etc.) o no usarlo en absoluto y proporcionar un buen deshacer.

Me gustaría ir de la manera no lingual y utilizar colas visuales para eso. por ejemplo, imagine una aplicación para Iphone que seleccione elementos limpiándose el dedo. antes de eliminarlos usando el botón master delete, "sacudirá" los elementos seleccionados y le mostrará un signo de interrogación titulado cuadro con un Botones V (ok) o X (cancelar)...

O, en el mundo 3D de Kinekt / Move / Wii - imagine seleccionar los archivos, moviendo su mano al botón eliminar y se le dirá que mueva su mano sobre su cabeza para confirmar (usando los mismos símbolos visuales que mencioné antes. por ejemplo,en lugar de pedirle que elimine 3 archivos? le mostrará 3 archivos con una X roja medio transparente y le dirá que haga algo para confirmar.

 0
Author: Eran Medan,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2010-12-19 06:10:57