Arredondamento de porcentagens de pesquisa é impreciso

Continuação da discussão Arredondamento de porcentagens em enquetes é impreciso:

Decidi criar um novo tópico, pois o problema mais recente não se trata de regras de arredondamento questionáveis, mas sim de regras completamente falsas. Portanto, o tópico deve estar na categoria Contribute > Bug. Não é um problema grave, mas é um pouco estranho de qualquer maneira.

Tivemos uma enquete pública onde 106 votos foram emitidos. Havia 69 votos para “não” e 37 para “sim”. Uma divisão simples mostra que 69/106 é cerca de 65,09 %. No entanto, o sistema informa que 66 % votaram para “não” e 34 % para “sim”. Aqui está uma imagem:

O resultado final foi de 72 votos para “não” e 38 para “sim”, e a enquete agora está encerrada. 72/110 é cerca de 65,45 %, que o sistema também arredonda para 66 %, então você pode ver o bug em ação em Tappara.co.

Tentei examinar o código para encontrar a causa do bug, mas não consegui. Descobri que uma função chamada evenRound é chamada, mas quando procurei sua origem, não a encontrei. Isso é apenas um palpite, mas talvez essa função arredonde o número para o inteiro par mais próximo?

Not sure I understand what’s broken here. The poll will round the % so they add up to 100%.

1 curtida

O resultado é terrível, é isso que está errado. :slight_smile:

Obrigado pelo código. Eu simplesmente não consegui encontrá-lo, o que mostra o quão ruim eu sou em usar o GitHub. O código foi retirado do Stack Overflow, onde seu autor escreve:

Não tenho certeza de qual nível de precisão você precisa, mas o que eu faria seria simplesmente somar 1 aos primeiros n números, sendo n o teto da soma total dos decimais. Neste caso, isso seria 3, então eu adicionaria 1 aos primeiros 3 itens e arredondaria para baixo o resto. Claro, isso não é super preciso, alguns números podem ser arredondados para cima ou para baixo quando não deveriam, mas funciona bem e sempre resultará em 100%.

Não é surpresa que, com um método tão rígido, você obtenha resultados estranhos. Sugeriria que fôssemos um pouco mais elaborados. Este post no mesmo tópico tem 72 votos positivos, enquanto o post de onde o código foi retirado tem apenas 1.

Existem muitas maneiras de fazer exatamente isso, desde que você não se preocupe com a dependência dos dados decimais originais.

O primeiro e talvez o método mais popular seria o Método da Maior Restante (Largest Remainder Method)

Que é basicamente:

  1. Arredondar tudo para baixo
  1. Calcular a diferença entre a soma e 100
  1. Distribuir essa diferença adicionando 1 aos itens em ordem decrescente de suas partes decimais

Acho que esse método seria a melhor escolha. Ainda é muito simples e dá resultados muito melhores. O código atual precisa de mais algumas linhas para dizer à função quais números devem ser arredondados para cima. Há mais um problema a ser considerado, no entanto. De este post no mesmo tópico:

A resposta muito votada de Varun Vohra minimiza a soma dos erros absolutos, e é muito simples de implementar. No entanto, existem casos extremos que ela não trata — qual deveria ser o resultado do arredondamento de 24,25, 23,25, 27,25, 25,25? Um desses números precisa ser arredondado para cima em vez de para baixo.

O post sugere vários métodos para escolher qual será arredondado para cima e qual para baixo, mas você nunca pode evitar completamente escolhas arbitrárias. Se você quiser buscar a perfeição, pode ler mais esse post, mas ficaria satisfeito com isso também nesses casos especiais raros.

Você provavelmente escolheria arbitrariamente o primeiro ou o último da lista.

Espero que isso ajude. Minhas habilidades provavelmente seriam suficientes para fazer as melhorias eu mesmo se estudasse alguma sintaxe básica primeiro. Não vou fazer isso agora, mas talvez em algum momento, se ninguém olhar para isso antes.

Edição. Melhorei o título um pouco, mudando a palavra “quebrado” para “impreciso”. Este tópico também deve ser movido para Contribute > Feature ou mesclado com o tópico anterior.

4 curtidas

Feel free to submit a pull request to change the rounding algorithm :wink:

5 curtidas

It was like classic exercises for beginning programmers. Here is a way to do it, but someone who has more experience and isn’t totally new to JavaScript might find some shortcuts.

https://github.com/rizka10/discourse/pull/1/files

2 curtidas

Looks fine to me. Would you mind making it a PR so that I can merge it?

I thought that was a pull request already… I’m as confused as always with Github. :confused:
I clicked some more green buttons now, maybe it does the trick?

If you want to create a PR from your code, you should go there: https://github.com/discourse/discourse/compare/master...rizka10:master :wink:

1 curtida

I think I’m getting it now. I ran into some Github tutorials online yesterday and I should really go through one to learn the basics.

1 curtida

Awesome. Before we can merge the code, we’ll need you to sign the CLA. I promise, this is the last step (also, you only have to sign it once ;))

6 curtidas

Thanks for all the help! I signed it now.

4 curtidas