Muitas vezes, ao gerar mensagens para mostrar ao usuário, a mensagem conterá uma série de algo que desejo informar ao cliente.
Vou dar um exemplo: o cliente selecionou uma série de itens de 1 em diante e clicou em excluir. Agora, quero deixar uma mensagem de confirmação para o cliente e mencionar o número de itens que ele selecionou para minimizar a chance de ele cometer um erro ao selecionar um monte de itens e clicar em excluir quando ele só deseja excluir um dos eles.
Uma maneira é fazer a mensagem genérica assim:
int noofitemsselected = SomeFunction();
string message = "You have selected " + noofitemsselected + " item(s). Are you sure you want to delete it/them?";
O "problema" aqui é o caso em que noofitemselected
é 1, e temos que escrever item e ele em vez de itens e eles .
Minha solução normal será algo assim
int noofitemsselected = SomeFunction();
string message = "You have selected " + noofitemsselected + " " + (noofitemsselected==1?"item" : "items") + ". Are you sure you want to delete " + (noofitemsselected==1?"it" : "them") + "?";
Isso fica muito longo e muito desagradável muito rápido se houver muitas referências à pluralidade de números dentro do código, e a mensagem real ficar difícil de ler.
Portanto, minhas perguntas são simples. Existe alguma maneira melhor de gerar mensagens como esta?
EDITAR
Vejo que muitas pessoas ficaram muito presas no caso de eu ter mencionado que a mensagem deveria ser exibida dentro de uma caixa de mensagem e simplesmente deu uma resposta de como evitar o uso da caixa de mensagem, e isso é bom .
Mas lembre-se de que o problema de pluralização também se aplica a textos em outros lugares do programa além de caixas de mensagens. Por exemplo, um rótulo ao lado de uma grade exibindo o número de linhas selecionadas na grade terá o mesmo problema em relação à pluralização.
Portanto, isso se aplica basicamente à maioria do texto que é gerado de alguma forma a partir de programas, e então a solução não é tão simples quanto apenas mudar o programa para não produzir mais texto :)
fonte
Respostas:
Se houver alguma chance, por menor que seja, de que este aplicativo precise ser traduzido para outros idiomas, ambos estão errados. A maneira correta de fazer isso é:
Isso ocorre porque idiomas diferentes lidam com a pluralidade de maneiras diferentes. Alguns, como o malaio, nem mesmo têm plurais sintáticos, então as cordas geralmente são idênticas. Separar as duas strings torna mais fácil oferecer suporte a outros idiomas posteriormente.
Caso contrário, se este aplicativo se destina a ser consumido pelo público em geral e deve ser amigável, o segundo método é preferível. Desculpe, mas eu realmente não conheço uma maneira mais curta de fazer isso.
Se este aplicativo se destina a ser consumido apenas internamente pela sua empresa, faça o atalho
"item(s)"
. Você realmente não precisa impressionar ninguém ao escrever um código empreendedor. Mas eu desaconselho fazer isso para aplicativos de consumo público, porque isso dá a impressão de que o programador é preguiçoso e, portanto, rebaixa sua opinião sobre a qualidade do aplicativo. Confie em mim, pequenas coisas como esta importam.fonte
noofitemsselected
neste exemplo para a primeira opção; já que você sabe que é 1.Você pode evitar toda essa pluralidade confusa apenas excluindo os itens sem nenhuma mensagem e dando ao usuário um recurso de Desfazer muito bom. Os usuários nunca lêem nada . Você deve construir uma boa instalação de Desfazer como parte de seu programa de qualquer maneira.
Na verdade, você obtém 2 benefícios ao criar uma facilidade Undo abrangente. O primeiro benefício facilita a vida do usuário ao permitir que ele reverta erros e minimize a leitura. O segundo benefício é que seu aplicativo reflete a vida real, permitindo a reversão do fluxo de trabalho não trivial (não apenas erros).
Certa vez, escrevi um aplicativo sem usar uma única caixa de diálogo ou mensagem de confirmação. Demorou muito e foi significativamente mais difícil de implementar do que usar mensagens do tipo confirmação. Mas o resultado final foi bastante bom de usar de acordo com seus usuários finais.
fonte
Que tal apenas:
Dessa forma, você elimina as dificuldades de acordo de número e acaba com uma mensagem de erro ainda mais curta e mais direta para o usuário como um bônus. Todos nós sabemos que os usuários não leem mensagens de erro de qualquer maneira . Quanto mais curtos forem, maior será a probabilidade de, pelo menos, dar uma olhada no texto.
Ou, sabendo que os usuários não lêem mensagens de erro, você poderia abordar isso de uma maneira diferente. Ignore completamente a mensagem de confirmação e forneça apenas um recurso de desfazer que simplesmente funciona, independentemente do que foi excluído. A maioria dos usuários já está acostumada a desfazer uma operação quando percebe que ela não é o que desejam, e provavelmente achará esse comportamento mais natural do que ter que lidar com outro pop-up irritante.
fonte
E o que Java teve por anos: java.text.MessageFormat e ChoiceFormat? Consulte http://download.oracle.com/javase/1.4.2/docs/api/java/text/MessageFormat.html para obter mais informações.
No seu caso, você quer algo um pouco mais simples:
A vantagem dessa abordagem é que ela funciona bem com os pacotes i18n e você pode fornecer traduções adequadamente para idiomas (como o japonês) que não têm conceito de palavras no plural ou no singular.
fonte
Eu não iria codificar a mensagem, mas fornecer duas mensagens em um arquivo de recurso separado. Gostar
e, em seguida, alimentando-os em String.Format como
Acho que essa abordagem é mais fácil de localizar e manter. Todas as mensagens da IU estariam em um único local.
fonte
Você pode contornar o problema completamente formulando a mensagem de maneira diferente.
fonte
A primeira coisa que sugiro é: use
string.Format
. Isso permite que você faça algo assim:Além disso, em aplicativos WPF, eu vi sistemas em que uma string de recurso seria delimitada por barras verticais para ter duas mensagens: uma mensagem singular e uma mensagem plural (ou até mesmo uma mensagem zero / única / muitos). Um conversor personalizado pode ser usado para analisar esse recurso e usar a string relevante (formatada), de modo que seu Xaml seja algo assim:
fonte
Para inglês, muitas respostas acima. Para outras línguas, é mais difícil, pois os plurais dependem do gênero do substantivo e da terminação da palavra. Alguns exemplos em francês:
Masculino normal:
Feminino regular
Irregular masculino (termina com 's')
O mesmo problema existe na maioria das línguas latinas e se agrava no alemão ou no russo, onde há 3 gêneros (maculino, feminino e neutro).
Você precisa ter cuidado se seu objetivo é lidar com mais do que apenas inglês.
fonte
Para poder ter mensagens pluralizadas que serão possíveis de localizar corretamente, minha opinião é que seria sensato primeiro criar uma camada de indireção entre o número e uma mensagem.
Por exemplo, use uma constante de algum tipo para especificar qual mensagem você deseja exibir. Busque a mensagem usando alguma função que irá ocultar os detalhes de implementação.
Em seguida, crie um dicionário que contenha as mensagens e variações possíveis e faça com que as variações saibam quando devem ser usadas.
Agora você pode simplesmente encontrar a chave que corresponde a
quantity
e interpolar o valor dequantity
com essa mensagem.Este exemplo simplificado e ingênuo, mas eu realmente não vejo nenhuma outra maneira sã de fazer isso e ser capaz de fornecer um bom suporte para L10N e I18N.
fonte
Você terá que traduzir a função abaixo de VBA para C #, mas seu uso mudaria para:
Eu tenho uma função VBA que uso no MS Access para fazer exatamente o que você está falando. Eu sei que serei cortado em pedaços por postar no VBA, mas lá vai de qualquer maneira. O algoritmo deve ser aparente a partir dos comentários:
O uso foi cortado um pouco nos comentários de código acima, então vou repetir aqui:
Sim, esta solução ignora idiomas que não sejam o inglês. Se isso importa depende dos seus requisitos.
fonte
Você pode gerar o plural automaticamente, consulte, por exemplo. gerador plural .
Para regras de geração de plural, consulte a wikipedia
fonte
Que tal uma forma mais genérica. Evite a pluralização na segunda frase:
Descobri que fazer dessa forma coloca o número no final da linha, o que é realmente fácil de detectar. Essa solução funcionaria com a mesma lógica em qualquer idioma.
fonte
Number
(eu estava respondendo enquanto embalava meu bebê para dormir).Minha abordagem geral é escrever uma "função única / plural", como esta:
Então, no corpo da mensagem, chamo esta função:
Isso não é muito melhor, mas pelo menos, (a) coloca a decisão em uma função e, portanto, organiza um pouco o código, e (b) é flexível o suficiente para lidar com plurais irregulares. ou seja, é fácil dizer o substantivo (n, "filho", "filhos") e assim por diante.
É claro que isso só funciona para o inglês, mas o conceito é facilmente extensível para idiomas com terminações mais complexas.
Ocorreu-me que você poderia tornar o último parâmetro opcional para o caso fácil:
fonte
Internacionalização
Presumo que você queira suporte de internacionalização, caso em que diferentes idiomas têm padrões diferentes para plurais (por exemplo, uma forma especial de plural para 2 de alguma coisa, ou idiomas mais complicados como o polonês), e você não pode confiar na aplicação de algum padrão simples à sua string para fixar isso.
Você pode usar a
ngettext
função GNU Gettext e fornecer duas mensagens em inglês em seu código-fonte. Gettext fornecerá a infraestrutura para escolher entre outras (potencialmente mais) mensagens quando traduzidas para outros idiomas. Veja http://www.gnu.org/software/hello/manual/gettext/Plural-forms.html para uma descrição completa do suporte plural do GNU gettext.GNU Gettext está sob a LGPL.
ngettext
é nomeadoGettextResourceManager.GetPluralString
na porta C # de Gettext.(Se você não precisa de suporte de localização e não quer usar o Gettext imediatamente, escreva sua própria função que faz isso para o inglês e passe duas mensagens completas para ela; dessa forma, se precisar de l10n mais tarde, você pode adicione reescrevendo uma única função.)
fonte
Que tal escrever uma função como
.. e usá-lo sempre que precisar?
fonte
Para o primeiro problema, quero dizer Pluralize, você pode usar o Inflector .
E para o segundo, você pode usar uma extensão de representação de string com um nome como ToPronounString.
fonte
Eu tive exatamente a mesma pergunta feita a mim ontem por um membro de nossa equipe.
Desde que surgiu novamente aqui no StackOverflow, imaginei que o universo estava me dizendo para ter uma batalha na produção de uma solução decente.
Eu rapidamente montei algo e não é de forma perfeita, mas pode ser útil ou gerar alguma discussão / desenvolvimento.
Este código é baseado na ideia de que pode haver 3 mensagens. Um para zero itens, um para um item e um para mais de um item que seguem a seguinte estrutura:
singlePropertyName
singlePropertyName_Zero
singlePropertyName_Plural
Eu criei uma classe interna para testar a fim de imitar a classe de recursos. Eu não testei isso usando um arquivo de recurso real ainda, então ainda estou para ver o resultado completo.
Aqui está o código (atualmente, incluí alguns genéricos onde sei que poderia ter especificado o terceiro parâmetro simplesmente como um tipo e também o segundo parâmetro é uma string, acho que há uma maneira de combinar esses dois parâmetros em algo melhor, mas eu ' Voltarei a isso quando tiver um momento livre.
Classe de recurso de teste:
e meu método de execução rápida
fonte
singlePropertyName_All
torná-lo ainda mais óbvio.Do meu ponto de vista, sua primeira solução é a mais adequada. O que digo é que, no caso de você precisar que o aplicativo suporte vários idiomas, a segunda opção pode ser trabalhosa. Com a primeira abordagem, é fácil localizar o texto sem muito esforço.
fonte
Você poderia ir para uma mensagem mais genérica como 'Tem certeza de que deseja excluir o (s) item (ns) selecionado (s)'.
fonte
Depende de quão boa é a mensagem que você deseja ter. Do mais fácil ao mais difícil:
Reescreva sua mensagem de erro para evitar pluralização. Não é tão bom para o seu usuário, mas mais rápido.
Use uma linguagem mais geral, mas ainda inclua o (s) número (s).
Use um sistema de "pluralização" e infletor ala Rails, para que você possa dizer
pluralize(5,'bunch')
e obter5 bunches
. Rails tem um bom padrão para isso.Para internacionalização, você precisa olhar o que Java oferece. Isso suportará uma grande variedade de idiomas, incluindo aqueles que têm diferentes formas de adjetivos com 2 ou 3 itens. A solução "s" é muito centrada em inglês.
A opção escolhida depende de seus objetivos de produto. - ndp
fonte
Por que você deseja apresentar uma mensagem que os usuários possam realmente entender? Vai contra 40 anos de história de programação. Nããão, temos uma coisa boa acontecendo, não a estrague com mensagens compreensíveis .
(j / k)
fonte
Faça como no World of Warcraft:
fonte
Ele fica um pouco mais curto com
fonte
Uma abordagem que não vi mencionada seria o uso de uma substituição / tag de seleção (por exemplo, algo como "Você está prestes a esmagar {0} [? I ({0} = 1): / cactus / cacti /]". (em outras palavras, tenha uma expressão semelhante a um formato que especifique a substituição com base em se o argumento zero, considerado como um inteiro, é igual a 1). Eu vi essas tags usadas antes de .net; não estou ciente de nenhuma padrão para eles em .net, nem sei a melhor maneira de formatá-los.
fonte
Eu pensaria fora da caixa por um minuto, todas as sugestões aqui são: fazer a pluralização (e se preocupar com mais de 1 nível de pluralização, gênero, etc.) ou não usá-la de forma alguma e fornecer um bom desfazer.
Eu seguiria o caminho não lingual e usaria filas visuais para isso. por exemplo, imagine um aplicativo para iPhone em que você seleciona itens limpando o dedo. antes de excluí-los usando o botão mestre de exclusão, ele "sacudirá" os itens selecionados e mostrará uma caixa de ponto de interrogação intitulada com botões V (ok) ou X (cancelar) ...
Ou, no mundo 3D de Kinekt / Move / Wii - imagine selecionar os arquivos, mover sua mão para o botão delete e ser instruído a mover sua mão acima da cabeça para confirmar (usando os mesmos símbolos visuais que mencionei antes. Por exemplo, de pedir para você deletar 3 arquivos? ele irá mostrar a você 3 arquivos com um X vermelho meio transparente pairando sobre e dizer para você fazer algo para confirmar.
fonte