Implementazioni alternative di funzioni/approcci standard - pagina 8

 
fxsaber:

Un esempio del mio stile?

Per esempio questo:

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

Immaginate di avere 100 funzioni e ognuna restituisce un tale record. Stai cercando un errore tra queste voci. Quanto tempo ci vorrà per la ricerca?

 
Реter Konow:

Per esempio questo:

Immaginate di avere 100 funzioni e ognuna restituisce questo record. Stai cercando un errore tra queste voci. Quanto tempo ci vorrà per la ricerca?

Non cercherei per più di un paio di minuti, soprattutto perché un record in questo stile permette di visualizzare più di qualche dozzina di funzioni in "una sola schermata", il che rende più facile lavorare con il codice

 
Реter Konow:

Per esempio questo:

Immaginate di avere 100 funzioni e ognuna restituisce questo record. Stai cercando un errore tra queste voci. Quanto tempo ci vorrà per trovarlo?

Credetemi quando scrivo testi come questo - non è per amore dello stile o del principio di brevità, ma perché è davvero molto più facile per me.

Hai citato il modo più semplice. Onestamente, non capisco cosa ci sia da confondere.

Devo confessare che non posso leggere il codice C++ perché non lo conosco affatto. Ma la gente ci scrive dentro. Quindi è solo una questione di ignoranza.

 
fxsaber:

Credetemi, quando scrivo in questo modo, non è per amore dello stile o del principio di brevità, ma perché è davvero più facile per me.

Lei ha citato il più semplice dei termini. Onestamente, non capisco cosa ci sia da confondere.

Devo confessare che non posso leggere il codice C++ perché non lo conosco affatto. Ma la gente ci scrive dentro. Quindi è solo una questione di ignoranza.

Forse abbiamo idee diverse sulla semplicità del codice.

Capisco che lei è un grande professionista della programmazione. Ma non bisogna dimenticare la produttivitàdel lavoro quando si insegue una produttività massima. Si comincia con la leggibilità del codice. Non mi è chiaro perché l'impulso di comprimere il codice a spese della leggibilità del codice sia giustificato, ma è abbastanza inaccettabile in grandi progetti (indipendenti).


Francamente, odio il C++ perché è troppo illeggibile. Per l'accumulo di entità la cui esistenza potrebbe essere facilmente evitata. E non potrà che migliorare. Spazioso.

SZU. Credo che nello sviluppo il codice debba essere compresso non a spese della leggibilità ma a spese di soluzioni migliori, pur lasciandolo il più leggibile possibile. La velocità di comprensione del codice ha un impatto enorme sulla vostra produttività.

ZSY. Il filo è grande. Grazie.

Productivity - США - MetaTrader 5
Productivity - США - MetaTrader 5
  • www.metatrader5.com
Индекс производительности труда показывает изменение объема выпущенной продукции, приходящегося на одного работника. Этот показатель полезен для предсказания инфляции и прироста объема производства. Если стоимость труда увеличивается соответственно увеличению производительности, и, кроме того, маловероятно увеличение производственных издержек...
 
Renat Fatkhullin:
Pensate a cosa otterrete fuori da un intero.

Quindi il controllo per LONG_MAX - dovrebbe essere prima di convertire il doppio in lungo. Chiaramente, la funzione di arrotondamento non è progettata per valori che non rientrano in un intero. E non cambia il problema.

Se la funzione restituisce doppio che poi convertiamo in lungo, affrontiamo lo stesso pericolo di overflow.

Personalmente, appena prima di arrotondare - ho sempre assert-check per i valori limite, più la logica del programma - cerco sempre di assicurarmi che la conversione non possa mai ottenere più del valore massimo per un intero.

 
Vitaly Muzichenko:

Non cercherei più di un paio di minuti, soprattutto perché scrivere in questo stile permette di visualizzare più di qualche dozzina di funzioni in "una schermata", rendendo più facile lavorare con il codice

C'è qualcosa di cui dubito.

Ecco il codice attuale della mia funzione, che restituisce il tipo di esecuzione (il codice è stato suggerito da fxsaber, e gli sono molto 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__ };

La funzione funziona molto bene. L'ho controllato molte volte e non si sono verificati errori. Ma ancora non capisco come si forma il risultato in questo terribile ritorno, nonostante la mia esperienza piuttosto buona. Inoltre, fxsaber ha risposto alla domanda che lui stesso non lo ricorda.

Vitaly, dimmi come funziona questo codice, se non è troppo difficile per te e lo "capisci in un paio di minuti" in questo stile!

Io "aprirei le parentesi" nell'operatore di ritorno, sostituirei tutte le "domande" con gli if e restituirei i valori trovati attraverso gli "or" logici. Personalmente sono infastidito dall'operatore "domanda". Produce esattamente lo stesso codice di un if simile, ma la sua leggibilità è molto peggiore.

 
Georgiy Merts:

Ho i miei dubbi al riguardo.

Ecco il codice attuale della mia funzione, che restituisce il tipo di esecuzione (il codice è stato suggerito da fxsaber, di cui gli sono molto grato):

La funzione funziona molto bene. L'ho controllato molte volte e non si sono verificati errori. Ma ancora non capisco come si forma il risultato in questo terribile ritorno, nonostante la mia, credo, abbastanza buona esperienza. Inoltre, fxsaber stesso ha risposto alla domanda che non si ricorda nemmeno.

Vitaly, dimmi come funziona questo codice, se non è troppo difficile per te e lo "capisci in un paio di minuti" in questo stile!

Io "aprirei le parentesi" nell'operatore di ritorno, sostituirei tutte le "domande" con gli if e restituirei i valori trovati tramite "or" logico. Personalmente sono molto infastidito dall'operatore "domanda". Produce esattamente lo stesso codice di un if simile, ma la sua leggibilità è molto peggiore.

Non interpreterò il codice, ma una volta ho postato un pezzo del mio template, e c'è un approccio simile. Non mi piace allungare i se in due rotoli del monitor

 
Реter Konow:

non dimenticare laproduttività del lavoro. Si comincia con la leggibilità del codice.

Un esempio del mio codice, che in questo momento non capisco affatto. E ci sono molti fattori che bisogna capire molto bene.

Forum sul trading, sistemi di trading automatico e test di strategia

Sequenza di esecuzione di Init() e 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);
  }

Come potete vedere, il codice/stile è molto semplice. Ma sarò in grado di rilevare un errore in esso o la sua assenza solo quando potrò riscrivere lo stesso codice. Ci vorrà davvero molto tempo, perché ho bisogno di capire a fondo il problema.

Ecco perché il principio è che le cose complesse vengono ripulite (vengono scritti gli stress test) in fase di creazione e utilizzate in forma semplice inserendo mqh. Come potete vedere, la complessità non è sempre determinata dallo stile o dalla brevità.


C'è anche un esempio di costrutti puramente linguistici - TypeToBytes. La complessità della comprensione è di un altro livello. Ed è qui che appassirei senza macro. È grazie alle macro che si entra abbastanza rapidamente nel codice sorgente. Perché le macro sono spesso usate non per la brevità, ma per la comprensione.


E c'è anche il caso in cui bisogna considerare un sacco di insidie non complicate ma dimenticabili. Questo è il caso di MT4Orders. Ecco perché alcune righe sono accompagnate da commenti rivolti solo a se stessi. Aiuta a capire il tuo codice.


Ma si noti che questi sono tutti mqh, che non è necessario entrare. E il codice di TC è scritto con mqh, che è molto semplice. Non si guarda nel codice sorgente delle funzioni regolari di iHigh. E sono davvero dei mostri. Basta usarli. Dovreste fare lo stesso con le biblioteche. La stessa Bibbia generica da usare non richiede che la comprendiate appieno.


Guarda il QB per gli EA MT4 e le loro porte MT5. Le porte di MT5 sono uno strazio da capire. Non solo non ha un odore vicino alla concisione (il codice è molte volte più grande dell'originale), ma viene anche con trabocchetti di MT5 che non sono considerati nei file mqh.

 
Vitaly Muzichenko:

Non interpreterò il codice, ma una volta ho postato un pezzo del mio template, e c'è un approccio simile. Non mi piace allungare i se in due rotoli di monitor

In questo caso, è saggio usare le funzioni.

E il fatto che non hai interpretato il codice dice che nemmeno tu riesci a capire subito come funziona. Bisogna analizzare a fondo le parentesi, proprio quelle "domande" e le "o" logiche. Ma tale "accumulo" è accettabile in casi molto limitati, quando dà codice più efficiente da usare nel "collo di bottiglia" del programma. In questo caso, ottenere il tipo di esecuzione non può essere un collo di bottiglia e tale codice è indesiderabile qui. Lo uso solo sulla base dell'autorità di fxsaber e di ripetuti autotest. Ma questa è un'eccezione. Come regola, non uso codice che non ho capito in dettaglio io stesso.

 
Georgiy Merts:

La funzione funziona davvero bene. Ho controllato molte volte, non si sono verificati errori. Ma ancora non capisco come si forma il risultato in questo orribile ritorno, nonostante la mia, secondo me, abbastanza buona esperienza. Inoltre, lo stesso fxsaber ha risposto alla domanda che non lo ricorda lui stesso.

Non si tratta di rimpatrio. Se descrivete la stessa logica sotto forma di if-else, non mi farà capire meglio. Questo è esattamente il caso quando si prende il problema del "riempimento non supportato" e lo si studia molto profondamente. Devi scrivere un sacco di codice di stress associato, aprire un sacco di account su diversi server torus e correre attraverso tutti i simboli. Trovare modelli tra diverse combinazioni di bandiere. E infine, per portare tutti i tavoli ad un denominatore comune. È qui che entra in gioco il "non ricordo".

Raggiunto che il problema non si verifica più e tranquillamente dimenticato. È fantastico quando non si deve tornare al codice scritto una volta. Funziona - la cosa principale.

Motivazione: