Implementaciones alternativas de funciones/enfoques estándar - página 8

 
fxsaber:

¿Un ejemplo de mi estilo?

Por ejemplo esto:

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

Imagina que tienes 100 funciones y que cada una devuelve un registro de este tipo. Está buscando un error entre estas entradas. ¿Cuánto tiempo le llevará la búsqueda?

 
Реter Konow:

Por ejemplo esto:

Imagina que tienes 100 funciones y cada una devuelve este registro. Está buscando un error entre estas entradas. ¿Cuánto tiempo le llevará la búsqueda?

Yo no buscaría más que un par de minutos, sobre todo porque un registro de este estilo permite mostrar más de una docena de funciones en "una pantalla", lo que facilita el trabajo con el código

 
Реter Konow:

Por ejemplo esto:

Imagina que tienes 100 funciones y cada una devuelve este registro. Está buscando un error entre estas entradas. ¿Cuánto tiempo tardarás en encontrarlo?

Créeme, cuando escribo textos así, no es por cuestiones de estilo o por el principio de brevedad, sino porque me resulta mucho más fácil.

Has citado la forma más sencilla. Sinceramente, no veo qué puede haber de confuso en ello.

Debo confesar que no sé leer código C++ porque no lo conozco en absoluto. Pero la gente escribe en él. Así que es sólo una cuestión de ignorancia.

 
fxsaber:

Créame, cuando lo escribo así no es por estilo o por el principio de la brevedad, sino porque realmente me resulta más fácil.

Has citado los términos más simples. Sinceramente, no entiendo qué puede haber de confuso en ello.

Debo confesar que no sé leer código C++ porque no lo conozco en absoluto. Pero la gente escribe en él. Así que es sólo una cuestión de ignorancia.

Tal vez tengamos ideas diferentes sobre la simplicidad del código.

Tengo entendido que es usted un gran profesional de la programación. Pero cuando se persigue la máxima productividad en todo no hay que olvidar laproductividad laboral. Comienza con la legibilidad del código. No tengo claro por qué se justifica el afán de comprimir el código a costa de la legibilidad del mismo, pero es bastante inaceptable en proyectos grandes (independientes).


Francamente, odio C++ porque es demasiado ilegible. Por el amontonamiento de entidades cuya existencia podría evitarse fácilmente. Y sólo va a mejorar. Amplio.

SZU. Creo que en el desarrollo hay que comprimir el código no a expensas de la legibilidad, sino a expensas de mejores soluciones, dejándolo lo más legible posible. La velocidad de comprensión del código tiene un gran impacto en su propia productividad.

ZSY. El hilo es genial. Gracias.

Productivity - США - MetaTrader 5
Productivity - США - MetaTrader 5
  • www.metatrader5.com
Индекс производительности труда показывает изменение объема выпущенной продукции, приходящегося на одного работника. Этот показатель полезен для предсказания инфляции и прироста объема производства. Если стоимость труда увеличивается соответственно увеличению производительности, и, кроме того, маловероятно увеличение производственных издержек...
 
Renat Fatkhullin:
Piensa en lo que obtendrás fuera de un número entero.

Así que la comprobación de LONG_MAX - debería ser antes de convertir double en long. Claramente, la función de redondeo no está diseñada para valores que no caben en un entero. Y eso no cambia el problema.

Si la función devuelve un doble que luego convertimos en long, nos enfrentamos al mismo peligro de desbordamiento.

Personalmente, justo antes de redondear -siempre tengo la comprobación de los valores límite, además de la lógica del programa- siempre busco que la conversión no pueda obtener nunca más que el valor máximo para un entero.

 
Vitaly Muzichenko:

Yo no buscaría más que un par de minutos, sobre todo porque escribir en este estilo permite mostrar más de una docena de funciones en "una pantalla", lo que facilita el trabajo con el código

Hay algo que dudo de eso.

Aquí está el código real de mi función, que devuelve el tipo de ejecución (el código fue sugerido por fxsaber, por lo que le estoy muy agradecido):

// Для МТ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__ };

La función funciona muy bien. Lo he comprobado muchas veces y no había ningún error. Sin embargo, sigo sin entender cómo se forma el resultado en este horrible retorno, a pesar de mi propia experiencia bastante buena. Además, fxsaber respondió a la pregunta que él mismo ni siquiera lo recuerda.

¡Vitaly, dime cómo funciona este código, si no es muy difícil para ti y lo "entiendes en un par de minutos" en este estilo !

Yo "abriría paréntesis" en el operador de retorno, sustituiría todas las "preguntas" por if's y devolvería los valores encontrados a través de "or" lógico. Personalmente me molesta el operador "pregunta" en absoluto. Produce exactamente el mismo código que un if similar, pero su legibilidad es mucho peor.

 
Georgiy Merts:

Tengo mis dudas al respecto.

Aquí está el código real de mi función, que devuelve el tipo de ejecución (el código fue sugerido por fxsaber, por lo que le estoy muy agradecido):

La función funciona muy bien. Lo he comprobado muchas veces y no se ha producido ningún error. Pero sigo sin entender cómo se forma el resultado en esta horrible devolución, a pesar de mi, creo, bastante buena experiencia. Además, el propio fxsaber respondió a la pregunta que ni siquiera lo recuerda.

¡Vitaly, dime cómo funciona este código, si no es muy difícil para ti y lo "entiendes en un par de minutos" en este estilo !

Yo "abriría paréntesis" en el operador de retorno, sustituiría todas las "preguntas" por if's y devolvería los valores encontrados mediante "or" lógico. Personalmente me molesta mucho el operador "pregunta". Produce exactamente el mismo código que un if similar, pero su legibilidad es mucho peor.

No voy a interpretar el código, pero una vez publiqué un trozo de mi plantilla, y hay un enfoque similar. No me gusta estirar los "si" en dos pergaminos del monitor

 
Реter Konow:

no te olvides de laproductividad del trabajo. Comienza con la legibilidad del código.

Un ejemplo de mi código, que ahora mismo no entiendo nada. Y hay muchos factores que hay que entender muy bien.

Foro sobre comercio, sistemas de comercio automatizados y pruebas de estrategias

Secuencia de ejecución de Init() y 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 puedes ver, el código/estilo es muy sencillo. Pero sólo podré detectar un error en él o su ausencia cuando pueda reescribir el mismo código. Realmente me va a llevar mucho tiempo, ya que necesito entender completamente el problema.

Por eso el principio es que las cosas complejas se limpian (se escriben las pruebas de esfuerzo) en la etapa de creación y se utilizan de forma simple al enchufar mqh. Como puede ver, la complejidad no siempre viene determinada por el estilo o la brevedad.


También hay un ejemplo de construcciones puramente lingüísticas: TypeToBytes. La complejidad de la comprensión es un nivel muy diferente. Y aquí es donde me marchitaría sin las macros. Precisamente gracias a las macros, se puede entrar en el código fuente con bastante rapidez. Porque las macros se utilizan a menudo no para la brevedad, sino para la comprensión.


Y también está el caso en el que hay que tener en cuenta un montón de escollos poco complicados, pero olvidables. Este es el caso de MT4Orders. Por eso algunas líneas van acompañadas de comentarios dirigidos sólo a uno mismo. Ayuda a entender su código.


Pero ten en cuenta que todos estos son mqh, en los que no necesitas entrar. Y el código de TC está escrito con mqh, que es muy sencillo. No se mira el código fuente de las funciones regulares de iHigh. Y son monstruosos, en efecto. Sólo tienes que usarlos. Debería hacer lo mismo con las bibliotecas. El mismo genérico-biblioteca para usar no requiere que lo entiendas completamente.


Mira el QB para los EAs de MT4 y sus puertos de MT5. Los puertos de MT5 son un cojo para entender. No sólo no huele a concisión (el código es muchas veces más grande que el original), sino que también viene con trampas de MT5 que no se tienen en cuenta en los archivos mqh.

 
Vitaly Muzichenko:

No voy a interpretar el código, pero una vez publiqué un trozo de mi plantilla, y hay un enfoque similar. No me gusta estirar los si en dos rollos de monitor

En este caso, es conveniente utilizar funciones.

Y el hecho de que no hayas interpretado el código dice que tampoco puedes averiguar cómo funciona de inmediato. Hay que analizar a fondo los paréntesis, esas mismas "preguntas" y "o" lógicas. Pero ese "amontonamiento" es aceptable en casos muy limitados, cuando da lugar a un código más eficiente que se utiliza en el "cuello de botella" del programa. En este caso, obtener el tipo de ejecución no puede ser un cuello de botella y ese código no es deseable aquí. Lo uso únicamente basándome en la autoridad de fxsaber y en las repetidas autocomprobaciones. Pero, esto es una excepción. Por regla general, no utilizo código que no haya resuelto yo mismo en detalle.

 
Georgiy Merts:

La función funciona realmente bien. Lo he comprobado muchas veces y no se ha producido ningún error. Pero sigo sin entender cómo se forma el resultado en este horrible retorno, a pesar de mi, en mi opinión, bastante buena experiencia. Además, el propio fxsaber respondió a la pregunta que él mismo no lo recuerda.

No se trata de un retorno. Si describes la misma lógica en forma de if-else, no hará que la entienda mejor. Este es exactamente el caso cuando se toma el problema del "relleno no soportado" y se estudia muy profundamente. Hay que escribir un montón de código de estrés asociado, abrir un montón de cuentas en diferentes servidores torus y correr a través de todos los símbolos. Encontrar patrones entre diferentes combinaciones de banderas. Y, por último, llevar todas las tablas al mismo denominador. Aquí es donde entra el "no me acuerdo".

Conseguido que el problema ya no se produzca y olvidado con seguridad. Es estupendo no tener que volver a un código ya escrito. Funciona - lo principal.