MB.: Kalkulationen in einer Zeile sind nicht zuviel?

Moin Community,

ich will wissen ob Rechenoperationen in einer Zeile nicht zuviel sind. Ich hab mal n kleines beispiel aus meinem Code genommen.

Konkretes Beispiel in JS:

for (var i = 0; i < count; i++) {
  // Creat new Array container
  step[i]= new Array(d.length);
  switch ( cfg ) {
    //// Linear sliding ////
    case "line"	:
      for ( var j = 1; j < d.length; j++ ) {
        var stp	= i * (d[j] / count)
        step[i][j] = stp;
      } break;
    //// power sliding ////
    case "pow" :
      for ( var j = 1; j < d.length; j++ ) {
        if ( d[j] == 0 ) {
          step[i][j] = 0;
        } if ( d[j] > 0 ) {
          var pow = Math.sqrt( d[j] );
	  var exp = (count -i) * (pow / count);
          step[i][j] = -Math.pow( exp, 2 ) + d[j];
        } if (d[j] < 0) {
          var temp = -d[j];
          var pow = Math.sqrt( temp );
          var exp = (count -i) * (pow / count);
          step[i][j] = Math.pow( exp, 2 ) + d[j];
        }
      } break;
      //// radial sliding ////
      case "rad" : 
        for (var j = 1; j < d.length; j++) {
	var calc = i * ( Math.PI / count );
        var res= Math.sin( calc +(Math.PI / 2) );
        step[i][j] =  -(d[j] / 2) * res +(d[j] / 2);
      } break;
      default : 
	alert("Algorithmic value!");
      break;
    }
} return step;
  • wenn ich zuviele kalkulationen mache verliehre ich früher oder später den überblick
  • wenn ich eine rechenoperation mache ist es zu lang an Code

Ich hoffe auf erfahrungen und andere herangehensweisen.

LB mb

  1. Hallo,

    ich will wissen ob Rechenoperationen in einer Zeile nicht zuviel sind.

    du meinst für dich selbst? Denn aus technischer Sicht ist das ziemlich egal.

    • wenn ich zuviele kalkulationen mache verliehre ich früher oder später den überblick
    • wenn ich eine rechenoperation mache ist es zu lang an Code

    Ich hoffe auf erfahrungen und andere herangehensweisen.

    Wenn es mehrere kurze, überschaubare Schritte sind, schreibe ich sie normalerweise in eine Zeile. Aber sobald ich merke, dass ich Mühe habe, den gesamten Ausdruck sofort zu erkennen, splitte ich ihn auf mehrere Zeilen - und ich meine Zeilen, nicht Anweisungen. Ich trenne die Zeilen dabei so, dass jede Zeile einen in sich geschlossenen gedanklichen Schritt darstellt. Etwa so:

    while (condition1
        && condition2
        && !condition3)
     { ...
    

    Noch eine Anmerkung zum Klammer-Stil: Ob man öffnende geschweifte Klammern ans Zeilenende setzen mag, ist Geschmackssache; ich will das nicht, weil ich sie dann leicht übersehe. Aber hinter die schließende Klammer noch eine Kontrollanweisung (break, return) in derselben Zeile, so wie ich es in deinem Codeauszug gesehen habe, ist sehr seltsam.

    So long,
     Martin

    --
    Bei der Umsetzung von guten Ideen hapert es meist viel mehr an der Wolle als an der Könne.
    1. Hallo Marin,

      Noch eine Anmerkung zum Klammer-Stil: ...

      mache ich auch so.

      Aber hinter die schließende Klammer noch eine Kontrollanweisung (break, return) in derselben Zeile, so wie ich ess in deinem Codeauszug gesehen habe, ist sehr seltsam.

      Ich arbeite noch an meinem Stil. Zur Begründung: Ih will damit die Zusammenhänge für mich deutlich machen wie:

      if{
      ...
      } else { // Diese Code Zeile
      ...
      }
      

      dem Folge ich als beispiel mit:

      switch( Bedingung ) {
        case Ausdruck : // fals der CASE-Block mehrere Spalten beansprucht
          Anweisung; break;  // BREAK ist ein sehr kurzer Befehl der immer gleich auftaucht
      }
      

      Wenn ich eine einfachen case Block habe will ich ihn in eine Zeile schreiben wenn es nicht 80 Zalten überschreitet.

      LG MB

      1. Moin!

        switch( Bedingung ) {
          case Ausdruck : // fals der CASE-Block mehrere Spalten beansprucht
            Anweisung; break;  // BREAK ist ein sehr kurzer Befehl der immer gleich auftaucht
        }
        

        Wenn ich eine einfachen case Block habe will ich ihn in eine Zeile schreiben wenn es nicht 80 Zalten überschreitet.

        Was ist das wichtigste an einem switch/case? Das Fehleranfälligste, wo man am Meisten Zeit mit Debugging verbringt?

        Wenn das "break" fehlt!

        Es gibt deshalb Coding Standards, die explizit vorschreiben (oder zumindest nahelegen), dass man einen Kommentar schreiben muss, wenn man an einer Stelle das "break" weglassen will, und das Absicht war.

        Deshalb: Nie das "break" ans Zeilenende. Dort wird es übersehen.

        Und wenn der Code eines Case sowieso in eine Zeile passt, sollte man das switch/case gleich ganz eliminieren, und beispielsweise Closures in einem Lookup-Array benutzen.

        Grüße Sven

  2. Tach!

    • wenn ich zuviele kalkulationen mache verliehre ich früher oder später den überblick
    • wenn ich eine rechenoperation mache ist es zu lang an Code

    Ich hoffe auf erfahrungen und andere herangehensweisen.

    Es gibt eine Daumenregel: Wenn in der Beschreibung, was ein Stück Code macht, ein "und" vorkommt, dann macht es zu viel und es ist Zeit für die Auslagerung in eine Funktion beispielsweise. In deinem Beispiel könnte man das, was die einzelnen cases machen, in eigene Funktionen/Methoden auslagern.

    Was auch nicht besonders toll ist, sind einbuchstabige nichtsprechende Bezeichner abseits von kurzen überschaubaren Codeabschnitten.

    dedlfix.

    1. Hallo,

      Es gibt eine Daumenregel: Wenn in der Beschreibung, was ein Stück Code macht, ein "und" vorkommt, dann macht es zu viel und es ist Zeit für die Auslagerung in eine Funktion beispielsweise.

      das ist aber wirklich nur eine Daumenregel, die ich oft nicht empfehlen würde. Beispielsweise wenn ein Stück Code nur eine sequentielle Abfolge von Schritten ist, die auch nur an einer Stelle vorkommt.

      In deinem Beispiel könnte man das, was die einzelnen cases machen, in eigene Funktionen/Methoden auslagern.

      Könnte man. Würde ich aber nicht tun, weil jeder case-Zweig immerhin noch kurz genug ist, um ihn bequem auf einer Bildschirmseite zu überblicken.

      So long,
       Martin

      --
      Bei der Umsetzung von guten Ideen hapert es meist viel mehr an der Wolle als an der Könne.
    2. Hallo Dedlfix,

      danke für die Daumenregel.

      Was auch nicht besonders toll ist, sind einbuchstabige nichtsprechende Bezeichner abseits von kurzen überschaubaren Codeabschnitten.

      Da ich nicht besonders gut in ausdrücken bin, habe ich nur buchstaben verwendet.

      Was mir wirklich wichtig war, sind die sorechenden Name der Funktionen. Damit kann man auf die Parameter mit einem Buchstaben schließen o oder obj = Objekt, e oder elem = Element, auch e oder err = Error, t = Zeit.

      Buchstaben aus denen erkennbar ist in einem "Sprechenden" Funktionsnamen was gemeint ist. Finde ich echt übersuchtlicher.

      Nachvollziehbar ;-)?

      LG MB

      1. Tach!

        Was mir wirklich wichtig war, sind die sorechenden Name der Funktionen. Damit kann man auf die Parameter mit einem Buchstaben schließen o oder obj = Objekt, e oder elem = Element, auch e oder err = Error, t = Zeit.

        Dass es ein Objekt oder ein Element ist, sieht man auf den ersten oder den zweiten Blick. Den Sinn dahinter sieht man nicht so schnell. Deswegen ist es wichtig, diesen Sinn mit einem sprechenden Bezeichner offenzulegen.

        Dass t allgemein für Zeit steht, ist aus der Physik zwar bekannt. Aber was für eine Zeit ist hier konkret gemeint? Das ist aus einen simplen t nicht erkennbar. Das mag übersichtlicher aussehen, aber ob es auch zum Verständnis beiträgt, darf bezweifelt werden.

        Es fällt nicht wenigen schwer, sprechende und gleichzeitig nicht allzu lange Namen für die Dinge zu finden. Es lohnt sich üblicherweise aber, sich dabei anzustrengen. Tipparbeit ist kein Argument, das dagegenspricht. Um die zu verkürzen gibt es Entwicklungsumgebungen mit Autovervollständigung.

        dedlfix.

        1. Hallo dedlfix,

          Was mir wirklich wichtig war, sind die sorechenden Name der Funktionen. Damit kann man auf die Parameter mit einem Buchstaben schließen

          Dass es ein Objekt oder ein Element ist, sieht man auf den ersten oder den zweiten Blick. Den Sinn dahinter sieht man nicht so schnell. Deswegen ist es wichtig, diesen Sinn mit einem sprechenden Bezeichner offenzulegen.

          Ich verweise noch einaml auf meinen obigen Kommentar zu dem du was geschrieben hast.

          Beispiel:

          function mathPower( b, e ) {
            r = 1;
            for( e = 0; e < b; e++ ){ // im beispiel verwende ich e anstatt i zu verdeutlichung
              r *= b;
            }
          }
          

          anstatt

          function mathPower( basis, exponent ) {
            result = 1;
            for( exponent = 0; exponent < basis; exponent++ ){
              result *= basis;
            } 
          }
          

          das ist natürlich übersichtlicher und ich würde das auch so schreiben aber wenns komplexer wird dann nicht! Im bepsiel gehts mir ums Prinzip.

          Ich bin noch zu unerfaren das ich darüber ne aussage fällen kann.

          1. Nachtrag:

            wie peinlich hab doch glatt das return r; vergessen. unverzeihlich! Seit bitte gnädig mit mir.

            vlg MB

          2. Moin!

            Ich verweise noch einaml auf meinen obigen Kommentar zu dem du was geschrieben hast.

            Beispiel:

            function mathPower( b, e ) {
              r = 1;
              for( e = 0; e < b; e++ ){ // im beispiel verwende ich e anstatt i zu verdeutlichung
                r *= b;
              }
            }
            

            anstatt

            function mathPower( basis, exponent ) {
              result = 1;
              for( exponent = 0; exponent < basis; exponent++ ){
                result *= basis;
              } 
            }
            

            das ist natürlich übersichtlicher und ich würde das auch so schreiben aber wenns komplexer wird dann nicht! Im bepsiel gehts mir ums Prinzip.

            Du meinst, dein erstes Beispiel ist übersichtlicher? Würde ich nicht sagen.

            Das zweite Codebeispiel macht mir beim Lesen beispielsweise sehr deutlich, dass du den Parameter "exponent" komplett ignorierst, und neu in der Schleife initialisierst. Außerdem vergleichst du den inkrementierten Exponenten mit der Basis. War das Problem der Potentberechnung nicht, so oft, wie der Exponent sagt, die Basis zu multiplizieren? Du brauchst also eine unabhängige Laufvariable, die du nicht hast.

            Und wenn du nur Buchstabenfitzel als Variablennamen verwendest, dann verwischst du den Sinn. Irgendein "e" als Laufvariable zu verwenden, ist genauso richtig oder falsch, wie ein "i" zu verwenden (wobei "i" mir immer "anonyme Laufvariable zum Inkrementieren" signalisiert - aber warum nicht auch mal "e" nehmen.) Ich erkenne den Sinngehalt der Funktion viel deutlicher, wenn die Variablennamen da ausgeschrieben stehen und ihren fachlichen Inhalt zum Namen haben.

            Ich bin noch zu unerfaren das ich darüber ne aussage fällen kann.

            Nimm den Rat der erfahrenen Entwickler hier, und schreibe Variablennamen lang. Manche Codingstyles meckern, wenn Variablennamen kürzer als 3 Zeichen sind.

            Dein Beispiel ist außerdem schlecht gewählt: In Code geht es nie selten um Mathematikoperationen, dafür gibts (hoffentlich) Support von der Programmiersprache selbst. Matheprobleme sind, zumindest bei solchen Basics, auch selbsterklärend, wenn nur wenigstens der Funktionsname etwas einleuchtend formuliert ist. In der Regel geht es immer um irgendeinen fachlichen Kontext, der nicht selbsterklärend ist. Und für den braucht man als Mensch alle verfügbaren Hilfestellungen zum Verständnis - ansonsten könntest du direkt Assembler binär in die Maschine tickern.

            Grüße Sven

            1. Hallo,

              Du meinst, dein erstes Beispiel ist übersichtlicher? Würde ich nicht sagen.

              ich auch nicht; für mich sind sie vomn der Verständlichkeit her gleichwertig.

              Das zweite Codebeispiel macht mir beim Lesen beispielsweise sehr deutlich, dass du den Parameter "exponent" komplett ignorierst, und neu in der Schleife initialisierst. Außerdem vergleichst du den inkrementierten Exponenten mit der Basis. War das Problem der Potentberechnung nicht, so oft, wie der Exponent sagt, die Basis zu multiplizieren? Du brauchst also eine unabhängige Laufvariable, die du nicht hast.

              Für mich haben beide Beispiele das Problem, dass zusammengehörende Token (Operand, Operator, Operand) genauso intern durch Leerzeichen getrennt sind wie Anweisungen untereinander. Ich bemühe mich im allgemeinen, zuammengehörende Token auch zusammen zu schreiben, und Leerzeichen (oder Leerzeilen) nur zur Trennung von separaten Schritten einzusetzen.

              In der Regel geht es immer um irgendeinen fachlichen Kontext, der nicht selbsterklärend ist. Und für den braucht man als Mensch alle verfügbaren Hilfestellungen zum Verständnis - ansonsten könntest du direkt Assembler binär in die Maschine tickern.

              Was oft das Ziel deutlicher zeigen würde als das, was manche Programmierer in Javascript, PHP, C oder einer anderen Hochsprache formulieren.

              So long,
               Martin

              --
              Bei der Umsetzung von guten Ideen hapert es meist viel mehr an der Wolle als an der Könne.
            2. Hallo Sven Rautenberg,

              Nimm den Rat der erfahrenen Entwickler hier, und schreibe Variablennamen lang.

              In der Regel geht es immer um irgendeinen fachlichen Kontext, der nicht selbsterklärend ist. Und für den braucht man als Mensch alle verfügbaren Hilfestellungen zum Verständnis.

              Obwohl ich den ersten Punkt etwas anders formuliert hätte („Verwende ausschließlich aussagekräftige Variablennamen - sogenannte sprechende Bezeichner“), möchte ich hinter diese beiden Aussagen, auch unabhängig vom Kontext der OOP zwei dicke Ausrufezeichen setzen.

              Bis demnächst
              Matthias

              --
              Wenn eine Idee nicht zuerst absurd erscheint, taugt sie nichts. (Albert Einstein)