Schaltjahr: "sauberer" Code

Vom einfachen Programm zum fertigen Debian-Paket, Fragen rund um Programmiersprachen, Scripting und Lizenzierung.
Benutzeravatar
Lord_Carlos
Beiträge: 5578
Registriert: 30.04.2006 17:58:52
Lizenz eigener Beiträge: GNU Free Documentation License
Wohnort: Dänemark

Re: Schaltjahr: "sauberer" Code

Beitrag von Lord_Carlos » 08.11.2016 11:48:50

paedubucher hat geschrieben: Lustig finde ich, dass ein Java-Experte (der Dozent) den Code der Java-Library überarbeiten würde.
Ich glaube eher er hat nach einer Aufgabe gesucht um euch etwas beizubringen. Der Inhalt ist nicht so wichtig, es geht um die Problem Loesung.
Das ist jedenfalls meine Vermutung.

Schaltjahr, Zeitumstellung und Zeitzonen selber zu implementieren sollte man so oder so vermeiden. Bekanntes Video dazu (Auf English) https://www.youtube.com/watch?v=-5wpm-gesOY

Code: Alles auswählen

╔═╗┬ ┬┌─┐┌┬┐┌─┐┌┬┐╔╦╗
╚═╗└┬┘└─┐ │ ├┤ │││ ║║
╚═╝ ┴ └─┘ ┴ └─┘┴ ┴═╩╝ rockt das Forum!

Benutzeravatar
paedubucher
Beiträge: 850
Registriert: 22.02.2009 16:19:02
Lizenz eigener Beiträge: GNU Free Documentation License
Wohnort: Schweiz
Kontaktdaten:

Re: Schaltjahr: "sauberer" Code

Beitrag von paedubucher » 08.11.2016 12:18:44

Lord_Carlos hat geschrieben: Ich glaube eher er hat nach einer Aufgabe gesucht um euch etwas beizubringen. Der Inhalt ist nicht so wichtig, es geht um die Problem Loesung.
Das ist jedenfalls meine Vermutung.
Das mag schon sein. Aber dann bleibe ich dabei: gut gemeint, weniger gut gemacht.
Lord_Carlos hat geschrieben: Schaltjahr, Zeitumstellung und Zeitzonen selber zu implementieren sollte man so oder so vermeiden. Bekanntes Video dazu (Auf English) https://www.youtube.com/watch?v=-5wpm-gesOY
Das kenne ich schon, es ist in der Tat eine grossartige Erklärung!
Habe nun, ach! Java
Python und C-Sharp,
Und leider auch Visual Basic!
Durchaus programmiert mit heissem Bemühn.
Da steh' ich nun, ich armer Tor!
Und bin so klug als wie zuvor.

Benutzeravatar
Meillo
Moderator
Beiträge: 8782
Registriert: 21.06.2005 14:55:06
Wohnort: Balmora
Kontaktdaten:

Re: Schaltjahr: "sauberer" Code

Beitrag von Meillo » 08.11.2016 12:31:29

paedubucher hat geschrieben:

Code: Alles auswählen

public static boolean isLeap(int year) {
	return year % 4 == 0 && (year % 100 != 0 || year % 400 == 0);
}
Nun meinte der Dozent, dass dieser Code zwar richtig, aber nicht sehr gut lesbar sei.
Das ist der typische Kommentar von mittelpraechtigen Programmierern ...

Gute Programmierer erkennen in obigem Code ein Idiom, weil sie genau dieses Pattern schon x-mal gesehen haben und auf einem Blick erfassen und verstehen koennen. Damit wird der Code -- ganz im Gegenteil zur Meinung des Dozenten -- viel leichter lesbar, denn er kann auf einen Blick erfasst werden!

(Ob die == bzw. != und die && bzw. || nun richtig sind oder nicht, das ist in keiner Umsetzung einfach zu pruefen.)
Use ed once in a while!

Benutzeravatar
hikaru
Moderator
Beiträge: 13559
Registriert: 09.04.2008 12:48:59

Re: Schaltjahr: "sauberer" Code

Beitrag von hikaru » 08.11.2016 12:53:15

offtopic:
Die Jungs aus dem Javaforum könnten mal ihre Code-Blöcke überarbeiten.
Solch unnötig schmales Website-Design, das im Vollbild nur 1/3 des Monitors füllt finde ich eh schon ungünstig, aber dann Code-Blöcke in einem Programmierfoum(!) nochmal auf die Hälfte dessen zu reduzieren hätte ich bis eben für einen verirrten Aprilscherz gehalten. DAS ist unlesbarer Code.

Benutzeravatar
Lord_Carlos
Beiträge: 5578
Registriert: 30.04.2006 17:58:52
Lizenz eigener Beiträge: GNU Free Documentation License
Wohnort: Dänemark

Re: Schaltjahr: "sauberer" Code

Beitrag von Lord_Carlos » 08.11.2016 13:24:40

Nochmal drueber nachgedacht finde ich eine Erweiterung von Loesung #2 am besten:

Code: Alles auswählen

    public static boolean isLeap(int year) {
        return isDividableBy(4, year) && isCenturyLeap(year);
    }

    private static boolean isCenturyLeap(int year) {
        return !isDividableBy(100, year) || isDividableBy(400, year);
    }

    private static boolean isDividableBy(int what, int x) {
        return x % what == 0;
    }
So hat man das wichtigste auf einer Linie, ohne es so voll zu machen wie in Loesung #3
Man kann jedoch schnell in die details eintauchen wenn es wichtig ist.
Und leichter veraendern wenn z.B. leap Century Berechnung irgendwann mal komplexer wird.
Meillo hat geschrieben: Das ist der typische Kommentar von mittelpraechtigen Programmierern ...
Das ist doch mal eine Aussage.

Code: Alles auswählen

╔═╗┬ ┬┌─┐┌┬┐┌─┐┌┬┐╔╦╗
╚═╗└┬┘└─┐ │ ├┤ │││ ║║
╚═╝ ┴ └─┘ ┴ └─┘┴ ┴═╩╝ rockt das Forum!

Liffi
Beiträge: 2306
Registriert: 02.10.2004 01:33:05

Re: Schaltjahr: "sauberer" Code

Beitrag von Liffi » 08.11.2016 13:29:46

Ich finde bei den drei wirklich überschaubaren Bedingungen Lösung 2 am besten.
Zusätzlich bin ich auch kein Freund von statischen Methoden. Auch wenn die hier natürlich überschaubar sind und keine Seiteneffekte haben. Sie erschweren das Testen einfach unnötig. (Ja, manche statische Methoden ergeben sicher Sinn, z.B. in der Math Klasse).

Benutzeravatar
Meillo
Moderator
Beiträge: 8782
Registriert: 21.06.2005 14:55:06
Wohnort: Balmora
Kontaktdaten:

Re: Schaltjahr: "sauberer" Code

Beitrag von Meillo » 08.11.2016 14:13:37

MSfree hat geschrieben: Und schädlich für die Geschwindigkeit.
Wer in Fragen der Code-Qualitaet die Rechner-Performance anfuehrt, verliert. (Ihr duerft das gerne Meillo's Law nennen.)

In den allermeisten Faellen (also in sehr viel mehr Faellen als man gemeinhin denkt) ist die Code-Qualitaet (und damit die Programmierer-Performance) soviel bedeutender als die Rechner-Performance.


Was fuer ein super Beispiel hier auch gleich zur Hand ist:
paedubucher hat geschrieben: Dort wurde mir gerade mitgeteilt, dass diese Methode seit Java 8 zur Standardlibrary gehört:

Code: Alles auswählen

public static boolean isLeap(long year) {
    return ((year & 3) == 0) && ((year % 100) != 0 || (year % 400) == 0);
}
Das ist fast identisch mit meinem Code, nur wurde Modulo 4 mit einem bitweisen Und umgesetzt.
Ich bin der Meinung, dass diese Optimierung zugunsten der Rechner so sehr zum Schaden der Programmierer ist, dass man dafuer Schmerzensgeld zahlen sollte. Nicht nur, dass hier ploetzlich das Idiom (4 -- 100 -- 400) verloren gegangen ist, viel schlimmer noch, hier riecht es ja sowas von nach einem Vertipper, dass es IMO einen Kommentar erfordern wuerde, der klarstellt, dass die 3 hier korrekt ist und das keine falsche 4 ist. All dies nur fuer ein kleines bisschen Rechner-Performance ... die der Compiler von morgen sowieso selbststaendig (vielleicht noch viel besser!) wegoptimieren wuerde.

Danke fuer dieses Beispiel als der Java-Standardbibliothek! Das wird mir noch viele Jahre als perfektes Beispiel fuer eine Worst Practice dienen.
Use ed once in a while!

Benutzeravatar
Lord_Carlos
Beiträge: 5578
Registriert: 30.04.2006 17:58:52
Lizenz eigener Beiträge: GNU Free Documentation License
Wohnort: Dänemark

Re: Schaltjahr: "sauberer" Code

Beitrag von Lord_Carlos » 08.11.2016 15:04:02

Meillo hat geschrieben: Ich bin der Meinung, dass diese Optimierung zugunsten der Rechner so sehr zum Schaden der Programmierer ist, dass man dafuer Schmerzensgeld zahlen sollte.
^ Dies.
Die Frage ist nur ob es so Programmiert wurde oder so aus dem de-compiler gekommen ist.

Code: Alles auswählen

╔═╗┬ ┬┌─┐┌┬┐┌─┐┌┬┐╔╦╗
╚═╗└┬┘└─┐ │ ├┤ │││ ║║
╚═╝ ┴ └─┘ ┴ └─┘┴ ┴═╩╝ rockt das Forum!

uname
Beiträge: 12045
Registriert: 03.06.2008 09:33:02

Re: Schaltjahr: "sauberer" Code

Beitrag von uname » 08.11.2016 16:10:11

Also mir gefällt die reine Modulo-Lösung am besten. Auch darf man bei heutigen Programmierern hoffentlich noch etwas IT-Sachverstand voraussetzen. Also die Lösung ist doch aufgrund der Boolesche Algebra sehr leicht zu erklären.

Vielleicht ein etwas einfacheres Beispiel im Vergleich zum Teilproblem: year % 100 != 0 || year % 400 == 0 . Ist aber im Prinzip auch eine Art Implikation als Oder-Funktion.

Bei Debiantmux benötige ich immer genau eine Sitzung. Sollte eine Sitzung existieren, möchte ich sie weiternutzen. Existiert keine Sitzung, so möchte ich eine neue Sitzung aufbauen. tmux bietet mir hierfür keinen eigenen Befehl.

Boolesche Algebra (Implikation)
Wenn ich keine Sitzung weiternutzen kann, dann möchte ich eine Sitzung aufbauen.

a: Sitzung weiternutzen
b: Sitzung aufbauen

Code: Alles auswählen

!a -> b  <=> a v b
Daraus folgt:

Code: Alles auswählen

tmux attach || tmux new
[1] https://de.wikipedia.org/wiki/Boolesche_Funktion

Wie kann ich das nun sauberer, einfacher oder eleganter programmieren? Vorschläge?

Benutzeravatar
Meillo
Moderator
Beiträge: 8782
Registriert: 21.06.2005 14:55:06
Wohnort: Balmora
Kontaktdaten:

Re: Schaltjahr: "sauberer" Code

Beitrag von Meillo » 08.11.2016 16:41:34

uname hat geschrieben: Bei Debiantmux benötige ich immer genau eine Sitzung. Sollte eine Sitzung existieren, möchte ich sie weiternutzen. Existiert keine Sitzung, so möchte ich eine neue Sitzung aufbauen. tmux bietet mir hierfür keinen eigenen Befehl.

[...]

Code: Alles auswählen

tmux attach || tmux new
Ha, da geht's dir wie mir:

Code: Alles auswählen

$ cat ~/bin/t
#!/bin/sh
tmux a || tmux
Die Alternative ist halt, wie du selbst (sinngemaess) schon schreibst:

Code: Alles auswählen

if ! tmux a ; then
    tmux
fi
Eleganter finde ich das nicht und ich kenne auch keine elegantere Umsetzung als mit || ... jedenfalls nicht in den Programmiersprachen, die ich programmiere.
Use ed once in a while!

Benutzeravatar
paedubucher
Beiträge: 850
Registriert: 22.02.2009 16:19:02
Lizenz eigener Beiträge: GNU Free Documentation License
Wohnort: Schweiz
Kontaktdaten:

Re: Schaltjahr: "sauberer" Code

Beitrag von paedubucher » 08.11.2016 17:09:02

@hikaru
Das sieht nur so besch...eiden aus, wenn man nicht eingeloggt ist. Die Werbe-Zwischenposts verschwinden nach dem Einloggen ebenfalls.

@Lord_Carlos
Die Lösung mit isCenturyLeap finde ich nicht schlecht, zumal man da nicht drei Variablennamen erfinden muss, sondern eben nur einen Begriff ("century leap"). Damit könnte ich leben.

Das "year & 3" wäre wirklich ein Griff ins Klo, wenn das tatsächlich so im Code steht. Dass der Compiler so etwas erzeugt, kann ich aber gut nachvollziehen. Aber dass das aus dem De-Compiler kommen soll, scheint mir unwahrscheinlich, da JavaDoc und alles weitere auch dabei ist.

Ich habe auch schon bei einigen Java-Programmierern festgestellt, dass Code sehr schnell als "hässlich" bezeichnet wird, wenn darin viele Operatoren vorkommen. Man versucht dann, dass auf Methoden zu verteilen. Zur Klarheit trägt das aber nur bedingt bei.

Nachtrag: In Clean Code wird es so gelöst:

Code: Alles auswählen

public static boolean isLeapYear(int year) {
	boolean fourth = year % 4 == 0;
	boolean hundredth = year % 100 == 0;
	boolean fourHundredth = year % 400 == 0;
	return fourth && (!hundreth || fourHundredth);
}
Die Variablennamen sind sinnvoll gewählt, finde ich. Auch auf das isDividable wird verzichtet. Von daher halte ich das für eine gute Lösung.
Habe nun, ach! Java
Python und C-Sharp,
Und leider auch Visual Basic!
Durchaus programmiert mit heissem Bemühn.
Da steh' ich nun, ich armer Tor!
Und bin so klug als wie zuvor.

Benutzeravatar
TRex
Moderator
Beiträge: 8038
Registriert: 23.11.2006 12:23:54
Lizenz eigener Beiträge: MIT Lizenz
Wohnort: KA

Re: Schaltjahr: "sauberer" Code

Beitrag von TRex » 21.11.2016 12:32:21

Jesus saves. Buddha does incremental backups.
Windows ist doof, Linux funktioniert nichtDon't break debian!Wie man widerspricht

Benutzeravatar
Meillo
Moderator
Beiträge: 8782
Registriert: 21.06.2005 14:55:06
Wohnort: Balmora
Kontaktdaten:

Re: Schaltjahr: "sauberer" Code

Beitrag von Meillo » 21.11.2016 14:30:51

Use ed once in a while!

Benutzeravatar
Meillo
Moderator
Beiträge: 8782
Registriert: 21.06.2005 14:55:06
Wohnort: Balmora
Kontaktdaten:

Re: Schaltjahr: "sauberer" Code

Beitrag von Meillo » 27.11.2016 21:15:27

paedubucher hat geschrieben: Nachtrag: In Clean Code wird es so gelöst:

Code: Alles auswählen

public static boolean isLeapYear(int year) {
	boolean fourth = year % 4 == 0;
	boolean hundredth = year % 100 == 0;
	boolean fourHundredth = year % 400 == 0;
	return fourth && (!hundreth || fourHundredth);
}
Auch ich will noch was nachtragen:

In ``The C Programming Language'' (2nd Ed.) von Kernighan und Ritchie ist auf Seite 41 folgender Code zu finden:

Code: Alles auswählen

if ((year % 4 == 0 && year % 100 != 0) || year % 400 == 0)
	printf("%d is a leap year\n", year);
else
	printf("%d is not a leap year\n", year);
Auf Seite 111 wird die gleiche Codezeile aufgegriffen, aber mit fehlendem Whitespace um den Modulo-Operator und ohne Klammern:

Code: Alles auswählen

leap = year%4 == 0 && year%100 != 0 || year%400 == 0;
(Evtl. ist die Anpassung der kurzen Zeilenlaenge im Buch geschuldet.)


In ``The Practice of Programming'' von Kernighan und Pike -- dem IMO besseren Zwilling von ``Clean Code'' -- steht auf Seite 7, im Abschnitt zu runden Klammern:
Even if parenthesis aren't necessary, they can help if the grouping is hard to grasp at first glance. This code doesn't need parenthesis:

Code: Alles auswählen

leap_year = y % 4 == 0 && y % 100 != 0 || y % 400 == 0;
but they make it easier to understand:

Code: Alles auswählen

leap_year = ((y%4 == 0) && (y%100 != 0)) || (y%400 == 0);
We also removed some of the blanks: grouping the operands of higher-precedence operators helps the reader to see the structure more quickly.
(Dass hier `y' statt `year' verwendet wird ist vermutlich der Zeilenlaenge geschuldet; dafuer wurde aber vorne `leap_year' statt nur `leap' verwendet, was das `y' dadurch verstaendlich macht.)

(Edit: Interessanterweise klammern Kernighan und Co. vorne, waehrend alle anderen hinten klammern.)


Um aber auch noch was ganz Abgefahrenes aus dem alten Unix-Umfeld zu bieten, hier ein Stueck Code aus Heirloom cal(1):

Code: Alles auswählen

        switch((jan1(y+1)+7-d)%7) {

        /*
         *      non-leap year
         */
        case 1:
                mon[2] = 28;
                break;

        /*
         *      1752
         */
        default:
                mon[9] = 19;
                break;

        /*
         *      leap year
         */
        case 2:
                ;
        }
Da war jemand super-clever und wollte das auch zeigen. Solchen Code will man nicht bearbeiten muessen.

(Ich sollte wohl mal zurueck verfolgen wo diese konkrete Implementierung herkommt ... wuerde auf Kalifornien tippen ;-) denn in der Codebasis von mmh, meinem Softwareprojekt, gab es auch so Zeugs, und der Code stammt auch aus Kalifornien. :-D )
Use ed once in a while!

owl102

Re: Schaltjahr: "sauberer" Code

Beitrag von owl102 » 27.11.2016 22:00:04

Meillo hat geschrieben:hier ein Stueck Code aus Heirloom cal(1):
Wie ist das Makro bzw. die Funktion jan1() implementiert?

Benutzeravatar
schorsch_76
Beiträge: 2535
Registriert: 06.11.2007 16:00:42
Lizenz eigener Beiträge: MIT Lizenz

Re: Schaltjahr: "sauberer" Code

Beitrag von schorsch_76 » 27.11.2016 22:30:06

Etwas Offtopic, aber im Bezug zum Compiler Optimizer

Understanding Compiler Optimization - Chandler Carruth - Opening Keynote Meeting C++ 2015
https://youtu.be/FnGCDLhaxKU?t=23m30s

Das ist zwar von der Cppcon, aber Optimizer arbeiten auf der gemeinsamen Zwischensprache welche auch für C verwendet wird.

Benutzeravatar
Meillo
Moderator
Beiträge: 8782
Registriert: 21.06.2005 14:55:06
Wohnort: Balmora
Kontaktdaten:

Re: Schaltjahr: "sauberer" Code

Beitrag von Meillo » 28.11.2016 05:21:56

owl102 hat geschrieben: Wie ist das Makro bzw. die Funktion jan1() implementiert?
http://heirloom.cvs.sourceforge.net/vie ... iew=markup
Entschuldige, dass ich den Code nicht gleich verlinkt habe.
Use ed once in a while!

Benutzeravatar
seep
Beiträge: 544
Registriert: 31.10.2004 14:21:08
Lizenz eigener Beiträge: GNU Free Documentation License
Wohnort: HSK

Re: Schaltjahr: "sauberer" Code

Beitrag von seep » 30.11.2016 08:57:01

Schöner Thread! :)

Erinnert mich an meine ersten Schritte in C, als ich für ein Projekt mal eine for-Schleife mit wenig, aber selbsterklärendem Getöse im Schleifeninneren programmiert hatte, was ein sehr erfahrener Programmierer sah und direkt in das for() hineinprogrammiert hatte. 5 Zeilen Code gespart, dafür 5 Zeilen Kommentar geschrieben, der erklärte, was die Schleife eigentlich macht.
paedubucher hat geschrieben:

Code: Alles auswählen

public static boolean isLeap(int year) {
	return year % 4 == 0 && (year % 100 != 0 || year % 400 == 0);
}
Das ist doch für jeden Programmierer, der zumindest den Modulo-Operator kennt, sofort begreifbar. Als C-Programmierer würde man da noch die überflüssigen "== 0" und "!= 0" wegoptimieren.

Zur besseren Lesbarkeit drösel ich solche Konstrukte lieber in einzelne if-Statements auf, kommentiere die und lasse den Compiler die möglichen Optimierungen vornehmen.

Benutzeravatar
Meillo
Moderator
Beiträge: 8782
Registriert: 21.06.2005 14:55:06
Wohnort: Balmora
Kontaktdaten:

Re: Schaltjahr: "sauberer" Code

Beitrag von Meillo » 30.11.2016 09:36:05

seep hat geschrieben: Als C-Programmierer würde man da noch die überflüssigen "== 0" und "!= 0" wegoptimieren.
Wie wuerdest du das machen? Sind dir Klammern lieber? Und was denkst du ueber die Frage, ob sich durch die damit eingefuehrte Negation (d.h. mit Ausrufezeichen ist es ganzzahlig teilbar) die natuerliche Verstaendlichkeit des Ausdrucks erschwert?

Ich frage auch deshalb, weil ich bei dieser Art von Optimierung schonmal auf die Schnauze gefallen bin: http://marmaro.de/rem/texte/fizzbuzz
Use ed once in a while!

Benutzeravatar
MSfree
Beiträge: 10686
Registriert: 25.09.2007 19:59:30

Re: Schaltjahr: "sauberer" Code

Beitrag von MSfree » 30.11.2016 09:39:08

seep hat geschrieben:Als C-Programmierer würde man da noch die überflüssigen "== 0" und "!= 0" wegoptimieren.
Moderne Compiler generieren dann aber gerne Warnungen.

Benutzeravatar
seep
Beiträge: 544
Registriert: 31.10.2004 14:21:08
Lizenz eigener Beiträge: GNU Free Documentation License
Wohnort: HSK

Re: Schaltjahr: "sauberer" Code

Beitrag von seep » 30.11.2016 10:43:09

Meillo hat geschrieben:
seep hat geschrieben: Als C-Programmierer würde man da noch die überflüssigen "== 0" und "!= 0" wegoptimieren.
Wie wuerdest du das machen? Sind dir Klammern lieber? Und was denkst du ueber die Frage, ob sich durch die damit eingefuehrte Negation (d.h. mit Ausrufezeichen ist es ganzzahlig teilbar) die natuerliche Verstaendlichkeit des Ausdrucks erschwert?
Ob ein "year % 4 == 0" lesbarer ist als ein "!(year % 4)" sei mal dahingestellt, da wird jeder seine eigenen Vorlieben haben. Klammern sind mir in jedem Fall sehr lieb, ich setze lieber zuviele als zuwenige, sprich lieber ein "(year % 4 == 0) && (...)" als ein "year % 4 == 0 && ...". Und bevor man es dem Compiler überlässt, ob && höher priorisiert wird als || dann halt noch einmal mehr klammern.

Benutzeravatar
Meillo
Moderator
Beiträge: 8782
Registriert: 21.06.2005 14:55:06
Wohnort: Balmora
Kontaktdaten:

Re: Schaltjahr: "sauberer" Code

Beitrag von Meillo » 30.11.2016 11:18:44

seep hat geschrieben: Ob ein "year % 4 == 0" lesbarer ist als ein "!(year % 4)" sei mal dahingestellt, da wird jeder seine eigenen Vorlieben haben.
Meiner Meinung nach ist halt gerade das die entscheidende Frage: Ist es nur eine Sache der Vorliebe oder ist eine der beiden Varianten tatsaechlich besser? Natuerlich ist diese Frage schwer konkret zu packen und fundierte und verstaendliche Ergebnisse erreicht man auch nicht so einfach (meist laeuft es auf das Sammeln von Beispielen bei denen bestimmte Konstrukte zu Bugs gefuehrt haben oder missverstanden wurden raus), aber das ist halt eines meiner wichtigsten Interessensgebiete in der Informatik. ;-) ... und ich bin nicht alleine damit: http://www.paulgraham.com/taste.html

<Nachtrag>
Das ist der hierfuer relevanteste Ausschnitt des Aufsatzes:
If there is such a thing as beauty, we need to be able to recognize it. We need good taste to make good things. Instead of treating beauty as an airy abstraction, to be either blathered about or avoided depending on how one feels about airy abstractions, let's try considering it as a practical question: how do you make good stuff?



If you mention taste nowadays, a lot of people will tell you that "taste is subjective." They believe this because it really feels that way to them. When they like something, they have no idea why. It could be because it's beautiful, or because their mother had one, or because they saw a movie star with one in a magazine, or because they know it's expensive. Their thoughts are a tangle of unexamined impulses.

Most of us are encouraged, as children, to leave this tangle unexamined. If you make fun of your little brother for coloring people green in his coloring book, your mother is likely to tell you something like "you like to do it your way and he likes to do it his way."

Your mother at this point is not trying to teach you important truths about aesthetics. She's trying to get the two of you to stop bickering.

Like many of the half-truths adults tell us, this one contradicts other things they tell us. After dinning into you that taste is merely a matter of personal preference, they take you to the museum and tell you that you should pay attention because Leonardo is a great artist.

What goes through the kid's head at this point? What does he think "great artist" means? After having been told for years that everyone just likes to do things their own way, he is unlikely to head straight for the conclusion that a great artist is someone whose work is better than the others'. A far more likely theory, in his Ptolemaic model of the universe, is that a great artist is something that's good for you, like broccoli, because someone said so in a book.



Saying that taste is just personal preference is a good way to prevent disputes. The trouble is, it's not true. You feel this when you start to design things.
</Nachtrag>

Und bevor man es dem Compiler überlässt, ob && höher priorisiert wird als || dann halt noch einmal mehr klammern.
Wenn ich mir erlauben darf, hier zu korrigieren: ``ob'' ist das falsche Wort, denn (zumindest bei C) ist klar definiert *dass* && eine hoehere Praezedenz hat als ||. Dass man dieses Wissen aber nicht unbedingt voraussetzen kann und dass in diesen Fallen Klammern meist oder vielleicht auch immer trotzdem sinnvoll sind, dem kann ich durchaus zustimmen.
Use ed once in a while!

Benutzeravatar
seep
Beiträge: 544
Registriert: 31.10.2004 14:21:08
Lizenz eigener Beiträge: GNU Free Documentation License
Wohnort: HSK

Re: Schaltjahr: "sauberer" Code

Beitrag von seep » 30.11.2016 14:58:10

Meillo hat geschrieben:
seep hat geschrieben: Ob ein "year % 4 == 0" lesbarer ist als ein "!(year % 4)" sei mal dahingestellt, da wird jeder seine eigenen Vorlieben haben.
Meiner Meinung nach ist halt gerade das die entscheidende Frage: Ist es nur eine Sache der Vorliebe oder ist eine der beiden Varianten tatsaechlich besser?
Aus meiner Sicht eine Frage der Perspektive bzw. Fragestellung. Frage ich mich "beim Teilen ist der Rest 0?", werde ich "== 0" bevorzugen. Frage ich mich "kein Rest?", wähle ich das !(...)". Ob der Compiler da in einem Fall besser optimieren kann und ein paar Taktzyklen zu sparen hilft, interessiert mich erst dann, wenn es auch darauf ankommt.
Meillo hat geschrieben:Wenn ich mir erlauben darf, hier zu korrigieren: ``ob'' ist das falsche Wort, denn (zumindest bei C) ist klar definiert *dass* && eine hoehere Praezedenz hat als ||. Dass man dieses Wissen aber nicht unbedingt voraussetzen kann und dass in diesen Fallen Klammern meist oder vielleicht auch immer trotzdem sinnvoll sind, dem kann ich durchaus zustimmen.
Das ist soweit korrekt. Und wenn man von morgens bis abends über das Jahr hinweg ausschließlich in einer Sprache programmiere, dann weiß ich das auch. Ich weiß aber auch, dass die Punkt-vor-Strichrechnung gilt und erwische immer zielsicher immer genau den Taschenrechner, der aus 1+2x3 trotzdem eine 9 errechnet, will sagen, was weiß ich denn, ob Perl und PHP und Python und Python und Java und hassenichgesehen && und || in all ihren Releases genauso wie C abarbeiten oder nicht. Klammern können da für Klarheit schaffen, nicht nur optisch. :D

Noch kurz ein Buchtipp, ich habe mich köstlich amüsiert, echt lesenswert, und ich habe mich oft ertappt aber auch bestätigt gesehen: https://www.amazon.de/Weniger-schlecht- ... 3897215675

Benutzeravatar
Meillo
Moderator
Beiträge: 8782
Registriert: 21.06.2005 14:55:06
Wohnort: Balmora
Kontaktdaten:

Re: Schaltjahr: "sauberer" Code

Beitrag von Meillo » 01.12.2016 09:44:00

seep hat geschrieben:
Meillo hat geschrieben:
seep hat geschrieben: Ob ein "year % 4 == 0" lesbarer ist als ein "!(year % 4)" sei mal dahingestellt, da wird jeder seine eigenen Vorlieben haben.
Meiner Meinung nach ist halt gerade das die entscheidende Frage: Ist es nur eine Sache der Vorliebe oder ist eine der beiden Varianten tatsaechlich besser?
Aus meiner Sicht eine Frage der Perspektive bzw. Fragestellung. Frage ich mich "beim Teilen ist der Rest 0?", werde ich "== 0" bevorzugen. Frage ich mich "kein Rest?", wähle ich das !(...)".
Danke fuer die Erklaerung deiner Sichtweise. Die finde ich sehr wichtig, weil sie verstaendlich macht *wieso* du das so schreibst und dass du das als Idiom ansiehst.
Meillo hat geschrieben:Wenn ich mir erlauben darf, hier zu korrigieren: ``ob'' ist das falsche Wort, denn (zumindest bei C) ist klar definiert *dass* && eine hoehere Praezedenz hat als ||. Dass man dieses Wissen aber nicht unbedingt voraussetzen kann und dass in diesen Fallen Klammern meist oder vielleicht auch immer trotzdem sinnvoll sind, dem kann ich durchaus zustimmen.
Das ist soweit korrekt. Und wenn man von morgens bis abends über das Jahr hinweg ausschließlich in einer Sprache programmiere, dann weiß ich das auch. Ich weiß aber auch, dass die Punkt-vor-Strichrechnung gilt und erwische immer zielsicher immer genau den Taschenrechner, der aus 1+2x3 trotzdem eine 9 errechnet, will sagen, was weiß ich denn, ob Perl und PHP und Python und Python und Java und hassenichgesehen && und || in all ihren Releases genauso wie C abarbeiten oder nicht. Klammern können da für Klarheit schaffen, nicht nur optisch. :D
Ich verstehe was du meinst, habe aber eine etwas andere Sicht darauf. Ich vermute, dass alle Sprachen, die die Operatoren && und || kennen, ihnen die gleiche Praezendez-Reihenfolge geben wie in C. (Zumindest in Python, Perl, PHP, Ruby, Java, C++ und JS habe ich es geprueft. Gegenbeispiele willkommen!) Und das ist auch gut so, denn es ist ein Zeichen von Konsistenz und Verlaesslichkeit. Gerade diese Aspekte sind mir wichtig. Gute Sprachen bieten diese Verlaesslichkeit, die man auch Principle of Least Surprise (POLS) nennen kann. Vielleicht mache ich es mir ja auch nur einfach bzw. bin ich in der gluecklichen Lage, hauptsaechlich Sprachen zu verwenden, die qualitativ so gut sind, dass man sich auf sie verlassen kann. ;-)

Insgesamt finde ich gerade das einen der wichtigsten Aspekte von Programmiersprachen (und von Software allgemein), dass der Programmierer bzw. Anwender weiss, auf was er sich verlassen kann und auf was nicht. Wenn Systeme es schaffen, dies zu vermitteln, dann haben sie viel erreicht.
Noch kurz ein Buchtipp, ich habe mich köstlich amüsiert, echt lesenswert, und ich habe mich oft ertappt aber auch bestätigt gesehen: https://www.amazon.de/Weniger-schlecht- ... 3897215675
Ich kenne das Buch nicht (und mir persoenlich ist es auch etwas zu neu ;-) ), aber der Titel hoert sich so an als ob darin manch sinnvoller Gedanke zu finden sein koennte. Ob es nun eines der besseren Buecher zu diesem Thema ist oder nicht, wichtig ist, dass es ein Buch zum Thema Code-Qualitaet und Entwicklungs-Qualitaet ist, und Literatur in diese Richtung sollte jeder Programmierer lesen.
Use ed once in a while!

owl102

Re: Schaltjahr: "sauberer" Code

Beitrag von owl102 » 02.12.2016 09:17:46

Meillo hat geschrieben:Wenn ich mir erlauben darf, hier zu korrigieren: ``ob'' ist das falsche Wort, denn (zumindest bei C) ist klar definiert *dass* && eine hoehere Praezedenz hat als ||. Dass man dieses Wissen aber nicht unbedingt voraussetzen kann
Widerspruch! Doch! Ich setze unbedingt voraus, daß jemand, der in C kodiert, sein Handwerkszeug beherrscht.

Und: Wer beim Kodieren unsicher ist, soll eben klammern. Wer beim Lesen unsicher ist, soll nachlesen und was dazulernen.

Antworten