Implementações alternativas de funções/abordagens padrão - página 8

 
fxsaber:

Um exemplo do meu estilo?

Por exemplo, isto:

return((int)((Value > 0) ? Value / Points[digits] + HALF_PLUS : Value / Points[digits] - HALF_PLUS) * Points[digits]);

Imagine que você tem 100 funções e cada uma delas devolve um registro desse tipo. Você está procurando por um erro entre estas entradas. Quanto tempo você levará para pesquisar?

 
Реter Konow:

Por exemplo, isto:

Imagine que você tem 100 funções e cada uma delas devolve este recorde. Você está procurando por um erro entre estas entradas. Quanto tempo você levará para pesquisar?

Eu não procuraria por mais de alguns minutos, especialmente porque um registro neste estilo permite exibir mais de algumas dezenas de funções em "uma tela", o que facilita o trabalho com o código

 
Реter Konow:

Por exemplo, isto:

Imagine que você tem 100 funções e cada uma delas devolve este recorde. Você está procurando por um erro entre estas entradas. Quanto tempo demorará para encontrá-lo?

Confie em mim quando escrevo textos como esse - não é por causa do estilo ou do princípio da brevidade, mas porque é realmente muito mais fácil para mim.

Você citou a maneira mais simples. Honestamente, não entendo o que pode ser um pouco confuso sobre isso.

Devo confessar que não consigo ler o código C++ porque não o conheço de forma alguma. Mas as pessoas escrevem nele. Portanto, é apenas uma questão de ignorância.

 
fxsaber:

Acredite em mim, quando escrevo desta maneira, não é por estilo ou brevidade, mas porque é realmente mais fácil para mim.

Você citou o mais simples dos termos. Honestamente, não entendo o que pode ser um pouco confuso sobre isso.

Devo confessar que não consigo ler o código C++ porque não o conheço de forma alguma. Mas as pessoas escrevem nele. Portanto, é apenas uma questão de ignorância.

Talvez tenhamos idéias diferentes de simplicidade de código.

Eu entendo que você é um grande profissional em programação. Mas quando você busca a maior produtividade em tudo, você não deve esquecer aprodutividade do trabalho. Ele começa com a legibilidade do código. Não está claro para mim por que o desejo de comprimir o código às custas da legibilidade do código é justificado, mas é bastante inaceitável em grandes projetos (independentes).


Francamente falando, eu odeio C++ porque é muito ilegível. Para empilhamento de entidades cuja existência poderia ser facilmente evitada. E só vai melhorar. Espaçoso.

SZU. Acredito que no desenvolvimento o código deve ser comprimido não às custas da legibilidade, mas às custas de melhores soluções, deixando-o o mais legível possível. A velocidade de compreensão do código tem um enorme impacto em sua própria produtividade.

ZSY. O fio é ótimo. Obrigado.

Productivity - США - MetaTrader 5
Productivity - США - MetaTrader 5
  • www.metatrader5.com
Индекс производительности труда показывает изменение объема выпущенной продукции, приходящегося на одного работника. Этот показатель полезен для предсказания инфляции и прироста объема производства. Если стоимость труда увеличивается соответственно увеличению производительности, и, кроме того, маловероятно увеличение производственных издержек...
 
Renat Fatkhullin:
Pense no que você terá fora de um número inteiro.

Portanto, a verificação para LONG_MAX - deve ser antes de converter o dobro para longo. Claramente, a função de arredondamento não é projetada para valores que não cabem em um número inteiro. E isso não muda o problema.

Se a função retorna o dobro que depois convertemos em longo, enfrentamos o mesmo perigo de transbordamento.

Pessoalmente, pouco antes do arredondamento - sempre fiz a verificação de valores-limite, mais a lógica do programa - sempre procuro garantir que a conversão nunca possa obter mais do que o valor máximo para um número inteiro.

 
Vitaly Muzichenko:

Eu não procuraria por mais de alguns minutos, especialmente porque escrever neste estilo permite exibir mais de algumas dezenas de funções em 'uma tela', facilitando o trabalho com o código

Algo que eu duvido sobre isso.

Aqui está o código real da minha função, que retorna o tipo de execução (o código foi sugerido pelo fxsaber, e eu lhe sou muito grato):

// Для МТ4 - возвращает otfFilingType. // Для МТ5 - возвращает тип исполнения ордера, равный otfFilingType, если он доступен на символе strSymbol, иначе - корректный вариант. ENUM_ORDER_TYPE_FILLING CSymbolInfo::GetTypeFilling(string strSymbol,ENUM_ORDER_TYPE_FILLING otfFilingType = ORDER_FILLING_FOK) {    #ifndef __MQL5__       return(otfFilingType);    #else // __MQL5__          // Функцию предложил fxsaber. Серьезной проверки не было - полагаемся на его авторитет.          const ENUM_SYMBOL_TRADE_EXECUTION steExeMode = (ENUM_SYMBOL_TRADE_EXECUTION)::SymbolInfoInteger(strSymbol, SYMBOL_TRADE_EXEMODE);    const int iFillingMode = (int)::SymbolInfoInteger(strSymbol, SYMBOL_FILLING_MODE);

   return((iFillingMode == 0 || (otfFilingType >= ORDER_FILLING_RETURN) || ((iFillingMode & (otfFilingType + 1)) != otfFilingType + 1)) ?          (((steExeMode == SYMBOL_TRADE_EXECUTION_EXCHANGE) || (steExeMode == SYMBOL_TRADE_EXECUTION_INSTANT)) ?            ORDER_FILLING_RETURN : ((iFillingMode == SYMBOL_FILLING_IOC) ? ORDER_FILLING_IOC : ORDER_FILLING_FOK)) :           otfFilingType);      #endif // __MQL5__ };

A função funciona muito bem. Verifiquei-o muitas vezes e não ocorreram erros. Mas eu ainda não entendo como o resultado é formado neste retorno horrível, apesar de minha própria experiência bastante boa. Além disso, fxsaber respondeu à pergunta que ele mesmo não se lembra disso.

Vitaly, diga-me como este código funciona, se não for muito difícil para você e você "entender em alguns minutos" neste estilo!

Eu "abriria parênteses" no operador de retorno, substituiria todas as "perguntas" por "se" e retornaria valores encontrados através do "ou" lógico. Pessoalmente, estou aborrecido com a "pergunta" do operador. Ele produz exatamente o mesmo código que um "se" semelhante, mas sua legibilidade é muito pior.

 
Georgiy Merts:

Tenho minhas dúvidas a esse respeito.

Aqui está o código real da minha função, que retorna o tipo de execução (o código foi sugerido pelo fxsaber, pelo qual lhe sou muito grato):

A função funciona muito bem. Verifiquei-o muitas vezes e não ocorreram erros. Entretanto, ainda não entendo como o resultado se forma neste horrível retorno, apesar de minha própria experiência bastante boa. Além disso, o fxsaber respondeu à pergunta de que ele mesmo não se lembra.

Vitaly, diga-me como este código funciona, se não for muito difícil para você e você "entender em alguns minutos" neste estilo!

Eu "abriria parênteses" em operador de retorno, substituiria toda a "pergunta" por "se" e retornaria valores encontrados via "ou" lógico. Pessoalmente, estou aborrecido com operador de "pergunta". Ele produz exatamente o mesmo código que um "se" semelhante, mas sua legibilidade é muito pior.

Não vou interpretar o código, mas uma vez coloquei uma peça do meu modelo, e há uma abordagem semelhante. Não gosto de esticar os "se" em dois rolos do monitor

 
Реter Konow:

não se esqueça daprodutividade do trabalho. Ele começa com a legibilidade do código.

Um exemplo do meu código, que neste momento não entendo de forma alguma. E há muitos fatores que você precisa entender muito bem.

Fórum sobre comércio, sistemas automatizados de comércio e testes estratégicos

Seqüência de execução do Init() e do DeInit()

fxsaber, 2017.04.14 23:35

  bool Check( void ) const
  {
    static bool FirstRun = true;
    static bool FirstRunInit = true;

    if (FirstRun && (!::GlobalVariableCheck(this.GlobalName)))
    {
      FirstRun = (::GlobalVariableSet(this.GlobalName, 0) == 0);

      if (!FirstRun)
      {
        ::EventKillTimer();

        ::OnInit();
        FirstRunInit = false;
      }
    }
    else if (FirstRun)
      ::EventSetMillisecondTimer(1);
    else
      FirstRunInit = true;

    return(FirstRun || !FirstRunInit);
  }

Como você pode ver, o código/estilo é muito simples. Mas só poderei detectar um erro nele ou em sua ausência quando puder reescrever o mesmo código. Levará realmente muito tempo, pois preciso entender completamente o problema.

É por isso que o princípio é que as coisas complexas são limpas (os testes de estresse são escritos) na fase de criação e utilizadas de forma simples através da conexão de mqh. Como você pode ver, a complexidade nem sempre é determinada pelo estilo ou pela brevidade.


Há também um exemplo de construções puramente lingüísticas - TypeToBytes. A complexidade de compreensão é um nível bem diferente. E aqui é onde eu murcharia sem macros. É por causa das macros que você entra no código fonte muito rapidamente. Porque as macros são freqüentemente usadas não para a brevidade, mas para a compreensão.


E há também o caso quando você tem que considerar muitas armadilhas descomplicadas, mas esquecíveis. Este é o caso do MT4Orders. É por isso que algumas linhas lá são acompanhadas de comentários dirigidos apenas a si mesmo. Ajuda a entender seu código.


Mas note que todos estes são mqh, nos quais você não precisa entrar. E o código da TC é escrito com mqh, o que é muito simples. Não se investiga o código fonte das funções iHigh regulares. E eles são realmente monstros. Basta usá-los. Você deve fazer o mesmo com as bibliotecas. A mesma Bíblia Genérica a ser usada não requer que você a entenda totalmente.


Veja o QB para MT4 EAs e seus portos MT5. Os portos do MT5 são um covarde para entender. Não só não cheira perto da concisão (o código é muitas vezes maior que o original), mas também vem com armadilhas de MT5 que não são contabilizadas nos arquivos de mqh.

 
Vitaly Muzichenko:

Não vou interpretar o código, mas uma vez coloquei uma peça do meu modelo, e há uma abordagem semelhante. Não gosto de esticar ses em dois rolos de monitor

Neste caso, é sábio usar funções.

E o fato de você não ter interpretado o código diz que você também não pode descobrir como ele funciona imediatamente. Você tem que analisar minuciosamente os parênteses, aquelas mesmas "perguntas" e "ou" lógico. Mas tal "empilhamento" é aceitável em casos muito limitados, quando dá código mais eficiente para ser usado no "gargalo da garrafa" do programa. Neste caso, obter o tipo de execução não pode de forma alguma ser um gargalo de garrafa e tal código é indesejável aqui. Uso-o exclusivamente com base na autoridade do fxsaber e em repetidos autoteste. Mas, isto é uma exceção. Como regra, eu não uso código que eu mesmo não tenha descoberto em detalhes.

 
Georgiy Merts:

A função realmente funciona bem. Eu verifiquei muitas vezes, não ocorreram erros. Mas ainda não entendo como o resultado é formado neste horrível retorno, apesar de minha experiência, em minha opinião, suficientemente boa. Além disso, o próprio fxsaber respondeu à pergunta de que ele mesmo não se lembra.

Não se trata de um repatriado. Se você descrever a mesma lógica na forma de if-else, isso não me fará entender melhor. Este é exatamente o caso quando você pega o problema do "preenchimento sem suporte" e o estuda muito profundamente. Você tem que escrever um monte de código de estresse associado, abrir muitas contas em diferentes servidores torus e correr através de todos os símbolos. Encontrar padrões entre diferentes combinações de bandeiras. E, finalmente, trazer todas as mesas para o mesmo denominador. É aqui que entra o "não consigo lembrar".

Conseguiu que o problema não ocorresse mais e fosse esquecido com segurança. É ótimo quando não se tem que voltar a um código uma vez escrito. Funciona - o principal.

Razão: