Wieviel LOC pro Tag?
-
Citizen42 schrieb:
Das habe ich sogar früher mal auf dem Amiga und auch jetzt werde ich dahin gehend mal einige Versuche auf dem PC unternehmen. Aber eine Hochsprache ist da dann doch schon komfortabler und ich traue den Compilern auch schönen Maschinencode zu, aber zum reinen Verständnis ist Assembler wirklich toll, jedenfalls der auf dem 680000. Ich weiß nicht wie der x86 Assembler so ist, aber da werde ich mich auch noch mit beschäftigen.
Das war von mir nicht wirklich ernst gemeint. Natuerlich bist Du mit Assembler naeher an der eigentlichen Maschine dran, aber Programmieren hat nicht nur etwas mit einem Low-Level Verstaendnis eines Computers zu tun. Jenseits davon lernst Du das selbst mit Assembler nicht wirklich. Natuerlich lernst Du mit Assembler, was zum Beispiel Register sind, Aber mit Dingen wie Pipelining, der Speicherhierarchie und so weiter kriegst Du es auch nicht direkt zu tun. Wenn Du fuer Deine Programmiertaetigkeit ein solches Verstaendnis von Computern benoetigst, dann solltest Du neben dem Erlernen der Programmiersprache ein Buch wie zum Beispiel das da durcharbeiten:
Computer Architecture | ISBN: 012383872X
-
Danke für den Buchtipp. Benötigen tue ich solches Wissen nicht. Das ist wie früher beim Democoding(nix bekanntes) auf dem Amiga einfach nur Hobbykram. Assembler war halt die einzige Sprache, mit der ich wirklich was mit dem Computer machen konnte. C + Libs waren damals grottenlahm und Basic naja nochmal hundert Stufen lahmer. Mir ist schon klar, dass das heute alles anders ist mit Multicore, der Pipeline und den Caches. Damals war Assembler halt nichts besonderes. Das haben eigentlich alle programmiert und es wurden auch viele Bücher und Artikel in Zeitschriften darüber geschrieben. Internet gab es ja nicht, also musste man selbst die Fehler finden. Schwer war das damals überhaupt nicht, wenn man einmal den Dreh raus hatte. Waren ja auch nur sehr wenige Befehle mit sehr wenigen Fragezeichen. Man musste halt geschickt auf die Register aufteilen und den Rest auf den Stack packen. Die Customchips kennen und wissen wie man die ansteuert, musste man auch, aber so viele waren das ja auch nicht. Und das schöne daran, so gut wie jeder hatte dieselbe Hardware, es gab einfach nie irgendwelche Sonderfälle zu beachten.
Aber ich gerate schon wieder ins Schwärmen, wie einfach das alles damals war. Aber nun probieren ich es mal mit C++ und OOP, an das ich mich erst noch gewöhnen muss, es sind aber tolle Pattern dafür vorhanden, wirklich beeindruckend.
Also alles nur ein Versuch eines alten Mannes mal wieder etwas zu programmieren, mehr nicht, reines Hobby.
-
Citizen42 schrieb:
aber zum reinen Verständnis ist Assembler wirklich toll, jedenfalls der auf dem 680000.
und der auf dem 800386 erstmal
-
Citizen42 schrieb:
@volkard, xin:
Ihr solltet mal ein Buch schreiben "C++ im Alltag" oder so.Das hat SeppJ in seinem letzten Posting schon. Es ist wirklich Handarbeit, Erfahrung sammeln.
Ich habe 1996 mit C++ angefangen, davor C, davor Assembler. Insgesamt programmiere ich fast seit 30 Jahren. Wie ich schon volkards Geschichte korrigierte, ich habe vorrangig aus Fehlern gelernt und wenn man ein paar Stunden über Assemblerquellcode gehangen hat, um herauszufinden, warum gelegentlich der Computer abschmiert, dann versteht man Abläufe irgendwann schnell bzw. entwickelt da wirklich ein Gefühl für, wo man mehr überlegen muss und was einem einfach so aus den Fingern in die Tastatur fließt, weil man das immer so macht.Citizen42 schrieb:
Bücher die den Syntax und die Standardlib + Tricks und Rezepte runter beten gibt es genug, aber Bücher die so kleine Projekte von A-Z mit allem drumherum und ein wenig Geschichte dazu erzählen gibt es meines Wissen gar nicht.
Die Geschichte ist oftmals sehr frustrierend.
Citizen42 schrieb:
Noch eine Frage, wenn ihr kaum debuggt, dann macht ihr auch kaum logische Fehler?
Das würde ich so nicht sagen. Ich mache auch seit 10 Jahren regelmäßig alle 2 Jahre folgenden Anfänger-Fehler:
if( cond1 ) if( cond2 ) OneAndTwo(); else NotOne();
Man startet das Programm, es funktioniert nicht, man sieht den Code, haut sich auf die Stirn, und korrigiert es:
if( !cond1 ) NotOne(); else if( cond2 ) OneAndTwo();
Oftmals sieht man die Ausgabe und weiß, warum kommt, was kommt, weil damit das kommt, was ausgegeben wird, muss der Fehler da und da liegen. Und dann guckt man an die Stelle und meistens sieht man schnell, wo sich der Algorithmus verläuft, um das Ergebnis zu liefern, dass man halt bekommen hat.
Man testet das ganze ja, weiß also was man reingibt und wie der zu testende Algorithmus daraus ein Ergebnis formen soll, was dann aber halt nicht kommt.Das sehe ich aber nicht als "Debuggen", das ist Alltag beim Entwickeln.
Debuggen fängt bei mir da an, wo man lange sucht, bzw. wo man einen Quellcode in die Versionsverwaltung entlassen hat und ein Kunde oder anderer Entwickler in einen freigegebenen Quellcode Fehler findet.
Manchmal sitzt man auch einfach vor einem Quellcode und findet ihn "nicht schön". Das ist oft erstmal mehr ein Gefühl, aber dann guckt man sich das genau an und merkt, dass das besser geht. Es ist einfach nicht so, wie man das als "schön" empfindet, wie man das immer macht, weil man weiß dass der "schöne" Quellcode in allen Fällen funktioniert.
Programmieren ist oftmals das richtige Zusammenstellen von Legobausteinen, also Code-Schnipseln. Und je länger man programmiert, desto mehr "schöne" Codeschnipsel kennt man und umso größer werden sie.
Es ist halt Erfahrung.Citizen42 schrieb:
Ich, als Anfänger, tappe von einem Fettnäpfchen ins nächste. Ich verbringe mehr Zeit auf Seiten wie StackOverflow, in Büchern, Tuts...
Dann machst Du es genau richtig. Der Rest ist "einfach" nur Erfahrung: Handarbeit.
Citizen42 schrieb:
Und Java, es tut mir Leid das sagen zu müssen, ist in meinen Augen auch nicht die richtige Sprache um das Programmieren zu lernen, da eben viele Aspekte des Programmierens eines Computers vor dem Anwender versteckt werden. Zumal ich Java nach wie vor lahm finde.
Java ist nicht unbedingt lahm, wenn das Problem groß genug ist und genug Speicher da ist. Java ist spezialisierter als C++. Wenn man also ein Problem hat, für das Java spezialisiert ist, sollte man sich durchaus mal mit C# beschäftigen
Ich halte C allerdings auch für besser, wenn es darum geht programmieren zu lernen.https://www.proggen.org/doku.php?id=start:cppjava
Citizen42 schrieb:
aber zum reinen Verständnis ist Assembler wirklich toll, jedenfalls der auf dem 680000. Ich weiß nicht wie der x86 Assembler so ist, aber da werde ich mich auch noch mit beschäftigen.
Warum nicht... aber wenn man einen 68000er programmiert hat, dann ist ein Intel schon eine traurige Nummer, was die Programmierung angeht.
-
volkard schrieb:
Mit 30 biste gut dabei.
Ist nicht dein Ernst - wenn das so ist dann steige ich auch wieder in das Berufsleben ein.
-
EOP schrieb:
volkard schrieb:
Mit 30 biste gut dabei.
Ist nicht dein Ernst - wenn das so ist dann steige ich auch wieder in das Berufsleben ein.
Üblicherweise wird mit 10 LOC pro Arbeitstag gerechnet. Mit 30 ist man wirklich ziemlich gut dabei.
-
Xin schrieb:
Das würde ich so nicht sagen. Ich mache auch seit 10 Jahren regelmäßig alle 2 Jahre folgenden Anfänger-Fehler:
if( cond1 ) if( cond2 ) OneAndTwo(); else NotOne();
Du glaubst nicht, wie viele Fehler dieser Art ich schon direkt während des Fehlermachens gefunden habe, einfach weil mein Editor automatisch den Code einrückt. So ein Gerät sollte Pflicht sein.
Auch beliebt und durch gutes Arbeitsgerät direkt vermeidbar sind einfache Tippfehler. Semikolon vergessen, Klammern passen nicht, und so weiter. Vielleicht gehört in jedes Programmieranfängerlehrbuch ein Kapitel über gängige Editoren und wie man sie produktiv einsetzt. Das sieht man ja schon hier im Forum, wie viele Beiträge von Anfängern man direkt beantworten kann, indem man ihren Code einfach mal von einem Editor automatisch einrücken lässt.
Und ein Kapitel über gängige Compiler (oder Compiler/IDE-Gespanne) und wie man Warnungen aktiviert.Ich glaube kaum etwas anderes hat meine Produktivität so sehr gesteigert, wie ein guter Editor und Compilerwarnungen. Denn auch wenn man als erfahrener Programmierer all diese Fehler kennt und bei der Fehlersuche sofort sieht, so macht man sie doch trotzdem immer mal wieder versehentlich. Es bringt so viel, wenn die Notwendigkeit, diese Arten von Fehlern zu suchen, gänzlich entfällt.
-
SeppJ schrieb:
Xin schrieb:
Das würde ich so nicht sagen. Ich mache auch seit 10 Jahren regelmäßig alle 2 Jahre folgenden Anfänger-Fehler:
if( cond1 ) if( cond2 ) OneAndTwo(); else NotOne();
Du glaubst nicht, wie viele Fehler dieser Art ich schon direkt während des Fehlermachens gefunden habe, einfach weil mein Editor automatisch den Code einrückt. So ein Gerät sollte Pflicht sein.
Das ist die eine Perspektive. Ich arbeite mit Visual Studio, CodeBlocks, CodeLite, Kate und TextWrangler. Letztere sind eigentlich eher nur Editoren.
Die Programmierung mit einfachen Editoren hilft mir Methodennamen zu optimieren. Nachschlagen kostet Zeit; um Zeit zu sparen, achte ich darauf, Methodennamen zu vereinheitlichen. Wenn ich nachschlagen muss, ist der Methodenname fraglich.Keiner formatiert meinen Code oder rückt ihn ein. Das tat Eclipse. Ich habe es gehasst, wenn ich meinen Code optisch ausgerichtet habe, so dass Ähnlichkeiten sofort ins Auge fielen und der Code dann automatisch so angepasst wurde, dass man den Algorithmus aus der Formatierung nicht mehr lesen konnte.
Ich verzichte auf Diskussionen mit meinem Computer, wann mein Code richtig formatiert ist. Ich hasse es, wenn mein Computer besser wissen will, was ich tun will. Ich hasse auch Autokorrektur, weil es aus einem Tippfehler ein komplett anderes Wort macht - ich also noch mehr korrigieren muss. Computer sollten nicht intelligenter tun, als sie sind.
Den beschriebenen Fehler mache ich zuverlässig alle 2 Jahre mal, er kostet mich in der Regel kaum mehr als 5 Minuten, weil ich ihn sofort sehe, wenn ich nach Fehlern suche und den fraglichen Code überfliege. Dieses fehlerhafte Konstrukt programmiere ich nicht, sondern es entsteht, wenn ich einen solchen Block ändere und dabei abgelenkt werde.
SeppJ schrieb:
Auch beliebt und durch gutes Arbeitsgerät direkt vermeidbar sind einfache Tippfehler. Semikolon vergessen, Klammern passen nicht, und so weiter.
Fehler, die man nicht kompilieren kann sind ja Kleinkram.
Darum liebe ich Const-Correctness: Man kann es nicht kompilieren, wenn man nicht sauber arbeitet.SeppJ schrieb:
Und ein Kapitel über gängige Compiler (oder Compiler/IDE-Gespanne) und wie man Warnungen aktiviert.
Das entspricht so auch meiner Erfahrung und deswegen gibt's das bei uns auch.
SeppJ schrieb:
Ich glaube kaum etwas anderes hat meine Produktivität so sehr gesteigert, wie ein guter Editor und Compilerwarnungen.
Ich habe auf dem SAS/C mit C angefangen. Der Compiler hatte so gute Fehlermeldungen, dass ich mich oft genug gefragt habe, warum er den Fehler nicht gleich selbst behebt.
Gute Fehlermeldungen sind also möglich.
Viele lernen mit Visual Studio. Visual C++ liefert gelegentlich Fehlermeldungen, die ich selbst nach der Lektüre der Hilfsseiten von Microsoft nicht verstehe und die Fehlermeldung auch nicht nachvollziehen kann, wenn ich den Fehler gefunden habe.SeppJ schrieb:
Denn auch wenn man als erfahrener Programmierer all diese Fehler kennt und bei der Fehlersuche sofort sieht, so macht man sie doch trotzdem immer mal wieder versehentlich. Es bringt so viel, wenn die Notwendigkeit, diese Arten von Fehlern zu suchen, gänzlich entfällt.
Ich klicke meistens nur auf die Zeile und gucke mir die Codestelle an. Das geht schneller, als die Fehlermeldung zu lesen. In 95% der Fälle reicht mir das.
-
SeppJ schrieb:
Klammern passen nicht, und so weiter.
Deshalb hab ich (nicht nur) heute in einem anderen thread gesagt: "Formatier das so, daß man es auch lesen und verstehen kann". So oder so ähnlich.
Zurück zun Thema.
10 - 30 LOC/Tag
Das wären etwa zwischen 1 und 4 Zeilen/StdWenn ich hier nicht nur rundrum verarscht werde dann fange ich wieder an zu arbeiten.
Da schaffe ich ja sogar in ASM manchmal 2 Zeilen/Std.mov eax, ecx
und jetzt ne Std. frei?
-
EOP schrieb:
Da schaffe ich ja sogar in ASM manchmal 2 Zeilen/Std.
mov eax, ecx
und jetzt ne Std. frei?
Es gibt eben solche Zeilen und es gibt andere Zeilen. In Assembler sind eben 80-90% des Codes Teile, die irgendwelche Konzepte umsetzen, die in anderen Sprachen nicht einmal eine einzelne Zeile wert sind. volkard meint sicherlich nicht 30 Zeilen Boilerplatecode, sondern 5-10 Codestücke, die insgesamt wirklich was richtig schwieriges umsetzen und dann in typischen Sprachen eben jeweils 3-6 Zeilen lang sind. Oder in Assembler dann eben 10-20 Zeilen, dann muss man eben mehr LOC/h schaffen. Deswegen ist das ja auch eine dumme Metrik (neben anderen Gründen). Problemlösungen pro Zeit wäre besser.
-
LOC ist eine sinnlos dumme Metrik.
Es hängt einfach davon ab was dein Job ist. Ich warte zB eine alte Software - da sind Änderungen 70% der Zeit den Code verstehen und die passende Stelle für die Änderung suchen, dann die Zeile ausbessern und 30% Testen ob noch alles läuft.
Da schreibe ich vielleicht 100 Zeilen im Jahr (neue Features die alle heiligen Zeiten mal kommen ausgenommen).
In der Arbeit entwicklen wir viele Webseiten und WebApps für Kunden. Alleine der Boilerplate für diese Projekte sind viele hundert Zeilen. Da schreiben die Entwickler sicher mehrere Tausend Zeilen in der Woche wenn die Entwicklung startet und es wird graduell weniger.
Ein neues Feature für eine Software sind sehr viele Zeilen. Einen Bug fixen sind idR keine neuen Zeilen und Refactoring entfernt sogar Zeilen.
Deshalb weiß man, sobald Jemand von LOCs zu reden anfängt was man von ihm halten muss.
-
Xin schrieb:
Ich mache meine Bugs aber lieber selbst. Darin bin ich aber schlecht, wenn ich im Jahr zwei Bugs bekomme, die ich selbst verschuldet habe, ist das viel.
Den Satz verstehe ich nicht ganz. Das erscheint mir zu wenig.
Was verstehst du unter einem Fehler?
Es gibt ja diverse Arten von Fehlern. Von einem Designfehler angefangen zu einfachen Abstürzen, falsche Berechnungen, Portabilitätsfehlern, Compiler Fehler, inkonsistentem Verhalten oder auch algorithmische Fehler,...
// WinAPI Beispiel zu Portabilitätsfehler: // Ich öffne einen "Datei speichern..." Dialog ohne die Bedeutung von WINVER verstanden zu haben. OPENFILENAMEW ofn = {0}; ofn.lStructSize = 54; // Hinter lStructSize steckt ein wenig mehr als nur die Größe des Structs. #ifndef OFN_EXPLORER #define OFN_EXPLORER 0x00080000 // Auch ein Klassiker der WinAPI Programmierung #endif ofn.Flags = OFN_OFN_EXPLORER; GetSaveFileName(&ofn) // Kleiner Flüchtigskeitsfehler std::string FileName = "C:\Benutzer\Kaiser Wilhelm\Info.doc"; std::string CmdLine = std::string("wordpad.exe") + FileName; system(CmdLine.c_str());
Das testen ist bei mir zu einer Phase geworden. D.h. ich teste nicht in dem ich hingehe und es im Debugger teste. Ich nutze manuelle oder automatische Testreihen, nutze Blackbox Tests, teste Annahmen mit Hilfe von Assertions,Test auf unterschiedlichen Plattformen, schaue wie sich das Program verhält wenn die Annahmen über die Eingaben nicht erfüllt sind,...
-
Shade Of Mine schrieb:
LOC ist eine sinnlos dumme Metrik.
Das Problem ist auch, dass bei einer Beurteilung nach LOC die Entwicklung sich anpasst und es schnell zu einem Copy-Paste-Modify Vorgehensmodell kommt. Und das ist ja bekanntlich nicht sonderlich gut und gleicht einem Schneeballsystem. Solange das Ganze noch junfräulich ist, sieht alles gut aus. Aber die letzten Entwickler im System haben die Arschkarte gezogen.
-
EOP schrieb:
10 - 30 LOC/Tag
Das wären etwa zwischen 1 und 4 Zeilen/StdWenn ich hier nicht nur rundrum verarscht werde dann fange ich wieder an zu arbeiten.
Meine "Lieblingsprogrammiersprache"...
public class HelloWorld { // 2 Fehlermöglichkeiten: public vergessen, Hello World falsch geschrieben public static void main(String[ ] args) // public, static, main, Argumente, kann alles falsch sein, tut aber nix. { // Ausgabe Hello World! System.out.println("Hello World!"); // <- eine Zeile Code. } }
So ein Hello World ist wie ein Roland Emerich-Film: Hier gibt's viel zu gucken, aber unglaublich wenig Handlung.
Der Code deckt sich mit dem Hello World aus Python.
print "Hello World\n"
Beides produzieren die gleiche Ausgabe, beide 1 LOC, aber Python hat dafür keinen Boilerplate.
EOP schrieb:
Da schaffe ich ja sogar in ASM manchmal 2 Zeilen/Std.
mov eax, ecx
und jetzt ne Std. frei?
hehehe, ja, wenn Du garantieren kannst, dass sie zwei Zeilen auf Dauer korrekt sind.
Dafür brauchst Du vielleicht einen Test. Und wenn Du dann nach einer Stunde weiterschreibst und feststellst, dass eine von den beiden Zeilen doch nicht zum Algorithmus passt, dann musst du die Zeile ändern und hast in der nächsten Stunde schon 50% mehr Arbeit zu leisten.
Zwischendurch Recherchieren, was Du eigentlich entwickeln sollst, Tests entwickeln, das über 10 Jahre warten - kommen am Schluss 10 Zeilen raus.
Es sind eben nicht die hunderte Zeilen, die sich mancher vorstellt.Die Chance in Assembler aufwendig zu debuggende Fehler zu machen ist gegeben. Ich habe auch Programme mit GUI in Assembler gemacht, ich bin mir da wirklich für nichts zu schade. Aber ich benutzte viele Macros. Gutes Assembler ist nicht wirklich weit von C entfernt. Aber wenn Du einen echten Bug hast, dann wirst Du tierisch ausgebremst und das reduziert Deine Ausbeute. Und so stehst Du dann am Ende doch mit relativ wenig Zeilen da. Die Macros müssen ja auch erstmal fehlerfrei sein. Und ein if oder while oder strlen in C ist relativ gut abgetestet, wie auch ein a = b+1; einfach praktischer ist Expressions in ASM-Manier runterzubeten.
Shade Of Mine schrieb:
LOC ist eine sinnlos dumme Metrik.
Hmm... jain. Sie ist dumm um die Produktivität zu messen, aber ein Indiz um Komplexität und Aufwand einer Software zu messen. LOC ergibt keinen Sinn, wenn man nur 3 Bildschirmseiten oder einen Algorithmus misst, aber als Maß für eine Software durchaus. Gute und schlechte Programmierer gleichen sich bezogen auf die LOC ja aus, es kommt ein Maß für einen Norm-Programmierer raus.
Nun kann man abschätzen, wieviel Normprogrammierer-Jahre man für ein Problem braucht, sofern man das Problem in der Größe ungefähr einordnen kann.Shade Of Mine schrieb:
Da schreibe ich vielleicht 100 Zeilen im Jahr (neue Features die alle heiligen Zeiten mal kommen ausgenommen).
Ich habe das mal mit meinem privaten Projekt durchgerechnet. Ich bin unglaublich produktiv, obwohl es ja nur in der Freizeit stattfindet.
Mit Deiner beruflichen Produktivität gleicht sich das ja wieder ausIch bin im Beruf äußerst produktiv. Ein von mir erzeugtes .cpp hat 43000 Zeilen, der dazugehörige Header mit inline-Funktionalität 57000. Macht 100000 Lines, abzüglich Deklaratives. Sagen wir 50000 LOC. Alleine die 2 Dateien ergeben dann 200LOC/d. Und die laufen sehr zuverlässig.
Wenn man jetzt noch verschweigt, dass die beiden Dateien von einem Python-Skript mit 1300 Zeilen (5,2 LOC/d) erzeugt werden, klingt das richtig gut.
Verschweigt man das nicht, bleibt mir vorrangig die Erweiterungen zu den generierten Klassen mit 1800 Zeilen (7,2 LOC) zusätzlich zu besagtem Python-Skript, womit ich auf 12,4 LOC/d komme. Das Debuggen bringt ja in der Regel keine neuen Zeilen.Ich gleiche meine privaten LOC/d beruflich also auch wieder aus. Ganz einfach, weil ich im Beruf in einem großen Projekt arbeite und privat im Vergleich noch im Aufbau bin.
Shade Of Mine schrieb:
Alleine der Boilerplate für diese Projekte sind viele hundert Zeilen.
Boilerplate zählt nicht.
Shade Of Mine schrieb:
Ein neues Feature für eine Software sind sehr viele Zeilen. Einen Bug fixen sind idR keine neuen Zeilen und Refactoring entfernt sogar Zeilen.
Deshalb weiß man, sobald Jemand von LOCs zu reden anfängt was man von ihm halten muss.
Yepp... auf kurze Sicht gar nichts, auf sehr lange Sicht hat man ein Indiz, mehr nicht.
Bitte ein Bit schrieb:
Xin schrieb:
Ich mache meine Bugs aber lieber selbst. Darin bin ich aber schlecht, wenn ich im Jahr zwei Bugs bekomme, die ich selbst verschuldet habe, ist das viel.
Den Satz verstehe ich nicht ganz. Das erscheint mir zu wenig.
Was verstehst du unter einem Fehler?Einen Quellcode, den ich zur Verwendung von Kunden oder anderen Entwicklern freigegeben habe und der nicht tut, was ich beabsichtigt habe. Das landet bei uns in Bugzilla.
Da landen bei mir auch "Bugs", wo sich Kollegen meinen Code gegriffen haben, bevor ich ihn vorgestellt und zur Verwendung freigegeben und melden, dass ein Feature nicht funktioniert. Liegt das daran, dass ich das Feature noch gar nicht entwickelt habe, ist das für mich kein Bug. Ist das Feature noch in aktiver Entwicklung, ist das für mich kein Bug, sondern unfertig.
Anderes Beispiel: Ich schreibe einen Im- und Exporter für ein aufwendiges Datenformat - siehe 100kLoc generierter Code. Diese 700 Klassen, die dafür generiert werden, haben auch individuelle Aufgaben, die ich Stück für Stück nachreiche. Der Im- und Exporter ist aber bereits im Kunden-Einsatz.
Dann kommt der Kunde an und meldet "Diese Datei funktioniert nicht" und ich bekomme eine Bugmeldung. Das ist ein Bug, wenn etwas nicht einzulesen ist, obwohl ich das bereits fertig programmiert hatte (oder dachte, es wäre fertig). Es ist kein Bug, wenn ich bei einem "not yet implemented" lande. Wenn der Support mir nun 10 Bugs schreibt, weil 10 Dateien aus den gleichen Gründen nicht einzuladen sind... dann ist das 1 Bug - oder eben auch gar keiner, wenn der Grund "not yet implemented" ist. Aber dann habe ich wenigstens neue Testdateien, die ich nutze bevor ich die entsprechenden Code-Stellen für die Öffentlichkeit freigebe.Für einen Bug muss von mir in Code manifestierter Irrtum vorliegen. Ein Not-Yet-Implemented ist der Irrtum des Projektleiters, dass man bei Bugzilla nicht nur Bugs schreiben, sondern auch Feature-Requests formulieren kann. Ein Feature-Request ist aber eben kein Bug.
Bitte ein Bit schrieb:
Es gibt ja diverse Arten von Fehlern. Von einem Designfehler angefangen zu einfachen Abstürzen, falsche Berechnungen, Portabilitätsfehlern, Compiler Fehler, inkonsistentem Verhalten oder auch algorithmische Fehler,...
Alles ist Bug, wenn das Verhalten nicht meinem Wunsch entspricht, sobald ich den Code zur Nutzung freigegeben habe.
Bitte ein Bit schrieb:
// WinAPI Beispiel zu Portabilitätsfehler: // Ich öffne einen "Datei speichern..." Dialog ohne die Bedeutung von WINVER verstanden zu haben. OPENFILENAMEW ofn = {0}; ofn.lStructSize = 54; // Hinter lStructSize steckt ein wenig mehr als nur die Größe des Structs. #ifndef OFN_EXPLORER #define OFN_EXPLORER 0x00080000 // Auch ein Klassiker der WinAPI Programmierung #endif ofn.Flags = OFN_OFN_EXPLORER; GetSaveFileName(&ofn) // Kleiner Flüchtigskeitsfehler std::string FileName = "C:\Benutzer\Kaiser Wilhelm\Info.doc"; std::string CmdLine = std::string("wordpad.exe") + FileName; system(CmdLine.c_str());
Ich habe keine Ahnung von dem Klassiker der Windowsprogrammierung, ich vermute aber dringend, dass die OPENFILENAMEW nicht ausreichend initialisiert ist.
Ansonsten springt nur ins Auge, dass die Backslashs nicht escaped sind und der Name ohne Leerzeichen an "wordpad.exe" angeklebt wird. Welcher genau ist der Flüchtigkeitsfehler?
-
// WinAPI Beispiel zu Portabilitätsfehler: // Ich öffne einen "Datei speichern..." Dialog ohne die Bedeutung von WINVER verstanden zu haben. OPENFILENAMEW ofn = {0}; ofn.lStructSize = 54; // Hinter lStructSize steckt ein wenig mehr als nur die Größe des Structs. #ifndef OFN_EXPLORER #define OFN_EXPLORER 0x00080000 // Auch ein Klassiker der WinAPI Programmierung #endif ofn.Flags = OFN_OFN_EXPLORER; GetSaveFileName(&ofn)
Hast recht, das Struct ist nicht komplett ausgefüllt. Aber das Hauptproblem ist lStructSize und die eigentwillige Definition von OFN_EXPLORER. Der Kern dahinter ist das WINVER Präprozessorflag, welches angibt für welche Windows Version ich entwickle. In der WinAPI dürfte folgendes stehen, wobei ich aber von der WinAPI abweiche, da ich keine Lust habe das exakte Beispiel zu suchen. Es kommt nur auf die WINVER Geschichte an.
#if WINVER > 0x600 // Erst ab Windows 7 funktioniert die Explorer Ansicht #define OFN_EXPLORER 0x00080000 #endif typedef struct { //... #if WINVER > 0x600 // Erst ab Windows 7 haben wir zusätzliche Flags für die Steuerung der Anzeige. int ExFlags; // Liste von zusätzlichen Flags zur Steuerung des Dialogs #endif } OPENFILENAMEW;
Wenn ich ofn.lStructSize auf die maximale Größe von OPENFILENAMEW setze, und WINVER kleiner als 0x600 ist, provoziere ich einen Zugriff auf nicht initialisierten Bereich (ExFlags). Ich möchte ja, und das sagt der Code, Features von Win7 nutzen, obwohl ich nicht für Win7 entwickele sondern auch für WinXP!
std::string FileName = "C:\Benutzer\Kaiser Wilhelm\Info.doc"; std::string CmdLine = std::string("wordpad.exe") + FileName; system(CmdLine.c_str());
Erster Fehler, klar die fehlende doppelte Escape Sequenzen. Den zweiten Fehler erkennt man, wenn man CmdLine betrachtet:
wordpad.exe C:\Benutzer\Kaiser Wilhelm\Info.doc
-> Fehlermeldung von Wordpad: Kann Datei C:\Benutzer\Kaiser nicht öffnen!
-> Ein Leerzeichen auf der Kommandozeile ist ein Trenner für Argumente
-> wordpad.exe "C:\Benutzer\Kaiser Wilhelm\Info.doc"
-
William Henry Gates III schrieb:
Measuring programming progress by lines of code is like measuring aircraft building progress by weight.
-
dot schrieb:
William Henry Gates III schrieb:
Measuring programming progress by lines of code is like measuring aircraft building progress by weight.
Hmm... ist ein typischer Gates. Sieht erstmal gut aus und man fühlt sich genötigt zu nicken und zu sagen "Recht hat er!".
Aber man sollte nicht drüber nachdenken.Der Kitty Hawk Flyer wog etwa 275kg und flog mit einer Person Zuladung 59 Sekunden.
Eine Curtiss C-46R aus den 40ern wiegt 13.290 kg und hob maximal 12t.
Ein A330 wiegt 120t, mit maximaler Zuladung wiegt das Ding 250t.
Wenn man den A330 zerlegt, passt er in den Frachtraum einer Antonow An-225, die 175 t wiegt. Für die 130t Zuladung und Kerosin der A330 ist im Laderaum der Antonov auch noch Platz, maximal darf die Antonov 600t wiegen.Gewicht von Flugzeugen ist durchaus ein Maßstab für den Fortschritt im Flugzeugbau. Einer von vielen, aber durchaus ein bisher zuverlässiges Indiz. Je schwerer das Flugzeug, desto mehr Fracht.
Wie LOCs.
Die Wahrscheinlichkeit 600000kg mit einem 275kg Flugzeug zu transportieren ist in nächerer Zukunft wohl eher nicht gegeben. Ähnlich sieht es aus, Windows 3.11 (3000000loc = 5*600000loc) in (1375 Zeilen = 5*275 Zeilen) zu realisieren.
Mehr Zeilen sind also durchaus ein Indiz auf mehr Features und Fortschritt.Außer man vergleicht C mit DOS.
Um Windows 3.11 in einer Batch-Datei zu rufen, reicht auch eine Zeile.
-
Ach Xin du Schelm.
Gemeint ist natürlich dass mehr LOC bei gleichem Feature-Set nicht unbedingt ein Indikator für "gut" ist. Genau so wie bei Flugzeugen mehr Gewicht bei gleichem Feature-Set nicht unbedingt gut ist.
(Und mit Feature-Set meine ich natürlich alles, also auch Dinge wie "wie Sicher ist das Ding" bei Flugzeugen oder "wie viel Bugs hat das Ding" bei Software.)Natürlich ist auch das Programm mit den wenigsten LOC nicht das beste. Das Optimum liegt irgendwo mitten drin - aber erfahrungsgemäss näher am Minimum als am Durchschnitt.
-
Xin schrieb:
Shade Of Mine schrieb:
LOC ist eine sinnlos dumme Metrik.
Hmm... jain. Sie ist dumm um die Produktivität zu messen, aber ein Indiz um Komplexität und Aufwand einer Software zu messen.
Nein. LOC ist sinnlos und dumm. Nichts anderes. In Pascal habe ich mehr LOCs als in C. In Bash habe ich mehr LOCs als in Python.
Je nach Library gehen die LOCs rauf und runter. Verwende ich zB das Facebook SDK direkt, habe ich massig LOCs für simple Aufgaben, verwende ich die korrekt gekapselten Bundles, habe ich kaum LOCs.
LOCs sagen nichts aus.
LOC ergibt keinen Sinn, wenn man nur 3 Bildschirmseiten oder einen Algorithmus misst, aber als Maß für eine Software durchaus. Gute und schlechte Programmierer gleichen sich bezogen auf die LOC ja aus, es kommt ein Maß für einen Norm-Programmierer raus.
Nun kann man abschätzen, wieviel Normprogrammierer-Jahre man für ein Problem braucht, sofern man das Problem in der Größe ungefähr einordnen kann.Unterschiedliche Aufgaben produzieren unterschiedliche LOCs. Wir haben zB einen Guru bei uns, der kaum LOCs produziert, aber seine Zeilen sind eben die kompliziertesten.
Eine Zeile Code hat komplett unterschiedliche Komplexitäten. Man kann die nicht miteinander vergleichen.
Shade Of Mine schrieb:
Alleine der Boilerplate für diese Projekte sind viele hundert Zeilen.
Boilerplate zählt nicht.
Und was genau ist Boilerplate Code denn?
Da gibt es keine Definition. Ist eine Schleife Boilerplate? Was ist mit einer Klassendefinition?Du kannst hier natürlich wieder frei erfundene Metriken anwenden ob eine Zeile Code nun unter Boilerplate fällt oder nicht - aber das ist objektiv nicht möglich.
LOC ist eine Dumme Metrik. Nichts aber auch garnichts sagt sie aus. Nicht mal den Hauch eines Indikators. Und wie bereits gesagt, Jemand der LOCs für irgendetwas anderes als eine lustige Zahl ansieht, den kann ich nicht ernst nehmen. Sorry. Ich meine wir duellieren uns in der Arbeit auch mit wer die meisten Commits und die meisten LOCs bei einem Projekt gemacht hat, aber wir machen das aus Spaß, weil es lustig ist Zahlen zu vergleichen. Aber derjenige mit den wenigstens LOCs kann dennoch die meiste Arbeit gemacht haben und umgekehrt. LOC und Produktivität steht in keinem Verhältnis zueinander. LOC ist eine lustige Zahl die Spaß macht um zu Zeigen wer den größten e-penis hat. Aber das war es auch schon.
-
Gibt es überhaupt kluge Metriken? Meiner aus leidvoller Erfahrung gespeisten Meinung nach sind Metriken untaugliche Krücken. Ich finde es schon fast menschenverachtend, kreative Arbeit anhand irgendwelcher leicht zu messenden Zahlen zu beurteilen. Nach welcher Metrik ist die Mona Lisa zu beurteilen? Größe eher klein, Anzahl der Farben, Krümmungsradius der Mundwinkel? Es geht nichts über das Lesen von Code, und die einzige sinnvolle "Metrik" ist die Anzahl der WTFs pro Minute dabei.