Anmelden

Archiv verlassen und diese Seite im Standarddesign anzeigen : Wie berechnen ich permutation?/kombinationsmöglichkeiten bei nummernschildern?


Gast
2009-03-11, 20:43:39
Hallo,

ich würde gern die anzahl an verschieden nummernschild kombinationen ausrechnen,
nur weis ich leider nicht wie ich anfangen soll, vielleicht kann mir ja der ein oder andere
ne kleine hilfestellung geben bzw ne link wo es gut und einfach erklärt ist.

AA - 1
bis
ZZ - 9

A - 1
bis
Z - 99

wobei die verbotenen kombinationen(zb SS/SA/AH/etc) nicht wirklich von bedeutung
sind und wohl auch zahlenmässig vernachlässigbar sind

danke fürs lesen.

pest
2009-03-11, 21:06:36
in dem fall würde ich es einfach bruteforce mit ner geschachtelten schleife durchgehen

bei mehreren elem.

C++ mit STL



vector<string> SSTL_Permutation(const char *input)
{
vector<string> result;
string cs = input;

stable_sort(cs.begin(), cs.end());

do
result.insert(result.end(), cs);
while(next_permutation(cs.begin(), cs.end()));

return result;
}



oder mit C und Rekursion...



#include <cstdlib>
#include <iostream>

using namespace std;

const int n=3;
static int Z[n];

void gen_perm(int int_i)
{
int i,j,t;
for (i=int_i;i<n;i++) {
t = Z[i];
Z[i] = Z[int_i];
Z[int_i] = t;

if (int_i < n-1) gen_perm(int_i + 1);
else {
for (j=0;j<n;j++) printf("%i ",Z[j]);
printf("\n");
}
t = Z[i];
Z[i] = Z[int_i];
Z[int_i] = t;
}
}

int main(int argc, char *argv[])
{

for (int i=0;i<n;i++) Z[i] = i;
gen_perm(0);
system("PAUSE");
return EXIT_SUCCESS;
}

Gast
2009-03-11, 21:16:37
danke dir vielenmals für deine mühe und den code :) ich versuche es mal zu verstehen,
bruteforce sollte eigentlich die einfachere variante sein, da ich mit rekursion immer
schon meine liebe mühe hatte

pest
2009-03-11, 21:36:43
der c-code ist im gegensatz zu dem STL-snippet direkt ausführbar, kannst damit also rumspielen

robobimbo
2009-03-11, 22:55:58
Im Fall von AA - 1 und ZZ - 9

wäre es ja doch ganz einfach 26*26*9 für die Mögliche anzahl an Kombinationen

und im Fall von A - 1 und Z - 99

nach Adam Riese 26*99....

pest
2009-03-11, 23:16:48
rofl, mein code berechnet die permutation natürlich
ein hoch auf meine selektive wahrnehmung

RMC
2009-03-11, 23:37:37
der c-code ist im gegensatz zu dem STL-snippet direkt ausführbar, kannst damit also rumspielen

Und unlesbar obendrein :uup:

pest
2009-03-12, 00:05:43
unlesbar im sinne...ich habe keine ahnung was du da machst
oder unlesbar im sinne...das kann man schöner schreiben?...dafür hats nur 10min gedauert und besitzt eine künstlerische komponente :D

RMC
2009-03-12, 06:32:06
unlesbar im sinne...ich habe keine ahnung was du da machst
oder unlesbar im sinne...das kann man schöner schreiben?...dafür hats nur 10min gedauert und besitzt eine künstlerische komponente :D

Beides. Ersteres passiert logischerweise aufgrund von Zweiteres. Und nein, das ist keine Kunst, das ist Perversion.

Bei Variablen wie Z, n, j, i, t, int_i (wtf) kann ich keine Ahnung haben, was du da machst.

Das müsste man fast schon auf http://thedailywtf.com/ posten.

pest
2009-03-12, 07:43:30
das ist Perversion.

lol, gehts noch? ich habe nich geschrieben das es kunst ist
wenn du schon mit 10 Zeilen [schleife,swap,rekursion,swap] schwierigkeiten hast, weiß ich aber auch nicht :|


Bei Variablen wie Z


große Buchstaben -> Arrays


n


n is immer die Anzahl von irgendwas


j, i


i,j usw.. sind immer zählvariablen


t


eine temporärvariable


int_i (wtf)


ja da habe ich auch gekuckt ;D

also tut mir leid, das ich hier total perversen code poste um nem gast mal schnell zu helfen
ich merke mir deine kritik und nenne sie das nächste mal "zaehl_1" "zaehl_2", "temporaer" und "array_groesse" ;D
weil die 10 Zeilen könnten ja schon ein strukturelles Wahrnehmungsproblem darstellen, das verstehe ich

btw ich glaube du hast dir noch nie code wie x264 oder libavcodec angesehen oder? :D

RMC
2009-03-12, 08:26:24
lol, gehts noch? ich habe nich geschrieben das es kunst ist

Wo ist denn deine künstlerische Komponente?


wenn du schon mit 10 Zeilen [schleife,swap,rekursion,swap] schwierigkeiten hast, weiß ich aber auch nicht :

So ein Haufen unorganisierter Mistcode auf 10 Zeilen, Respekt. :|

große Buchstaben -> Arrays
n is immer die Anzahl von irgendwas
i,j usw.. sind immer zählvariablen
eine temporärvariable


Große Buchstaben entsprechen Arrays...interessant ;D
"t" ist temporär...aha. Und "i" und "j" sind Zähler..warum kann nicht auch "t" oder "n" dann ein Zähler sein? Wodurch unterscheidet sich das?


ich merke mir deine kritik und nenne sie das nächste mal "zaehl_1" "zaehl_2", "temporaer" und "array_groesse" ;D


Make Names Fit (http://www.possibility.com/Cpp/CppCodingStandard.html#descriptive)

Lesen, verstehen, merken, anwenden. In der Reihenfolge.


also tut mir leid, das ich hier total perversen code poste um nem gast mal schnell zu helfen


Nett gemeint, aber guter Code unterscheidet sich von schlechtem schon mal darin, dass auch Außenstehende ihn in einem Drittel der Zeit verstehen können.


btw ich glaube du hast dir noch nie code wie x264 oder libavcodec angesehen oder? :D

Wahrscheinlich aus gutem Grund.

pest
2009-03-12, 08:41:58
Wo ist denn deine künstlerische Komponente?


erkennst du nicht die symmetrie? wunderschön...


So ein Haufen unorganisierter Mistcode auf 10 Zeilen, Respekt. :|


und genau deswegen habe ich mir angewöhnt so zu coden, damit solche leute wie du..ewig brauchen das zu kapieren


Wahrscheinlich aus gutem Grund.

tja, ist vielleicht auch gut so, ich habe kein problem damit solchen code zu lesen


warum kann nicht auch "t" oder "n" dann ein Zähler sein? Wodurch unterscheidet sich das?


eine stille konvention, ich hab mir das ja nicht ausgedacht :rolleyes:
warum soll ich mehr tippen, wenn es das selbe macht und nur damit "andere" es besser verstehen


Make Names Fit (http://www.possibility.com/Cpp/CppCodingStandard.html#descriptive)


es ist C :D


Lesen, verstehen, merken, anwenden. In der Reihenfolge.


ich mache das seit mehr als 10 jahren...und komme auch in meinen 6k Zeilen Projekten klar.


Nett gemeint, aber guter Code unterscheidet sich von schlechtem schon mal darin, dass auch Außenstehende ihn in einem Drittel der Zeit verstehen können.


in einem drittel der zeit die ich gebraucht habe es zu schreiben? nein...das wäre unfair

und weil's so schön ist, hier habe ich superguppy geholfen indem ich den simplex-alg implementiert habe
ich weiß du wirst es nicht verstehen, aber ich muss nocheinmal deutlich betonen das ich diesen "stil" sehr mag, also nehme ich dein geblubber persönlich
nur weil du diese art nicht gewohnt bist, heißt es noch lange nicht das es schlecht ist



#include <stdio.h>
#include <stdlib.h>

void printvec(float *vec,int n)
{
int i=0;
printf("[");while (i<n){if (i>0) printf(" ");printf("%0.2f",vec[i]);i++;};printf("]\n");
}

void printtab(float *tab,int n,int m)
{
int i,j;
float *ttab=tab;
for (i=0;i<n;i++) {
if (i==n-1) printf("---------------------------------\n");
for (j=0;j<m-1;j++) printf("%10.3f",ttab[j]);
printf(" | %10.3f\n",ttab[j]);
ttab+=m;
};printf("\n");
}

int simplex(float *tab,int n,int m,float *xopt,float *minzf)
{
const int m1=m-1; /* Dimension der Koef-Matrix */
const int n1=n-1;
const int nbl = n1+m1;

int i,j,pr,pc,itmp,count,ret;
int *bl;
float fmin,ftmp,pvt;
float *ttab,*utab,*zftab;

bl=(int*)malloc( nbl * sizeof(int)); /* Position der BV+NBV */
for (i=0;i<nbl;i++) bl[i] = i;
for (i=0;i<m1;i++) xopt[i]=0.;

ret=0;count=1;
*minzf = 0.;zftab = &tab[n1*m]; /* Ptr auf ZF */
while (1) {
printf("n = %i\n",count);
printtab(tab,n,m);

/* Pivotsuche, bestimme Pivotspalte pc*/
fmin=*zftab;pc = 0; /* suche kleinsten ZF-Koef*/
for (i=1;i<m1;i++) if (zftab[i] < fmin) {fmin=zftab[i];pc=i;};
if (fmin>0) break;/* alle ZF-Koef >0 */

/* bestimme Pivotzeile pr=min{b/Pivotspalte} */
/* ttab=Ptr auf Pivotspalte,utab=Ptr auf b */
ttab = &tab[pc];utab = &tab[m1];
fmin=1e30;pr = -1;
for (i=0;i<n1;i++) {
if (*utab < 0.) {ret=-2;break;}; /* keine zBl */
if (*ttab > 0.) {
ftmp = *utab / *ttab;
if (ftmp < fmin) {fmin=ftmp;pr=i;};
}
utab+=m;ttab+=m;
}
if (pr==-1) {ret=-1;break;} /* Unbeschraenktheitstest */

/* Umrechnung (inplace) */
itmp=bl[pc];bl[pc] = bl[m1+pr];bl[m1+pr]=itmp; /* Tausche BV/NBV */
/* alle Elem. außer Pivotzeile/spalte */
/* ttab=Ptr auf Matrix[0,0],utab=Ptr auf Pivotzeile, pvt=Pivotelement*/
ttab = tab;utab = &tab[pr*m];pvt = utab[pc];
for (i=0;i<n;i++) {
if (i!=pr) for (j=0;j<m;j++) if (j!=pc) ttab[j] -= (utab[j]*ttab[pc])/pvt;
ttab+=m;
}
/* Pivotzeile/spalte, ttab=Ptr auf Pivotspalte*/
ttab = &tab[pc];
for (i=0;i<n;i++) {
if (i==pr) {
for (j=0;j<m;j++) {if (j!=pc) utab[j] /= pvt;else utab[j] = 1./pvt;};
} else *ttab /= -pvt;
ttab+=m;
}
count++;
}

/* bestimme Optimalwert/stelle, ttab=Ptr auf b*/
ttab = &tab[m1];
for (i=m1;i<nbl;i++) {if (bl[i] < m1) xopt[bl[i]] = *ttab;ttab+=m;}
*minzf=-tab[n*m-1];

free(bl);
return ret;
}

static float mytab[] = {
4.0,8.0,96.0,
8.0,4.0,120.0,
6.0,0.0,78.0,
-12.0,-8.0,0.0};

const int n=4;
const int m=3;

int main(int argc, char *argv[])
{
int ret;
float minzf;
float xopt[m-1];
printf("Simplex by pest\n\n");
ret = simplex(mytab,n,m,xopt,&minzf);
if (ret==-1) printf("LP unbeschränkt\n");
else if (ret==-2) printf("Basislösung nicht zulässig\n");
else {
printf("Optimalwert z* = %0.2f\n",minzf);
printf("Optimalstelle x* = ");printvec(xopt,m-1);
}
return 0;
}

DocEW
2009-03-12, 09:56:18
Also, eigentlich hätte ich ja nicht gemeckert, aber dass du auch noch stolz drauf bist - nee, nee... :D

RMC
2009-03-12, 12:16:42
und genau deswegen habe ich mir angewöhnt so zu coden, damit solche leute wie du..ewig brauchen das zu kapieren

eine stille konvention, ich hab mir das ja nicht ausgedacht :rolleyes:
warum soll ich mehr tippen, wenn es das selbe macht und nur damit "andere" es besser verstehen

Hast du je im Team gearbeitet wo andere Leute deinen Code lesen und verstehen mussten? Vermutlich nicht.


es ist C :D


That doesn't count. Du kannst auch schönen Code in C schreiben ;) Das soll dich nicht davon abhalten, dir mal allgemein gültige Regeln über Namensgebung durchzuschauen.



ich mache das seit mehr als 10 jahren...und komme auch in meinen 6k Zeilen Projekten klar.

Autsch, das tut echt weh X-(

Ja, du hast vermutlich nie im Team gearbeitet.



nur weil du diese art nicht gewohnt bist, heißt es noch lange nicht das es schlecht ist

Es ist schlecht weil der Code weder lesbar noch wartbar ist.

Wenn du dir das in 4 Wochen nochmal ansiehst, wirst nicht mal du selbst mehr wissen was i,n,t,j zählt oder was in Z[] steht.

Bei deinem Simplex Algorithmus krieg ich das Kotzen. Wer das mal debuggen muss, weil irgendeiner deiner komischen Zähler nicht richtig läuft, tut mir echt leid.

Und auch noch stolz drauf auf den Crap.. *kopfschüttel*

pest
2009-03-12, 14:35:11
Hast du je im Team gearbeitet wo andere Leute deinen Code lesen und verstehen mussten? Vermutlich nicht.


sicher


Es ist schlecht weil der Code weder lesbar noch wartbar ist.


im team entwickelt jeder seine teilmodule und stellt über eine spezifizierte api sicher das die kommunikation funktioniert.


Wenn du dir das in 4 Wochen nochmal ansiehst, wirst nicht mal du selbst mehr wissen was i,n,t,j zählt oder was in Z[] steht.


ka was dein problem ist, beide code-fragmente sind älter als 3 monate und ich kann dir jede zeile sofort erklären


Bei deinem Simplex Algorithmus krieg ich das Kotzen. Wer das mal debuggen muss, weil irgendeiner deiner komischen Zähler nicht richtig läuft, tut mir echt leid.


das sind keine zähler, das sind zeiger

du gehst mir grad echt auf die nerven, wer wie ich mit assembler angefangen hat, kann solchen code ohne probs lesen, und natürlich findet man da die fehler genauso schnell wie sonst, du musst halt nen bisschen abstrakter denken :|

wenn ich meinen low-level kram kapsel wird's auch leserlicher, und das ist das wichtige, weil ich damit ja dann arbeite

PHuV
2009-03-12, 14:46:16
Na ja, mit einem hat er schon recht, wenn Du den Code nach Jahren Dir anschaust, wirst Du schon ein paar Schwierigkeiten haben, erst mal zu blicken, was was genau ist. Ich habe mir von Anfang an angewöhnt, sprechende Variablennamen zu verwenden, viel zu kommentieren, auch wenn es anfänglich ein größerer Codierungsaufwand bedeutet, die Übersichtlichkeit wird es Dir danken. Das hat jetzt nichts mit Abstraktionsebene usw. zu tun. Man schreibt über die Jahre so viel Code, da kommt nach 15 Jahren, wie bei mir, eine Menge zusammen. Natürlich kommt man nach einer Weile forschen wieder rein, aber dennoch kommt man mit einen ausführlicheren Code viel besser wieder rein.

Man darf ja auch nicht vergessen, daß sich die Art, zu Code schreiben, über die Jahre und mit der Erfahrung ändert. Ich wundere mich heute auch über alte Zeilen, und was ich da teilweise früher für einen Käse gemacht habe, und würde es heute ganz anders lösen.

Gast
2009-03-12, 16:57:08
Im Fall von AA - 1 und ZZ - 9

wäre es ja doch ganz einfach 26*26*9 für die Mögliche anzahl an Kombinationen

und im Fall von A - 1 und Z - 99

nach Adam Riese 26*99....


hehe, genau das hab ich gesucht :) - dennoch danke an alle anderen!

RMC
2009-03-12, 17:15:51
im team entwickelt jeder seine teilmodule und stellt über eine spezifizierte api sicher das die kommunikation funktioniert.

Und du hast in 10 Jahren bestimmt noch nie Code von einem anderen Teammember gesehen, debuggt, erweitert oder sonst wie damit Kontakt gehabt (et vice versa)? ;)

Ich vermute mal, dass du beruflich nicht mit Programmieren zu tun hast. Besser gesagt, ich hoffe es stark.


ka was dein problem ist, beide code-fragmente sind älter als 3 monate und ich kann dir jede zeile sofort erklären

Aber bestimmt kannst du das ;) Und in 2 Jahren kannst du mir auch noch jede einzelne Zeile all deiner Programme erklären, die du geschrieben hast.


das sind keine zähler, das sind zeiger


Und Zähler sind trotzdem dabei, ich zeigs dir mal: zB fällt mir spontan diese wunderschöne Zeile auf:

int i,j,pr,pc,itmp,count,ret;

Sag mir mal bitte auf Anhieb, für was jede einzelne von diesen Variablen zuständig ist ;D

du musst halt nen bisschen abstrakter denken :|

Ja genau. Abstraktes Denken overruled strukturierten und selbsterklärenden Code. Deswegen musst du auch solche Kommentarzeilen wie:

/* ttab=Ptr auf Pivotspalte,utab=Ptr auf b */

in deine Programme einfügen :)

PatkIllA
2009-03-12, 18:12:26
ich mache das seit mehr als 10 jahren...und komme auch in meinen 6k Zeilen Projekten klar. ist "6k Zeilen Projekt" ein Projekt mit insgesamt 6000 Zeilen Code und siehst du das als groß an?

Gast
2009-03-19, 18:53:15
Wo ist denn deine künstlerische Komponente?



So ein Haufen unorganisierter Mistcode auf 10 Zeilen, Respekt. :|



Große Buchstaben entsprechen Arrays...interessant ;D
"t" ist temporär...aha. Und "i" und "j" sind Zähler..warum kann nicht auch "t" oder "n" dann ein Zähler sein? Wodurch unterscheidet sich das?



Make Names Fit (http://www.possibility.com/Cpp/CppCodingStandard.html#descriptive)

Lesen, verstehen, merken, anwenden. In der Reihenfolge.



Nett gemeint, aber guter Code unterscheidet sich von schlechtem schon mal darin, dass auch Außenstehende ihn in einem Drittel der Zeit verstehen können.



Wahrscheinlich aus gutem Grund.


Also sorry diesen Quelltext kann man doch noch lesen.
Schau die mal CGI o. Perl an.
Die Variablen zum Inkrementieren nennt man doch nunmal i ,j ,n u.z usw.

Coda
2009-03-19, 19:02:57
Und du hast in 10 Jahren bestimmt noch nie Code von einem anderen Teammember gesehen, debuggt, erweitert oder sonst wie damit Kontakt gehabt (et vice versa)? ;)
Bla bla. Immer die gleiche Leier von dir.

Hast genau die gleiche Scheiße damals bei mir abgelassen, dabei sieht das ganze bei großen Projekten von Adobe, Apple usw. auch nicht anders aus.

Darunter WebKit (http://svn.webkit.org/repository/webkit/trunk/WebCore/css/CSSStyleSelector.cpp), Qt, LLVM (http://llvm.org/svn/llvm-project/llvm/trunk/lib/CodeGen/SelectionDAG/SelectionDAGBuild.cpp), Boost, usw., und die sind ganz sicher nicht für schlechten Code bekannt. Eher im Gegenteil.

Du stellst dich hier auf ein Podest, das du dir nicht leisten kannst. Mir ist egal, ob sie dir an der Uni das Gehirn gewaschen haben, aber lass uns bitte mit dem Zeug in Ruhe.

RMC
2009-03-19, 20:03:04
Bla bla. Immer die gleiche Leier von dir.

Hast genau die gleiche Scheiße damals bei mir abgelassen, dabei sieht das ganze bei großen Projekten von Adobe, Apple usw. auch nicht anders aus.

Und wir sollen uns jetzt alle ein schlechtes Beispiel nehmen, weil sie Adobe und Apple heißen? :rolleyes:


Darunter WebKit (http://svn.webkit.org/repository/webkit/trunk/WebCore/css/CSSStyleSelector.cpp), Qt, LLVM (http://llvm.org/svn/llvm-project/llvm/trunk/lib/CodeGen/SelectionDAG/SelectionDAGBuild.cpp), Boost, usw., und die sind ganz sicher nicht für schlechten Code bekannt. Eher im Gegenteil.

Sagt wer..du? ;D

Wenn ich meine, dass der Code hinsichtlich der Lesbarkeit schlecht ist, dann spreche ich nicht seine generelle Funktionsweise an. Ja, er mag funktionieren, und da sind solche Bibliotheken garantiert nicht schlecht (hab ich auch nirgends angekreidet) umgesetzt, aber es is bestimmt net zu viel verlangt (grad von solchen Entwicklern), zumindest die Basics einzuhalten.



Du stellst dich hier auf ein Podest, das du dir nicht leisten kannst.

Weil grad du das beurteilen kannst ;D

Coda
2009-03-19, 20:12:17
Sagt wer..du? ;D
Nein, das ist weitverbreiteter Konsens.

Apple wählte KHTML damals gezielt aus als Basis für WebKit, weil es einfach zu erweitern war. Genauso wird LLVM für seine saubere Struktur gelobt ggü. GCC.

Weil grad du das beurteilen kannst ;D
Reiß deine Fresse mal nicht so weit auf hier. Das ist echt unterste Schublade.

Und ja, ich glaub sehr wohl, das sich das beurteilen kann. Ich entwickle jetzt schon seit über 10 Jahren und bin dabei ganz sicher nicht stehen geblieben. Wenn du als Anfänger Code nicht lesen kannst wenn er nicht in einer bestimmten Form formatiert ist, dann gilt das noch lange nicht für andere.

noid
2009-03-19, 20:19:04
Nein, das ist weitverbreiteter Konsenz.

Apple wählte KHTML damals gezielt aus als Basis für WebKit, weil es einfach zu erweitern war. Genauso wird LLVM für seine saubere Struktur gelobt ggü. GCC.


Reiß deine Fresse mal nicht so weit auf hier. Über deine kleinen Java-Spielerein bin ich schon lang hinaus.

Coda, ich weiss nicht was du bezwecken willst, aber würden wir nur Codingstyle bewerten, dann sind die von dir gezeigten Beispiele um Längen besser als Pests Schnipsel.
Auch wenn eine Variable mal einen Buchstaben hat, man kann den Code aber nur lesen, weil der Datentyp sowas von eindeutig ist. Das macht den Unterschied aus. Wenn ich "int i" vs "GenericListIterator i" setze. Musst ja nicht gleich einen auf dicke Hose machen. ;(

edit: Coda, Unrecht hat RMC aber nicht. Ich hatte erst gestern Code, da stand eigentlich der gleich Quark im Kommentar wie im Quelltext: /* In case t22 is greater as Cond22 + c54 */. Das mag irgendwann nicht mehr klappen.

Coda
2009-03-19, 20:19:46
Coda, ich weiss nicht was du bezwecken willst, aber würden wir nur Codingstyle bewerten, dann sind die von dir gezeigten Beispiele um Längen besser als Pests Schnipsel.
Ich weiß. Nur hat er ähnliche Kommentare schon damals bei meinem Code gebracht, der sehr ähnlich aussieht.

Der Code von Pest ist wirklich nicht sehr optimal, aber was er hier schon wieder deswegen ablässt geht mir echt gehörig auf die Nerven. Als ob man so ein kleines Stück Code nicht mit ein wenig Programmiererfahrung trotzdem nachvollziehen könnte.

Allein schon dass er meint dass so Projekte wie LLVM oder WebKit angeblich schlechten Code haben ist einfach nur noch lächerlich.

Coda
2009-03-19, 20:24:54
edit: Coda, Unrecht hat RMC aber nicht. Ich hatte erst gestern Code, da stand eigentlich der gleich Quark im Kommentar wie im Quelltext: /* In case t22 is greater as Cond22 + c54 */. Das mag irgendwann nicht mehr klappen.
Ich sage ja auch nicht, dass er unrecht hat, ich sage nur dass er es maßlos übertreibt und dabei andere mit unglaublicher Großkotzigkeit angeht.

noid
2009-03-19, 20:25:03
Ich weiß. Nur hat er ähnliche Kommentare schon damals bei meinem Code gebracht, der sehr ähnlich aussieht.

Der Code von Pest ist wirklich nicht sehr optimal, aber was er hier schon wieder deswegen ablässt geht mir echt gehörig auf die Nerven. Als ob man so ein kleines Stück Code nicht mit ein wenig Programmiererfahrung trotzdem nachvollziehen könnte.

Allein schon dass er meint dass so Projekte wie LLVM oder WebKit angeblich schlechten Code haben ist einfach nur noch lächerlich.

Das mag sein, du bevorzugst auch eine für mich seltsame Formatierung ;)
Aber gerade das mit der Programmiererfahrung ist hier bei so einer Frage die Frage. :|

Coda
2009-03-19, 20:25:46
Das mag sein, du bevorzugst auch eine für mich seltsame Formatierung ;)
Das ist aber der Standard, der fast überall Verwendung findet in C++-Projekten. Akzeptiert es oder nicht.

Überhaupt ist mir das wie gesagt egal. Ich bin darüber hinweg, und halte mich an den Coding-Standard des jeweiligen Auftraggebers. Für mich macht das vom Verständnis keinen Unterschied mehr.

Aber gerade das mit der Programmiererfahrung ist hier bei so einer Frage die Frage. :|
Jo, gerade deshalb verstehe ich auch nicht warum er anfängt auf dem Niveau zu aggieren. Ich habe sowas normal nicht nötig.

pest
2009-03-19, 20:35:09
ich weiß immernoch nicht was an meinem code suboptimal sein sollte
vor allem ist der simplex code schön schnell :)

das ich spaghetti code schreibe höre ich auch schon seit 10 jahren
aber liegt wahrscheinlich echt daran das ich nur code, wenn ich irgendwelche algorithmen teste usw...würde ich es beruflich machen, würde ichs vielleicht anders machen.

man orientiert sich halt auch an dem was man so liest

und mein code sah oft so (http://ffmpeg.cvs.sourceforge.net/viewvc/ffmpeg/ffmpeg/libavcodec/h264.c?hideattic=0&view=markup) aus

ich entschuldige mich hiermit offiziell für das int int_i war glaube ich stoned ;D

pest
2009-03-19, 20:37:56
int i,j,pr,pc,itmp,count,ret;

Sag mir mal bitte auf Anhieb, für was jede einzelne von diesen Variablen zuständig ist ;D


hm...ohne jetzt auf den code zu schauen

i,j sind zähler
pr ... PivotRow
pc ... PivotColumn
itmp... Integertemp
count...schleifenzähler
ret...Rückgabewert
zftab...Zielfunktionstabelle

usw...


/* ttab=Ptr auf Pivotspalte,utab=Ptr auf b */

in deine Programme einfügen :)

ja Kommentare haben ihre Daseinsberechtigung

RMC
2009-03-19, 20:45:06
Reiß deine Fresse mal nicht so weit auf hier. Das ist echt unterste Schublade.

Damit musst du rechnen wenn du meinst, dass ich mir solche Aussagen nicht erlauben kann.


Und ja, ich glaub sehr wohl, das sich das beurteilen kann. Ich entwickle jetzt schon seit über 10 Jahren und bin dabei ganz sicher nicht stehen geblieben. Wenn du als Anfänger Code nicht lesen kannst wenn er nicht in einer bestimmten Form formatiert ist, dann gilt das noch lange nicht für andere.

Coda, ich weiß net warum du jetzt mit dem Schwanzvergleich daherkommst, aber wenn ich dir das Anfänger-Gerücht scheinbar nicht anders ausreden kann, muss ich halt auch zugeben, dass ich schon 10 Jahre dabei bin.

Und meinen Stil hab ich nicht auf der Uni gelernt, wie du es mir unterstellst, nein, sondern im Beruf. Dort, wo man mit vielen Menschen an noch mehr Code gemeinsam arbeitet und wo ein sauberer, lesbarer und reglementierter Stil Voraussetzung ist.

Mich verwundert viel mehr, warum du mit einer scheinbar solchen Erfahrung meinen Standpunkt nicht verstehst. Bist du so stur?

Ich kann jeden Code lesen, aber meine Erfahrung zeigt (und das sag ich jetzt schon zum xten Mal), dass man sich viel Zeit, Mühe - und im Endeffekt Kosten - erspart, wenn der Code sauber und selbsterklärend geschrieben ist, dass ihn jeder versteht und jeder warten kann. Auch noch nach Jahren.

Allein schon dass er meint dass so Projekte wie LLVM oder WebKit angeblich schlechten Code haben ist einfach nur noch lächerlich.

Kapierst du nicht dass mir die Projekte völlig egal sind? Der Code ist trotzdem nicht optimal und selbst wenn ein Microsoft/Apple/Google-Pickerl drauf klebt erwarte ich zumindest ein gewisses Maß an Professionalität.

pest
2009-03-19, 20:51:09
erspart, wenn der Code sauber und selbsterklärend geschrieben ist, dass ihn jeder versteht und jeder warten kann. Auch noch nach Jahren.

was programmierst du denn beruflich so? Datenbanken?

wie willst du ein Programm das partielle Differentialgleichungen löst, selbsterklärend schreiben? Viele Algorithmen sind kompliziert
da macht's ne hübsche Formatierung auch nicht besser.

Hier, damit du verstehst was ich meine, schnellster PPM-Codec wo gibt von Dmitry Shkarin



/****************************************************************************
* This file is part of PPMd project *
* Written and distributed to public domain by Dmitry Shkarin 1997, *
* 1999-2001 *
* Contents: PPMII model description and encoding/decoding routines *
****************************************************************************/
#include <string.h>
#include "PPMd.h"
#pragma hdrstop
#include "Coder.hpp"
#include "SubAlloc.hpp"

enum { UP_FREQ=5, INT_BITS=7, PERIOD_BITS=7, TOT_BITS=INT_BITS+PERIOD_BITS,
INTERVAL=1 << INT_BITS, BIN_SCALE=1 << TOT_BITS, MAX_FREQ=124, O_BOUND=9 };

#pragma pack(1)
static struct SEE2_CONTEXT { // SEE-contexts for PPM-contexts with masked symbols
WORD Summ;
BYTE Shift, Count;
void init(UINT InitVal) { Summ=InitVal << (Shift=PERIOD_BITS-4); Count=7; }
UINT getMean() {
UINT RetVal=(Summ >> Shift); Summ -= RetVal;
return RetVal+(RetVal == 0);
}
void update() {
if (Shift < PERIOD_BITS && --Count == 0) {
Summ += Summ; Count=3 << Shift++;
}
}
} _PACK_ATTR SEE2Cont[24][32], DummySEE2Cont;
static struct PPM_CONTEXT { // Notes:
BYTE NumStats, Flags; // 1. NumStats & NumMasked contain
WORD SummFreq; // number of symbols minus 1
struct STATE { // 2. sizeof(WORD) > sizeof(BYTE)
BYTE Symbol, Freq; // 3. contexts example:
PPM_CONTEXT* Successor; // MaxOrder:
} _PACK_ATTR * Stats; // ABCD context
PPM_CONTEXT* Suffix; // BCD suffix
inline void encodeBinSymbol(int symbol);// BCDE successor
inline void encodeSymbol1(int symbol);// other orders:
inline void encodeSymbol2(int symbol);// BCD context
inline void decodeBinSymbol();// CD suffix
inline void decodeSymbol1();// BCDE successor
inline void decodeSymbol2();
inline void update1(STATE* p);
inline void update2(STATE* p);
inline SEE2_CONTEXT* makeEscFreq2();
void rescale();
void refresh(int OldNU,BOOL Scale);
PPM_CONTEXT* cutOff(int Order);
PPM_CONTEXT* removeBinConts(int Order);
STATE& oneState() const { return (STATE&) SummFreq; }
} _PACK_ATTR* MaxContext;
#pragma pack()

static BYTE NS2BSIndx[256], QTable[260]; // constants
static PPM_CONTEXT::STATE* FoundState; // found next state transition
static int InitEsc, OrderFall, RunLength, InitRL, MaxOrder;
static BYTE CharMask[256], NumMasked, PrevSuccess, EscCount, PrintCount;
static WORD BinSumm[25][64]; // binary SEE-contexts
static MR_METHOD MRMethod;

inline void SWAP(PPM_CONTEXT::STATE& s1,PPM_CONTEXT::STATE& s2)
{
WORD t1=(WORD&) s1; PPM_CONTEXT* t2=s1.Successor;
(WORD&) s1 = (WORD&) s2; s1.Successor=s2.Successor;
(WORD&) s2 = t1; s2.Successor=t2;
}
inline void StateCpy(PPM_CONTEXT::STATE& s1,const PPM_CONTEXT::STATE& s2)
{
(WORD&) s1=(WORD&) s2; s1.Successor=s2.Successor;
}
struct PPMD_STARTUP { inline PPMD_STARTUP(); } PPMd_StartUp;
inline PPMD_STARTUP::PPMD_STARTUP() // constants initialization
{
UINT i, k, m, Step;
for (i=0,k=1;i < N1 ;i++,k += 1) Indx2Units[i]=k;
for (k++;i < N1+N2 ;i++,k += 2) Indx2Units[i]=k;
for (k++;i < N1+N2+N3 ;i++,k += 3) Indx2Units[i]=k;
for (k++;i < N1+N2+N3+N4;i++,k += 4) Indx2Units[i]=k;
for (k=i=0;k < 128;k++) {
i += (Indx2Units[i] < k+1); Units2Indx[k]=i;
}
NS2BSIndx[0]=2*0; NS2BSIndx[1]=2*1;
memset(NS2BSIndx+2,2*2,9); memset(NS2BSIndx+11,2*3,256-11);
for (i=0;i < UP_FREQ;i++) QTable[i]=i;
for (m=i=UP_FREQ, k=Step=1;i < 260;i++) {
QTable[i]=m;
if ( !--k ) { k = ++Step; m++; }
}
(DWORD&) DummySEE2Cont=PPMdSignature;
}
static void _STDCALL StartModelRare(int MaxOrder,MR_METHOD MRMethod)
{
UINT i, k, m;
memset(CharMask,0,sizeof(CharMask)); EscCount=PrintCount=1;
if (MaxOrder < 2) { // we are in solid mode
OrderFall=::MaxOrder;
for (PPM_CONTEXT* pc=MaxContext;pc->Suffix != NULL;pc=pc->Suffix)
OrderFall--;
return;
}
OrderFall=::MaxOrder=MaxOrder; ::MRMethod=MRMethod;
InitSubAllocator();
RunLength=InitRL=-((MaxOrder < 12)?MaxOrder:12)-1;
MaxContext = (PPM_CONTEXT*) AllocContext();
MaxContext->Suffix=NULL;
MaxContext->SummFreq=(MaxContext->NumStats=255)+2;
MaxContext->Stats = (PPM_CONTEXT::STATE*) AllocUnits(256/2);
for (PrevSuccess=i=0;i < 256;i++) {
MaxContext->Stats[i].Symbol=i; MaxContext->Stats[i].Freq=1;
MaxContext->Stats[i].Successor=NULL;
}
static const WORD InitBinEsc[]={0x3CDD,0x1F3F,0x59BF,0x48F3,0x64A1,0x5ABC,0x6632,0x6051};
for (i=m=0;m < 25;m++) {
while (QTable[i] == m) i++;
for (k=0;k < 8;k++)
BinSumm[m][k]=BIN_SCALE-InitBinEsc[k]/(i+1);
for (k=8;k < 64;k += 8)
memcpy(BinSumm[m]+k,BinSumm[m],8*sizeof(WORD));
}
for (i=m=0;m < 24;m++) {
while (QTable[i+3] == m+3) i++;
SEE2Cont[m][0].init(2*i+5);
for (k=1;k < 32;k++) SEE2Cont[m][k]=SEE2Cont[m][0];
}
}
void PPM_CONTEXT::refresh(int OldNU,BOOL Scale)
{
int i=NumStats, EscFreq;
STATE* p = Stats = (STATE*) ShrinkUnits(Stats,OldNU,(i+2) >> 1);
Flags=(Flags & (0x10+0x04*Scale))+0x08*(p->Symbol >= 0x40);
EscFreq=SummFreq-p->Freq;
SummFreq = (p->Freq=(p->Freq+Scale) >> Scale);
do {
EscFreq -= (++p)->Freq;
SummFreq += (p->Freq=(p->Freq+Scale) >> Scale);
Flags |= 0x08*(p->Symbol >= 0x40);
} while ( --i );
SummFreq += (EscFreq=(EscFreq+Scale) >> Scale);
}
#define P_CALL(F) ( PrefetchData(p->Successor), \
p->Successor=p->Successor->F(Order+1))
PPM_CONTEXT* PPM_CONTEXT::cutOff(int Order)
{
int i, tmp;
STATE* p;
if ( !NumStats ) {
if ((BYTE*) (p=&oneState())->Successor >= UnitsStart) {
if (Order < MaxOrder) P_CALL(cutOff);
else p->Successor=NULL;
if (!p->Successor && Order > O_BOUND)
goto REMOVE;
return this;
} else {
REMOVE: SpecialFreeUnit(this); return NULL;
}
}
PrefetchData(Stats);
Stats = (STATE*) MoveUnitsUp(Stats,tmp=(NumStats+2) >> 1);
for (p=Stats+(i=NumStats);p >= Stats;p--)
if ((BYTE*) p->Successor < UnitsStart) {
p->Successor=NULL; SWAP(*p,Stats[i--]);
} else if (Order < MaxOrder) P_CALL(cutOff);
else p->Successor=NULL;
if (i != NumStats && Order) {
NumStats=i; p=Stats;
if (i < 0) { FreeUnits(p,tmp); goto REMOVE; }
else if (i == 0) {
Flags=(Flags & 0x10)+0x08*(p->Symbol >= 0x40);
StateCpy(oneState(),*p); FreeUnits(p,tmp);
oneState().Freq=(oneState().Freq+11) >> 3;
} else refresh(tmp,SummFreq > 16*i);
}
return this;
}
PPM_CONTEXT* PPM_CONTEXT::removeBinConts(int Order)
{
STATE* p;
if ( !NumStats ) {
p=&oneState();
if ((BYTE*) p->Successor >= UnitsStart && Order < MaxOrder)
P_CALL(removeBinConts);
else p->Successor=NULL;
if (!p->Successor && (!Suffix->NumStats || Suffix->Flags == 0xFF)) {
FreeUnits(this,1); return NULL;
} else return this;
}
PrefetchData(Stats);
for (p=Stats+NumStats;p >= Stats;p--)
if ((BYTE*) p->Successor >= UnitsStart && Order < MaxOrder)
P_CALL(removeBinConts);
else p->Successor=NULL;
return this;
}
static void RestoreModelRare(PPM_CONTEXT* pc1,PPM_CONTEXT* MinContext,
PPM_CONTEXT* FSuccessor)
{
PPM_CONTEXT* pc;
PPM_CONTEXT::STATE* p;
for (pc=MaxContext, pText=HeapStart;pc != pc1;pc=pc->Suffix)
if (--(pc->NumStats) == 0) {
pc->Flags=(pc->Flags & 0x10)+0x08*(pc->Stats->Symbol >= 0x40);
p=pc->Stats; StateCpy(pc->oneState(),*p);
SpecialFreeUnit(p);
pc->oneState().Freq=(pc->oneState().Freq+11) >> 3;
} else
pc->refresh((pc->NumStats+3) >> 1,FALSE);
for ( ;pc != MinContext;pc=pc->Suffix)
if ( !pc->NumStats )
pc->oneState().Freq -= pc->oneState().Freq >> 1;
else if ((pc->SummFreq += 4) > 128+4*pc->NumStats)
pc->refresh((pc->NumStats+2) >> 1,TRUE);
if (MRMethod > MRM_FREEZE) {
MaxContext=FSuccessor; GlueCount += !(BList[1].Stamp & 1);
} else if (MRMethod == MRM_FREEZE) {
while ( MaxContext->Suffix ) MaxContext=MaxContext->Suffix;
MaxContext->removeBinConts(0); MRMethod=MR_METHOD(MRMethod+1);
GlueCount=0; OrderFall=MaxOrder;
} else if (MRMethod == MRM_RESTART || GetUsedMemory() < (SubAllocatorSize >> 1)) {
StartModelRare(MaxOrder,MRMethod);
EscCount=0; PrintCount=0xFF;
} else {
while ( MaxContext->Suffix ) MaxContext=MaxContext->Suffix;
do {
MaxContext->cutOff(0); ExpandTextArea();
} while (GetUsedMemory() > 3*(SubAllocatorSize >> 2));
GlueCount=0; OrderFall=MaxOrder;
}
}
static PPM_CONTEXT* _FASTCALL CreateSuccessors(BOOL Skip,PPM_CONTEXT::STATE* p,
PPM_CONTEXT* pc);
static PPM_CONTEXT* _FASTCALL ReduceOrder(PPM_CONTEXT::STATE* p,PPM_CONTEXT* pc)
{
PPM_CONTEXT::STATE* p1, * ps[MAX_O], ** pps=ps;
PPM_CONTEXT* pc1=pc, * UpBranch = (PPM_CONTEXT*) pText;
BYTE tmp, sym=FoundState->Symbol;
*pps++ = FoundState; FoundState->Successor=UpBranch;
OrderFall++;
if ( p ) { pc=pc->Suffix; goto LOOP_ENTRY; }
for ( ; ; ) {
if ( !pc->Suffix ) {
if (MRMethod > MRM_FREEZE) {
FROZEN: do { (*--pps)->Successor = pc; } while (pps != ps);
pText=HeapStart+1; OrderFall=1;
}
return pc;
}
pc=pc->Suffix;
if ( pc->NumStats ) {
if ((p=pc->Stats)->Symbol != sym)
do { tmp=p[1].Symbol; p++; } while (tmp != sym);
tmp=2*(p->Freq < MAX_FREQ-9);
p->Freq += tmp; pc->SummFreq += tmp;
} else { p=&(pc->oneState()); p->Freq += (p->Freq < 32); }
LOOP_ENTRY:
if ( p->Successor ) break;
*pps++ = p; p->Successor=UpBranch;
OrderFall++;
}
if (MRMethod > MRM_FREEZE) {
pc = p->Successor; goto FROZEN;
} else if (p->Successor <= UpBranch) {
p1=FoundState; FoundState=p;
p->Successor=CreateSuccessors(FALSE,NULL,pc);
FoundState=p1;
}
if (OrderFall == 1 && pc1 == MaxContext) {
FoundState->Successor=p->Successor; pText--;
}
return p->Successor;
}
void PPM_CONTEXT::rescale()
{
UINT OldNU, Adder, EscFreq, i=NumStats;
STATE tmp, * p1, * p;
for (p=FoundState;p != Stats;p--) SWAP(p[0],p[-1]);
p->Freq += 4; SummFreq += 4;
EscFreq=SummFreq-p->Freq;
Adder=(OrderFall != 0 || MRMethod > MRM_FREEZE);
SummFreq = (p->Freq=(p->Freq+Adder) >> 1);
do {
EscFreq -= (++p)->Freq;
SummFreq += (p->Freq=(p->Freq+Adder) >> 1);
if (p[0].Freq > p[-1].Freq) {
StateCpy(tmp,*(p1=p));
do StateCpy(p1[0],p1[-1]); while (tmp.Freq > (--p1)[-1].Freq);
StateCpy(*p1,tmp);
}
} while ( --i );
if (p->Freq == 0) {
do { i++; } while ((--p)->Freq == 0);
EscFreq += i; OldNU=(NumStats+2) >> 1;
if ((NumStats -= i) == 0) {
StateCpy(tmp,*Stats);
tmp.Freq=(2*tmp.Freq+EscFreq-1)/EscFreq;
if (tmp.Freq > MAX_FREQ/3) tmp.Freq=MAX_FREQ/3;
FreeUnits(Stats,OldNU); StateCpy(oneState(),tmp);
Flags=(Flags & 0x10)+0x08*(tmp.Symbol >= 0x40);
FoundState=&oneState(); return;
}
Stats = (STATE*) ShrinkUnits(Stats,OldNU,(NumStats+2) >> 1);
Flags &= ~0x08; i=NumStats;
Flags |= 0x08*((p=Stats)->Symbol >= 0x40);
do { Flags |= 0x08*((++p)->Symbol >= 0x40); } while ( --i );
}
SummFreq += (EscFreq -= (EscFreq >> 1));
Flags |= 0x04; FoundState=Stats;
}
static PPM_CONTEXT* _FASTCALL CreateSuccessors(BOOL Skip,PPM_CONTEXT::STATE* p,
PPM_CONTEXT* pc)
{
PPM_CONTEXT ct, * UpBranch=FoundState->Successor;
PPM_CONTEXT::STATE* ps[MAX_O], ** pps=ps;
UINT cf, s0;
BYTE tmp, sym=FoundState->Symbol;
if ( !Skip ) {
*pps++ = FoundState;
if ( !pc->Suffix ) goto NO_LOOP;
}
if ( p ) { pc=pc->Suffix; goto LOOP_ENTRY; }
do {
pc=pc->Suffix;
if ( pc->NumStats ) {
if ((p=pc->Stats)->Symbol != sym)
do { tmp=p[1].Symbol; p++; } while (tmp != sym);
tmp=(p->Freq < MAX_FREQ-9);
p->Freq += tmp; pc->SummFreq += tmp;
} else {
p=&(pc->oneState());
p->Freq += (!pc->Suffix->NumStats & (p->Freq < 24));
}
LOOP_ENTRY:
if (p->Successor != UpBranch) {
pc=p->Successor; break;
}
*pps++ = p;
} while ( pc->Suffix );
NO_LOOP:
if (pps == ps) return pc;
ct.NumStats=0; ct.Flags=0x10*(sym >= 0x40);
ct.oneState().Symbol=sym=*(BYTE*) UpBranch;
ct.oneState().Successor=(PPM_CONTEXT*) (((BYTE*) UpBranch)+1);
ct.Flags |= 0x08*(sym >= 0x40);
if ( pc->NumStats ) {
if ((p=pc->Stats)->Symbol != sym)
do { tmp=p[1].Symbol; p++; } while (tmp != sym);
s0=pc->SummFreq-pc->NumStats-(cf=p->Freq-1);
ct.oneState().Freq=1+((2*cf <= s0)?(5*cf > s0):((cf+2*s0-3)/s0));
} else
ct.oneState().Freq=pc->oneState().Freq;
do {
PPM_CONTEXT* pc1 = (PPM_CONTEXT*) AllocContext();
if ( !pc1 ) return NULL;
((DWORD*) pc1)[0] = ((DWORD*) &ct)[0];
((DWORD*) pc1)[1] = ((DWORD*) &ct)[1];
pc1->Suffix=pc; (*--pps)->Successor=pc=pc1;
} while (pps != ps);
return pc;
}
static inline void UpdateModel(PPM_CONTEXT* MinContext)
{
PPM_CONTEXT::STATE* p=NULL;
PPM_CONTEXT* Successor, * FSuccessor, * pc, * pc1=MaxContext;
UINT ns1, ns, cf, sf, s0, FFreq=FoundState->Freq;
BYTE Flag, sym, FSymbol=FoundState->Symbol;
FSuccessor=FoundState->Successor; pc=MinContext->Suffix;
if (FFreq < MAX_FREQ/4 && pc) {
if ( pc->NumStats ) {
if ((p=pc->Stats)->Symbol != FSymbol) {
do { sym=p[1].Symbol; p++; } while (sym != FSymbol);
if (p[0].Freq >= p[-1].Freq) {
SWAP(p[0],p[-1]); p--;
}
}
cf=2*(p->Freq < MAX_FREQ-9);
p->Freq += cf; pc->SummFreq += cf;
} else { p=&(pc->oneState()); p->Freq += (p->Freq < 32); }
}
if (!OrderFall && FSuccessor) {
FoundState->Successor=CreateSuccessors(TRUE,p,MinContext);
if ( !FoundState->Successor ) goto RESTART_MODEL;
MaxContext=FoundState->Successor; return;
}
*pText++ = FSymbol; Successor = (PPM_CONTEXT*) pText;
if (pText >= UnitsStart) goto RESTART_MODEL;
if ( FSuccessor ) {
if ((BYTE*) FSuccessor < UnitsStart)
FSuccessor=CreateSuccessors(FALSE,p,MinContext);
} else
FSuccessor=ReduceOrder(p,MinContext);
if ( !FSuccessor ) goto RESTART_MODEL;
if ( !--OrderFall ) {
Successor=FSuccessor; pText -= (MaxContext != MinContext);
} else if (MRMethod > MRM_FREEZE) {
Successor=FSuccessor; pText=HeapStart;
OrderFall=0;
}
s0=MinContext->SummFreq-(ns=MinContext->NumStats)-FFreq;
for (Flag=0x08*(FSymbol >= 0x40);pc1 != MinContext;pc1=pc1->Suffix) {
if ((ns1=pc1->NumStats) != 0) {
if ((ns1 & 1) != 0) {
p=(PPM_CONTEXT::STATE*) ExpandUnits(pc1->Stats,(ns1+1) >> 1);
if ( !p ) goto RESTART_MODEL;
pc1->Stats=p;
}
pc1->SummFreq += (3*ns1+1 < ns);
} else {
p=(PPM_CONTEXT::STATE*) AllocUnits(1);
if ( !p ) goto RESTART_MODEL;
StateCpy(*p,pc1->oneState()); pc1->Stats=p;
if (p->Freq < MAX_FREQ/4-1) p->Freq += p->Freq;
else p->Freq = MAX_FREQ-4;
pc1->SummFreq=p->Freq+InitEsc+(ns > 2);
}
cf=2*FFreq*(pc1->SummFreq+6); sf=s0+pc1->SummFreq;
if (cf < 6*sf) {
cf=1+(cf > sf)+(cf >= 4*sf);
pc1->SummFreq += 4;
} else {
cf=4+(cf > 9*sf)+(cf > 12*sf)+(cf > 15*sf);
pc1->SummFreq += cf;
}
p=pc1->Stats+(++pc1->NumStats); p->Successor=Successor;
p->Symbol = FSymbol; p->Freq = cf;
pc1->Flags |= Flag;
}
MaxContext=FSuccessor; return;
RESTART_MODEL:
RestoreModelRare(pc1,MinContext,FSuccessor);
}
// Tabulated escapes for exponential symbol distribution
static const BYTE ExpEscape[16]={ 25,14, 9, 7, 5, 5, 4, 4, 4, 3, 3, 3, 2, 2, 2, 2 };
#define GET_MEAN(SUMM,SHIFT,ROUND) ((SUMM+(1 << (SHIFT-ROUND))) >> (SHIFT))
inline void PPM_CONTEXT::encodeBinSymbol(int symbol)
{
BYTE indx=NS2BSIndx[Suffix->NumStats]+PrevSuccess+Flags;
STATE& rs=oneState();
WORD& bs=BinSumm[QTable[rs.Freq-1]][indx+((RunLength >> 26) & 0x20)];
if (rs.Symbol == symbol) {
FoundState=&rs; rs.Freq += (rs.Freq < 196);
SubRange.LowCount=0; SubRange.HighCount=bs;
bs += INTERVAL-GET_MEAN(bs,PERIOD_BITS,2);
PrevSuccess=1; RunLength++;
} else {
SubRange.LowCount=bs; bs -= GET_MEAN(bs,PERIOD_BITS,2);
SubRange.HighCount=BIN_SCALE; InitEsc=ExpEscape[bs >> 10];
CharMask[rs.Symbol]=EscCount;
NumMasked=PrevSuccess=0; FoundState=NULL;
}
}
inline void PPM_CONTEXT::decodeBinSymbol()
{
BYTE indx=NS2BSIndx[Suffix->NumStats]+PrevSuccess+Flags;
STATE& rs=oneState();
WORD& bs=BinSumm[QTable[rs.Freq-1]][indx+((RunLength >> 26) & 0x20)];
if (ariGetCurrentShiftCount(TOT_BITS) < bs) {
FoundState=&rs; rs.Freq += (rs.Freq < 196);
SubRange.LowCount=0; SubRange.HighCount=bs;
bs += INTERVAL-GET_MEAN(bs,PERIOD_BITS,2);
PrevSuccess=1; RunLength++;
} else {
SubRange.LowCount=bs; bs -= GET_MEAN(bs,PERIOD_BITS,2);
SubRange.HighCount=BIN_SCALE; InitEsc=ExpEscape[bs >> 10];
CharMask[rs.Symbol]=EscCount;
NumMasked=PrevSuccess=0; FoundState=NULL;
}
}
inline void PPM_CONTEXT::update1(STATE* p)
{
(FoundState=p)->Freq += 4; SummFreq += 4;
if (p[0].Freq > p[-1].Freq) {
SWAP(p[0],p[-1]); FoundState=--p;
if (p->Freq > MAX_FREQ) rescale();
}
}
inline void PPM_CONTEXT::encodeSymbol1(int symbol)
{
UINT LoCnt, i=Stats->Symbol;
STATE* p=Stats; SubRange.scale=SummFreq;
if (i == symbol) {
PrevSuccess=(2*(SubRange.HighCount=p->Freq) >= SubRange.scale);
(FoundState=p)->Freq += 4; SummFreq += 4;
RunLength += PrevSuccess;
if (p->Freq > MAX_FREQ) rescale();
SubRange.LowCount=0; return;
}
LoCnt=p->Freq;
i=NumStats; PrevSuccess=0;
while ((++p)->Symbol != symbol) {
LoCnt += p->Freq;
if (--i == 0) {
if ( Suffix ) PrefetchData(Suffix);
SubRange.LowCount=LoCnt; CharMask[p->Symbol]=EscCount;
i=NumMasked=NumStats; FoundState=NULL;
do { CharMask[(--p)->Symbol]=EscCount; } while ( --i );
SubRange.HighCount=SubRange.scale;
return;
}
}
SubRange.HighCount=(SubRange.LowCount=LoCnt)+p->Freq;
update1(p);
}
inline void PPM_CONTEXT::decodeSymbol1()
{
UINT i, count, HiCnt=Stats->Freq;
STATE* p=Stats; SubRange.scale=SummFreq;
if ((count=ariGetCurrentCount()) < HiCnt) {
PrevSuccess=(2*(SubRange.HighCount=HiCnt) >= SubRange.scale);
(FoundState=p)->Freq=(HiCnt += 4); SummFreq += 4;
RunLength += PrevSuccess;
if (HiCnt > MAX_FREQ) rescale();
SubRange.LowCount=0; return;
}
i=NumStats; PrevSuccess=0;
while ((HiCnt += (++p)->Freq) <= count)
if (--i == 0) {
if ( Suffix ) PrefetchData(Suffix);
SubRange.LowCount=HiCnt; CharMask[p->Symbol]=EscCount;
i=NumMasked=NumStats; FoundState=NULL;
do { CharMask[(--p)->Symbol]=EscCount; } while ( --i );
SubRange.HighCount=SubRange.scale;
return;
}
SubRange.LowCount=(SubRange.HighCount=HiCnt)-p->Freq;
update1(p);
}
inline void PPM_CONTEXT::update2(STATE* p)
{
(FoundState=p)->Freq += 4; SummFreq += 4;
if (p->Freq > MAX_FREQ) rescale();
EscCount++; RunLength=InitRL;
}
inline SEE2_CONTEXT* PPM_CONTEXT::makeEscFreq2()
{
BYTE* pb=(BYTE*) Stats; UINT t=2*NumStats;
PrefetchData(pb); PrefetchData(pb+t);
PrefetchData(pb += 2*t); PrefetchData(pb+t);
SEE2_CONTEXT* psee2c;
if (NumStats != 0xFF) {
t=Suffix->NumStats;
psee2c=SEE2Cont[QTable[NumStats+2]-3]+(SummFreq > 11*(NumStats+1));
psee2c += 2*(2*NumStats < t+NumMasked)+Flags;
SubRange.scale=psee2c->getMean();
} else {
psee2c=&DummySEE2Cont; SubRange.scale=1;
}
return psee2c;
}
inline void PPM_CONTEXT::encodeSymbol2(int symbol)
{
SEE2_CONTEXT* psee2c=makeEscFreq2();
UINT Sym, LoCnt=0, i=NumStats-NumMasked;
STATE* p1, * p=Stats-1;
do {
do { Sym=p[1].Symbol; p++; } while (CharMask[Sym] == EscCount);
CharMask[Sym]=EscCount;
if (Sym == symbol) goto SYMBOL_FOUND;
LoCnt += p->Freq;
} while ( --i );
SubRange.HighCount=(SubRange.scale += (SubRange.LowCount=LoCnt));
psee2c->Summ += SubRange.scale; NumMasked = NumStats;
return;
SYMBOL_FOUND:
SubRange.LowCount=LoCnt; SubRange.HighCount=(LoCnt+=p->Freq);
for (p1=p; --i ; ) {
do { Sym=p1[1].Symbol; p1++; } while (CharMask[Sym] == EscCount);
LoCnt += p1->Freq;
}
SubRange.scale += LoCnt;
psee2c->update(); update2(p);
}
inline void PPM_CONTEXT::decodeSymbol2()
{
SEE2_CONTEXT* psee2c=makeEscFreq2();
UINT Sym, count, HiCnt=0, i=NumStats-NumMasked;
STATE* ps[256], ** pps=ps, * p=Stats-1;
do {
do { Sym=p[1].Symbol; p++; } while (CharMask[Sym] == EscCount);
HiCnt += p->Freq; *pps++ = p;
} while ( --i );
SubRange.scale += HiCnt; count=ariGetCurrentCount();
p=*(pps=ps);
if (count < HiCnt) {
HiCnt=0;
while ((HiCnt += p->Freq) <= count) p=*++pps;
SubRange.LowCount = (SubRange.HighCount=HiCnt)-p->Freq;
psee2c->update(); update2(p);
} else {
SubRange.LowCount=HiCnt; SubRange.HighCount=SubRange.scale;
i=NumStats-NumMasked; NumMasked = NumStats;
do { CharMask[(*pps)->Symbol]=EscCount; pps++; } while ( --i );
psee2c->Summ += SubRange.scale;
}
}
inline void ClearMask(_PPMD_FILE* EncodedFile,_PPMD_FILE* DecodedFile)
{
EscCount=1; memset(CharMask,0,sizeof(CharMask));
if (++PrintCount == 0) PrintInfo(DecodedFile,EncodedFile);
}
void _STDCALL EncodeFile(_PPMD_FILE* EncodedFile,_PPMD_FILE* DecodedFile,
int MaxOrder,MR_METHOD MRMethod)
{
ariInitEncoder(); StartModelRare(MaxOrder,MRMethod);
for (PPM_CONTEXT* MinContext; ; ) {
BYTE ns=(MinContext=MaxContext)->NumStats;
int c = _PPMD_E_GETC(DecodedFile);
if ( ns ) {
MinContext->encodeSymbol1(c); ariEncodeSymbol();
} else {
MinContext->encodeBinSymbol(c); ariShiftEncodeSymbol(TOT_BITS);
}
while ( !FoundState ) {
ARI_ENC_NORMALIZE(EncodedFile);
do {
OrderFall++; MinContext=MinContext->Suffix;
if ( !MinContext ) goto STOP_ENCODING;
} while (MinContext->NumStats == NumMasked);
MinContext->encodeSymbol2(c); ariEncodeSymbol();
}
if (!OrderFall && (BYTE*) FoundState->Successor >= UnitsStart)
PrefetchData(MaxContext=FoundState->Successor);
else {
UpdateModel(MinContext); PrefetchData(MaxContext);
if (EscCount == 0) ClearMask(EncodedFile,DecodedFile);
}
ARI_ENC_NORMALIZE(EncodedFile);
}
STOP_ENCODING:
ARI_FLUSH_ENCODER(EncodedFile); PrintInfo(DecodedFile,EncodedFile);
}
void _STDCALL DecodeFile(_PPMD_FILE* DecodedFile,_PPMD_FILE* EncodedFile,
int MaxOrder,MR_METHOD MRMethod)
{
ARI_INIT_DECODER(EncodedFile); StartModelRare(MaxOrder,MRMethod);
PPM_CONTEXT* MinContext=MaxContext;
for (BYTE ns=MinContext->NumStats; ; ) {
( ns )?(MinContext->decodeSymbol1()):(MinContext->decodeBinSymbol());
ariRemoveSubrange();
while ( !FoundState ) {
ARI_DEC_NORMALIZE(EncodedFile);
do {
OrderFall++; MinContext=MinContext->Suffix;
if ( !MinContext ) goto STOP_DECODING;
} while (MinContext->NumStats == NumMasked);
MinContext->decodeSymbol2(); ariRemoveSubrange();
}
_PPMD_D_PUTC(FoundState->Symbol,DecodedFile);
if (!OrderFall && (BYTE*) FoundState->Successor >= UnitsStart)
PrefetchData(MaxContext=FoundState->Successor);
else {
UpdateModel(MinContext); PrefetchData(MaxContext);
if (EscCount == 0) ClearMask(EncodedFile,DecodedFile);
}
ns=(MinContext=MaxContext)->NumStats;
ARI_DEC_NORMALIZE(EncodedFile);
}
STOP_DECODING:
PrintInfo(DecodedFile,EncodedFile);
}



das kannst du dir gern die nächsten 10 Jahre anschaun...aber ich denk' kapieren wirst du Großmaul das trotzdem nicht.

Coda
2009-03-19, 20:51:34
RMC: Ich finde nach wie vor dass du maßlos übertreibst. EOD.

Wer Codequalität an der Formatierung bewertet hat es sowieso nicht kapiert. Und wer WebKit-Code für schlecht wartbar hält hat wohl den Beruf verfehlt.

wie willst du ein Programm das partielle Differentialgleichungen löst, selbsterklärend schreiben? Viele Algorithmen sind kompliziert da macht's ne hübsche Formatierung auch nicht besser.
Eben.

Für einfachen GUI-Code, oder ähnliches kann man sehr gut auf Wartbarkeit, usw. achten und sehr schönen Code abliefern. Hab ich gar nichts dagegen und praktiziere ich auch selber so. Aber wenn's um's Eingemachte geht, dann versteht ohne Nachfrage sowieso niemand mehr um was es geht.

RMC
2009-03-19, 21:12:21
Wer Codequalität an der Formatierung bewertet hat es sowieso nicht kapiert.
Und wer WebKit-Code für schlecht wartbar hält hat wohl den Beruf verfehlt.

Wer sich erst bei verschachteleten switch-Statements so richtig gut und toll fühlt, dem gehört eine gewatscht.

Den WebKit Code kann man stellenweise noch ordentlich verbessern, aber ein ganzes Stück besser als dein zweites Beispiel ist er auf jeden Fall.

Ich schätze Coda, den Beruf hat derjenige verfehlt, der absolut kein Verständnis für die offensichtlichsten Basics zeigt. Schade.

Viele Algorithmen sind kompliziert
da macht's ne hübsche Formatierung auch nicht besser.

Doch.

das kannst du dir gern die nächsten 10 Jahre anschaun...aber ich denk' kapieren wirst du Großmaul das trotzdem nicht.

Das war hochgradig unnötig

pest
2009-03-19, 21:20:20
Wer sich erst bei verschachteleten switch-Statements so richtig gut und toll fühlt, dem gehört eine gewatscht.


ich versteh dich wirklich nicht


Doch.


ich finde z.B. den Skarin-Code deutlich hübscher als meinen Simplex-Code
lesbarer wird dadurch keiner von beiden. In Ersterem hätte ich persönlich Variablennamen noch kürzer gewählt (succ statt successor z.B.)...aber jeder wie er's mag und braucht.

und noch eine letzte Frage...was machst du eigentlich bei Assembler-Code? dich auch beschweren das der Code nicht selbsterklärend ist?


Das war hochgradig unnötig

na komm...Schwanzvergleich ;)

Trap
2009-03-19, 21:22:41
Der Code ist trotzdem nicht optimal und selbst wenn ein Microsoft/Apple/Google-Pickerl drauf klebt erwarte ich zumindest ein gewisses Maß an Professionalität.
Ist besondere Aufmerksam gegenüber der Formatierung des Codes und der sprechenden Bennenung der Variablen nicht unprofessionell?

Wenn man sich die Geschichte der erfolgreichen Software so anguckt war wenig davon berühmt für besonders saubere und durchdachte Entwürfe.

RMC
2009-03-19, 21:37:47
und noch eine letzte Frage...was machst du eigentlich bei Assembler-Code? dich auch beschweren das der Code nicht selbsterklärend ist?

Selbsterklärender Code ist nicht auf eine Sprache limitiert.


In Ersterem hätte ich persönlich Variablennamen noch kürzer gewählt (succ statt successor z.B.)...aber jeder wie er's mag und braucht.

...

pr ... PivotRow
pc ... PivotColumn


Jetzt will ich zur Abwechslung mal ein Argument hören:

Was hält dich eigentlich wirklich davon ab (Faulheit zählt nicht), statt "pc" oder "pr" die Variablen auf "pivotColumn" oder "pivotRow" auszuschreiben, oder "functionTable" statt "zftab", sodass man eindeutig erkennen kann, worum es geht?


Ist besondere Aufmerksam gegenüber der Formatierung des Codes und der sprechenden Bennenung der Variablen nicht unprofessionell?

Aus welchem guten Grund sollte das so sein?

Ihm
2009-03-19, 21:49:29
Jetzt will ich zur Abwechslung mal ein Argument hören:

Was hält dich eigentlich wirklich davon ab (Faulheit zählt nicht), statt "pc" oder "pr" die Variablen auf "pivotColumn" oder "pivotRow" auszuschreiben, oder "functionTable" statt "zftab", sodass man eindeutig erkennen kann, worum es geht?


Okay, ich habe mir den Spass jetzt komplett durchgelesen. Ich verstehe auch, dass eine eindeutige Bezeichnung von Befehlen/Funktionen der Übersicht dienlicher ist. ABER: Das kann man auch alles in einem höflicheren und vor allem bescheideneren Ton äussern. Deine Art wirkt jedoch sehr arrogant und überheblich. Ich hoffe du liest dir deine ersten Kommentare nochmal in aller Ruhe durch und erkennst was ich meine. ;)

pest
2009-03-19, 21:54:50
Selbsterklärender Code ist nicht auf eine Sprache limitiert.


wie soll das bei assembler gehn? mit makros?

sag mir ernsthaft wie man hier die lesbarkeit erhöhen kann, weil bei sowas habe ich nach ein paar jahren auch probleme

das ist übrigens eine CDF2,2-Wavelet-Tranformation in MMX, ewig alt



[BITS 32]

[GLOBAL _fow_cdf22_row_mmx]

[SECTION .text]
ALIGN 16

cdf22_pdst equ 4+8
cdf22_psrc equ 4+8+4
cdf22_size equ 4+8+8

; cdf-22 forward transform
_fow_cdf22_row_mmx:
push esi
push edi

mov esi,[esp+cdf22_psrc]
mov edi,[esp+cdf22_pdst]
mov edx,[esp+cdf22_size]

pxor mm0,mm0
pxor mm1,mm1
pxor mm2,mm2

movd mm0,[esi] ;process first 2
movd mm1,[esi+4]
movd mm2,[esi+8]

movq mm3,mm0

paddd mm0,mm2
psrad mm0,1
psubd mm1,mm0

movq mm5,mm1

psrad mm1,1
paddd mm3,mm1

movd [edi],mm3
movd [edi+2*edx],mm5

add esi,8
add edi,4

mov ecx,edx ;any left?
shr ecx,1
sub ecx,2
test ecx,ecx
jz _fow_cdf22_row_mmx_l1

_fow_cdf22_row_mmx_l0:
movq mm0,mm2

movd mm1,[esi+4]
movd mm2,[esi+8]

movq mm3,mm0
movq mm6,mm5 ; save last high

paddd mm0,mm2
psrad mm0,1
psubd mm1,mm0

movq mm5,mm1

paddd mm1,mm6
psrad mm1,2
paddd mm3,mm1

movd [edi],mm3
movd [edi+2*edx],mm5

add esi,8
add edi,4

dec ecx
jnz _fow_cdf22_row_mmx_l0

_fow_cdf22_row_mmx_l1:
movd mm1,[esi+4]

movq mm0,mm2
movq mm3,mm2
movq mm6,mm5

psubd mm1,mm0
movq mm5,mm1

paddd mm1,mm6
psrad mm1,2

paddd mm3,mm1
movd [edi],mm3
movd [edi+2*edx],mm5

pop edi
pop esi
ret





Was hält dich eigentlich wirklich davon ab (Faulheit zählt nicht), statt "pc" oder "pr" die Variablen auf "pivotColumn" oder "pivotRow" auszuschreiben, oder "functionTable" statt "zftab", sodass man eindeutig erkennen kann, worum es geht?


also bei zf kann ich mich rausreden, weil man in der mathematik den zielfunktionswert mit zf abkürzt

1. ich bin wirklich zu faul
2. mir fallen kaum aussagekräftige Namen ein, zftab ist da schon das Höchste der Gefühle

wenn ich entwickle ist es auch oft so, das ich am Anfang nicht weiß,
wie sich die Struktur entwickelt, also haben manche Variablen
seltsame Namen, da ich eh weiß das ich da später noch rumwurschtel

Allerdings, um mich zu verteidigen. Ist alles in Klassen verpackt, ließt sich das bedeutend schöner.

Hier in Beispiel aus dem Frontend meines letzten AudioPacker-Projektes,

Lesbarer kann ich nicht ;)
die 30 Zeilen dekodieren eine PCM-Datei, berechnet die MD5-Summe
und kodiert das Signal mit einem verlustfreien Audiopacker




clibSac *libSac = new clibSac(&SacConfig);

GetMemory(BlockAlign,SacConfig.GetMaxSamples(),iWave->GetNumChannels());
cMD5 MyMd5;
if (!MyMd5.SelfTest())
{
printf(" Warning: MD5 Selftest not successfull!\n");
}
MyMd5.Init();

libSac->StartEncoder();

iWave->StartReader();

if ( (CmdOptions.GetStripHdr()) || !(iWave->GetChunks()->GetTotalSize())) oSac->SetUseChunks(false);

oSac->CreateHeader();

int MaxBlockSamples = SacConfig.GetMaxSamples();
while (SamplesLeft)
{
int SamplesToRead = (SamplesLeft < MaxBlockSamples)?SamplesLeft:MaxBlockSamples;

SamplesRead = iWave->ReadSamples((void*)TmpPcmBuf,SamplesToRead);
if (SamplesRead)
{
if (SamplesRead != SamplesToRead) fprintf(dev_out,"\n warning: read over eof (%i Samples missing)!\n",SamplesToRead-SamplesRead);
uint8_t *ptr = (uint8_t*)TmpPcmBuf;
int nsize = SamplesRead*BlockAlign;
MyMd5.Append(ptr,nsize);

mPcm->Decode(pChData,(void*)TmpPcmBuf,SamplesRead);

int BytesEncoded = libSac->Encode((void*)TmpRawBuf,pChData,SamplesRead);
int BytesWritten = oSac->WriteSamples((void*)TmpRawBuf,SamplesRead,BytesEncoded);

td = mTimer.DiffMs(t0,cTimer::rdtsc());
TotSamplesRead += SamplesRead;
SamplesLeft -= SamplesRead;
TotalBytesEncoded = (sint64_t)oSac->GetHandle()->GetPos();
FramesEncoded++;
if (Verbose > 0) PrintProgress(TotSamplesRead,TotNumSamples,TotalBytesEncoded,td,SacConfig.GetSam pleRate());
} else
{
fprintf(dev_out,"\n warning: could not read !\n",SamplesRead);
break;
}
}
char hexmd5[16*2 + 1];
MyMd5.Finish();
MyMd5.Int2Hex(hexmd5);

Trap
2009-03-19, 22:00:06
Aus welchem guten Grund sollte das so sein?
Besondere Codequalität ist offensichtlich für wirtschaftlichen Erfolg nicht nötig und auf unnötige Eigenschaften besonderen Wert zu legen halte ich nicht für professionell.
Was hält dich eigentlich wirklich davon ab (Faulheit zählt nicht), statt "pc" oder "pr" die Variablen auf "pivotColumn" oder "pivotRow" auszuschreiben, oder "functionTable" statt "zftab", sodass man eindeutig erkennen kann, worum es geht?
Dann passt weniger Code in lesbarer Größe ins Blickfeld.

noid
2009-03-19, 22:15:14
@pest: ASM hat Kommentare oder du kannst ihn wegwerfen. Dein Beispiel zeigt zB wie es nicht sein sollte. Da fehlt das 'why', das 'wie' kann man sich schenken.

PS: der PPM-code wäre deutlich lesbarer wenn man nicht 2-3 Zeilen in eine schreiben würde. Und nein, mein alter Informatiklehrer hatte nicht Unrecht, dass man durch logisch formatierten Text bessere Lesbarkeit erzeugt, einfach weil gewisse Strukturen gleich formatiert sein sollten, damit man allein vom groben Sehen sieht was da passiert an Datenfluss. Macht Sinn.
Dh. so einen Unfug wie "If ( dfdf ) sdfsdf; sdfsdf;" macht man nicht. Egal was für ein toller Hecht man doch jetzt sein möge.

PS: http://thedailywtf.com/Articles/ifdef-WTF.aspx - ich hab 80% aller Auflistungen schon bei unseren Projekten entdeckt.
http://thedailywtf.com/Articles/The-How,-Not-the-Why.aspx - das kenn ich auch zur genüge.
Da gibt es viel zu tun ;(

Besondere Codequalität ist offensichtlich für wirtschaftlichen Erfolg nicht nötig und auf unnötige Eigenschaften besonderen Wert zu legen halte ich nicht für professionell.

Dann passt weniger Code in lesbarer Größe ins Blickfeld.

Wozu haben wir große Monitore >30"? ;)

RMC
2009-03-19, 22:18:40
Besondere Codequalität ist offensichtlich für wirtschaftlichen Erfolg nicht nötig und auf unnötige Eigenschaften besonderen Wert zu legen halte ich nicht für professionell.

Ich würds genau umgekehrt sehen.

Wenn ich von meiner Erfahrung ausgehe, schreibt man ein Programm nicht einmal und lässt es dann liegen. Es gibt neue Iterationen mit neuen Features und neue Releases, dazu kommt vielleicht noch eine gemeinsame Codebase für weitere Projekte.

Man muss sich also in gewissen Abständen immer mit altem Code wieder neu beschäftigen. Der wirtschaftliche Erfolg von jeder Iteration hängt auch von der Entwicklungsdauer ab.

Diese kann gering gehalten werden, wenn die Codequalität passt, sowohl von der funktioniellen als auch von der "optischen" Seite. Die Wartbarkeit spielt hierbei eine große Rolle.

Zudem kommt auch noch, dass sich die Belegschaft in einem größeren Team nach einer gewissen Zeit naturgemäß ändert. Irgendwann ist einmal keiner mehr da, den man zu dem Stück Code etwas fragen kann.

Ich hab schon erlebt, dass ganze Projektteile weggeworfen wurden, weil der Programmierer die Firma verlassen hatte und den fürchterlichsten Code fabriziert hat.

Da kam es uns billiger, von vorn anzufangen. Hat auch leider ganz schön gekostet. Darum würd ich schon sagen, dass Qualität eine große Rolle spielt.


Dann passt weniger Code in lesbarer Größe ins Blickfeld.

Kann ich so nicht gelten lassen. Du wirst sicher mehr Zeit brauchen herauszufinden, was für ein Typ "pc" ist, was er speichert, was er bedeutet und wie er mit anderen Variablen zusammenhängt als ein bisschen zur Seite zu scrollen. Außerdem gibts auch die Enter-Taste.


EDIT:
PS: http://thedailywtf.com/Articles/ifdef-WTF.aspx - ich hab 80% aller Auflistungen schon bei unseren Projekten entdeckt.

Ach du scheiße. Und ich dachte die WTFlib wär schon traurig. Vorallem #ifdef DONT_DO_THIS hats mir angetan ;)

Trap
2009-03-20, 00:13:02
Kann ich so nicht gelten lassen. Du wirst sicher mehr Zeit brauchen herauszufinden, was für ein Typ "pc" ist, was er speichert, was er bedeutet und wie er mit anderen Variablen zusammenhängt als ein bisschen zur Seite zu scrollen. Außerdem gibts auch die Enter-Taste.
"using vision to think" ist das Stichwort, es geht mir nicht um die benötigte Zeit für ein erstes Verständnis, sondern um die Zeit in der man auf den bekannten Code guckt und drüber nachdenkt. Je nach Art des Code kann das viel oder wenig sein, je mehr man drüber Nachdenken muss, desto mehr helfen einem kurze Bezeichner. Leider zwingen einen die gängigen Programmiersprachen und Entwicklungsumgebungen zwischen kurzen und sprechenden Namen zu wählen...

Mathematik, Physik und theoretische Informatik benutzen nicht ohne Grund meist sehr kurze Bezeichner in den wissenschaftlichen Arbeiten. Man kann damit einfach mehr gleichzeitig im Blick behalten.

Ich halte Wartbarkeit von Code für einen Begriffsfehler, Code existiert nicht unabhängig von den Menschen die ihn lesen und schreiben. Was heute als wartbarer Code zählt wäre es vor einigen Jahren sicher nicht gewesen. Viel sinnvoller ist der Begriff für Softwareprojekte im Ganzen und da ist personeller Wechsel ohne Wissensweitergabe ein Faktor der die Wartbarkeit verringert. Die Codequalität muss schon unterirdisch sein um für sich allein ein echtes Problem mit der Wartbarkeit zu verursachen.

RMC
2009-03-20, 01:00:10
"using vision to think" ist das Stichwort, es geht mir nicht um die benötigte Zeit für ein erstes Verständnis, sondern um die Zeit in der man auf den bekannten Code guckt und drüber nachdenkt.

Das musst du noch mal ausformulieren ;) Wo ist da der Unterschied? Wenn genug Zeit vergangen ist, sieht der vermeintlich "bekannte" Code genauso aus wie ein x-beliebiger.

Außerdem muss der Code dir selbst ja nicht bekannt sein. Sich in fremden Code einzuarbeiten dauert am Längsten.


Je nach Art des Code kann das viel oder wenig sein, je mehr man drüber Nachdenken muss, desto mehr helfen einem kurze Bezeichner.

Also das find ich recht unlogisch. Warum sollten gerade kurze Bezeichner helfen beim Nachdenken? Ich nehme an du meinst richtig kurze Bezeichner die nicht selbst für sich sprechen, à la "zftab".


Leider zwingen einen die gängigen Programmiersprachen und Entwicklungsumgebungen zwischen kurzen und sprechenden Namen zu wählen...

Wär mir noch nicht untergekommen, dass einen die gängigen Umgebungen und Sprachen zu irgendwas zwingen. Wovon sprichst du? Beschränkung bei der Namenswahl von Variablen?



Mathematik, Physik und theoretische Informatik benutzen nicht ohne Grund meist sehr kurze Bezeichner in den wissenschaftlichen Arbeiten. Man kann damit einfach mehr gleichzeitig im Blick behalten.

1:1 umgesetzte Formeln wären auch die einzige Ausnahme, die ich akzeptieren würde, wobei man dann aber trotzdem sehr aufpassen muss, dass man mit den Bezeichnern nicht durcheinander kommt.


Ich halte Wartbarkeit von Code für einen Begriffsfehler, Code existiert nicht unabhängig von den Menschen die ihn lesen und schreiben.

Sollte er aber. Warum sollte Code abhängig sein von Menschen?


Was heute als wartbarer Code zählt wäre es vor einigen Jahren sicher nicht gewesen.

Aber auch wir entwickeln uns weiter. Nur was damals als gut galt muss heute nicht angebetet werden.


Viel sinnvoller ist der Begriff für Softwareprojekte im Ganzen und da ist personeller Wechsel ohne Wissensweitergabe ein Faktor der die Wartbarkeit verringert.

Auch. Aber oft lässt es sich nicht vermeiden, dass man für ein Gebiet vielleicht nur einen Spezialisten hat.

Natürlich wurde auch die Wissensweitergabe vor Ablöse vollzogen. Hat aber nicht viel bewirkt, denn:

Die Codequalität muss schon unterirdisch sein um für sich allein ein echtes Problem mit der Wartbarkeit zu verursachen.

Die Codequalität hat dazu geführt, dass es irgendwo nicht auffindbare Fehler im System gab (womit wir wieder beim Thema ominöse Zählvariablen in einem nicht durchsichtigen System wären etc.), die sich auch Dank der miesen strukturellen Programmierung nicht vollständig auffinden liesen.

Wer mal vor so einem Problem steht, kann sich entweder sehr sehr lang damit beschäftigen oder das System kübeln und es gleich gscheit machen.

Trap
2009-03-20, 02:28:23
Das musst du noch mal ausformulieren ;) Wo ist da der Unterschied?

Also das find ich recht unlogisch. Warum sollten gerade kurze Bezeichner helfen beim Nachdenken? Ich nehme an du meinst richtig kurze Bezeichner die nicht selbst für sich sprechen, à la "zftab".
Denken ist etwas das man auch mit den Augen macht, je mehr vom Code gleichzeitig scharf zu sehen ist, desto eher fällt einem da etwas auf. So wie wenn man Formeln umstellt, man sieht einfach was man machen muss.

Das ist natürlich erst dann interessant, wenn man weiß was der Code wie macht, aber noch nicht weiß was man daran ändern möchte bzw. wie man die Änderung machen möchte.
Wär mir noch nicht untergekommen, dass einen die gängigen Umgebungen und Sprachen zu irgendwas zwingen. Wovon sprichst du? Beschränkung bei der Namenswahl von Variablen?
Man kann Variablen nicht 2 Namen geben (einen sprechenden und einen kurzen) und in der IDE den angezeigten Namen umschalten.

Softwareentwicklung mit den aktuellen IDEs ist wie CAD mit PovRay...
1:1 umgesetzte Formeln wären auch die einzige Ausnahme, die ich akzeptieren würde, wobei man dann aber trotzdem sehr aufpassen muss, dass man mit den Bezeichnern nicht durcheinander kommt.
Ich meinte Formeln nicht als Beispiel für Sachen, die man direkt mit kurzen Bezeichnern in Code überführen darf, sondern als Beispiel dafür, dass die meisten Menschen von sich aus für Dinge, über die sie lange nachdenken, möglichst kompakte Schreibweisen entwickeln. Es hilft beim Lesen, beim Schreiben und beim Denken.

Bei der Programmentwicklung soll man jetzt aber darauf verzichten, weil die ersten Entwickler von Programmiersprachen dachten, eine Textdatei als Eingabe wäre eine gute Idee und später die economy of scale dafür gesorgt hat, das diese Idee überlebt hat.
Sollte er aber. Warum sollte Code abhängig sein von Menschen?
Solang es noch keine Programme gibt die Programme verändern muss das immer noch ein Mensch machen und zwar nicht ein hypothetischer Mensch, sondern ein ganz konkreter mit Namen, Alter und so weiter. Wartbarkeit ist da zwangsläufig eine Kombination der Eigenschaften des Codes und deren des Menschen der ihn verändert.

Man kann sicher ein paar Sachen allein aus dem Code ablesen, aber Wartbarkeit oder Erweiterbarkeit würde ich nichts davon nennen.
Auch. Aber oft lässt es sich nicht vermeiden, dass man für ein Gebiet vielleicht nur einen Spezialisten hat.

Natürlich wurde auch die Wissensweitergabe vor Ablöse vollzogen. Hat aber nicht viel bewirkt, denn:
Die Codequalität hat dazu geführt, dass es irgendwo nicht auffindbare Fehler im System gab (womit wir wieder beim Thema ominöse Zählvariablen in einem nicht durchsichtigen System wären etc.), die sich auch Dank der miesen strukturellen Programmierung nicht vollständig auffinden liesen.
Das geht aber weit über die von dir kritisierten "falschen" Variablennamen oder Formatierungen hinaus.

Ich hab den Code bei dir nicht gesehen, aber es könnte nach deiner Beschreibung unter "unterirdisch" fallen. Das wird man aber durch Appelle zur Codequalität nicht ändern, wirklich schlechten Code schreibt man nicht aus Faulheit, eher aus Unwissen oder Gleichgültigkeit. Da hilft ein Appell nicht gegen.

RMC
2009-03-20, 08:45:38
Denken ist etwas das man auch mit den Augen macht, je mehr vom Code gleichzeitig scharf zu sehen ist, desto eher fällt einem da etwas auf. So wie wenn man Formeln umstellt, man sieht einfach was man machen muss.

So wie beim Beispiel von Dmitry Shkarin (gepostet von pest) ? ;) Viel Code auf einen Blick, aber kein Durchblick.


Man kann Variablen nicht 2 Namen geben (einen sprechenden und einen kurzen) und in der IDE den angezeigten Namen umschalten.

Ich glaub auch echt nicht, dass man sowas braucht.


Ich meinte Formeln nicht als Beispiel für Sachen, die man direkt mit kurzen Bezeichnern in Code überführen darf, sondern als Beispiel dafür, dass die meisten Menschen von sich aus für Dinge, über die sie lange nachdenken, möglichst kompakte Schreibweisen entwickeln. Es hilft beim Lesen, beim Schreiben und beim Denken.

Eine möglichst kompakte Schreibweise verkompliziert nur den Weg von der visuellen Aufnahme der Codezeile bis letzten Endes zum völligen Verständnis im Zusammenhang mit dem restlichen Code - für andere und auch für einen selbst. Das ist nur unnötig und ineffektiv. Es hilft weder beim Lesen, noch beim Denken.



Das geht aber weit über die von dir kritisierten "falschen" Variablennamen oder Formatierungen hinaus.

Jap. Aber es fängt allein schon damit an :)


Das wird man aber durch Appelle zur Codequalität nicht ändern, wirklich schlechten Code schreibt man nicht aus Faulheit, eher aus Unwissen oder Gleichgültigkeit. Da hilft ein Appell nicht gegen.

Alle deine genannten Gründen spielen zusammen eine Rolle.

Ich meine, lesbaren und selbsterklärenden Code zu schreiben ist etwas, was überhaupt keine nenneswerten Nachteile hat und meiner Erfahrung nach extrem viel bringt :)

Man packt das Problem damit schon an der Wurzel und verhindert die gröbsten Verständnisprobleme von Anfang an.

Wenn der Code lesbar, strukturiert und wartbar bleibt, steigert das die Effizienz und man spart man sich Zeit, Mühe, Nerven und alles in allem Kosten, und das in einer nicht zu unterschätzenden Menge. Stell dir nur mal vor du wirst damit beauftragt, den PPM-Codec von Dmitry Shkarin zu untersuchen, weil ein Fehler vermutet wird ;) Die Zeit die du investierst um das Monstrum zu verstehen und zu debuggen wird erstens kein Mensch der Welt bezahlen wollen weil es einen in der selben Zeit billiger kommt, wenn man das Ganze neu schreibt. Solche Unarten in der Softwareentwicklung verhindern eine effektive Weiterentwicklung.

Es gibt keinen logischen Grund, es nicht zu machen und meiner Meinung nach gehört die Angewohnheit, lesbaren Code zu schreiben, zum professionellen Arbeiten einfach dazu.

pest
2009-03-20, 10:19:55
der Code von Shkarin wird übrigens in WinRAR und WinZIP verwendet

RMC
2009-03-20, 10:42:55
der Code von Shkarin wird übrigens in WinRAR und WinZIP verwendet

Toll, und weiter? Rechtfertigt das etwa den Stil?

pest
2009-03-20, 10:53:13
Toll, und weiter? Rechtfertigt das etwa den Stil?

Die Variablennamen sind aussagekräftig.
Die Datenstruktur ist kompliziert weil sie schnell sein muss, und das schlägt sich auch im Code wieder.

das man nicht alles in eine Zeile quetschen muss ist berechtigt, ansonsten macht der Mann da einfach Magic...und das kann ich beurteilen, weil ich schon mehr als einen PPM-Codec geschrieben habe, die nicht annähernd so schnell waren, und es lag nicht daran das ich die falschen Algorithmen verwendet habe.

und jetzt hör' ich auf Coda und verpiss' mich hier, weil von dir immernoch nix kam, was deine überlegene Codebrillianz bezeugen könnte. Dummschwatzen kann man immer

RMC
2009-03-20, 11:06:28
Die Variablennamen sind aussagekräftig.

Du hast dir den Code scheinbar nicht angesehen.



Die Datenstruktur ist kompliziert weil sie schnell sein muss, und das schlägt sich auch im Code wieder. das man nicht alles in eine Zeile quetschen muss ist berechtigt, ansonsten macht der Mann da einfach Magic

Genau...deswegen seh ich da auch nette gotos mittendrin...it's magic ;D



und jetzt hör' ich auf Coda und verpiss' mich hier, weil von dir immernoch nix kam, was deine überlegene Codebrillianz bezeugen könnte. Dummschwatzen kann man immer

Ich liefere Argumente, alles was du lieferst ist eine programmiertechnische Dummaussage nach der anderen.

Komplizierte Datenstruktur weil der Code schnell sein muss? Aha.

Ich hätte mir eigentlich schon bei dieser Aussage


wenn ich entwickle ist es auch oft so, das ich am Anfang nicht weiß,
wie sich die Struktur entwickelt, also haben manche Variablen
seltsame Namen, da ich eh weiß das ich da später noch rumwurschtel

denken müssen, dass du vollkommen unqualifiziert bist.

pest
2009-03-20, 11:16:00
Du hast dir den Code scheinbar nicht angesehen.


ich weiß was da passiert du nase



Komplizierte Datenstruktur weil der Code schnell sein muss? Aha.


oh man, das ist das dümmste was ich seit langem gelesen habe
natürlich ist ein suffix-tree komplizierter zu programmieren als ne hash-tabelle


denken müssen, dass du vollkommen unqualifiziert bist.

jap, ich code wenigstens und laber nich nur
komm poste einfach mal 30 zeilen von deinem code und ich halte meine fresse
ansonsten stfu

RMC
2009-03-21, 15:19:54
natürlich ist ein suffix-tree komplizierter zu programmieren als ne
hash-tabelle


Sowas bestreit ich auch nicht.

Aber ich weiß worauf du hinaus wolltest: Schneller Code = komplizierte Struktur = zwangsweise unübersichtlich. Bullshit.

ich weiß was da passiert du nase

Das glaub ich dir erstens mal keine Sekunde, und zweitens war das nicht die Frage.

Scheinbar ist es echt sinnlos solchen vernunftsresistenten Menschen wie dir zu erklären, das unter
"aussagekräftig" einfach nicht sowas gemeint sein kann (habe mir spontan eine Funktion rausgepickt, ohne GOTO..war eh schwer eine zu finden):



void PPM_CONTEXT::rescale()
{
UINT OldNU, Adder, EscFreq, i=NumStats;
STATE tmp, * p1, * p;
for (p=FoundState;p != Stats;p--) SWAP(p[0],p[-1]);
p->Freq += 4; SummFreq += 4;
EscFreq=SummFreq-p->Freq;
Adder=(OrderFall != 0 || MRMethod > MRM_FREEZE);
SummFreq = (p->Freq=(p->Freq+Adder) >> 1);
do {
EscFreq -= (++p)->Freq;
SummFreq += (p->Freq=(p->Freq+Adder) >> 1);
if (p[0].Freq > p[-1].Freq) {
StateCpy(tmp,*(p1=p));
do StateCpy(p1[0],p1[-1]); while (tmp.Freq > (--p1)[-1].Freq);
StateCpy(*p1,tmp);
}
} while ( --i );
if (p->Freq == 0) {
do { i++; } while ((--p)->Freq == 0);
EscFreq += i; OldNU=(NumStats+2) >> 1;
if ((NumStats -= i) == 0) {
StateCpy(tmp,*Stats);
tmp.Freq=(2*tmp.Freq+EscFreq-1)/EscFreq;
if (tmp.Freq > MAX_FREQ/3) tmp.Freq=MAX_FREQ/3;
FreeUnits(Stats,OldNU); StateCpy(oneState(),tmp);
Flags=(Flags & 0x10)+0x08*(tmp.Symbol >= 0x40);
FoundState=&oneState(); return;
}
Stats = (STATE*) ShrinkUnits(Stats,OldNU,(NumStats+2) >> 1);
Flags &= ~0x08; i=NumStats;
Flags |= 0x08*((p=Stats)->Symbol >= 0x40);
do { Flags |= 0x08*((++p)->Symbol >= 0x40); } while ( --i );
}
SummFreq += (EscFreq -= (EscFreq >> 1));
Flags |= 0x04; FoundState=Stats;
}



Jetzt mal in einer halbwegs lesbaren Form (OHNE Umbenennung, Auflösung der Verschachtelungen oder Sonstiges)



void PPM_CONTEXT::rescale()
{
UINT OldNU;
UINT Adder;
UINT EscFreq;
UINT i = NumStats;

STATE tmp;
STATE* p1;
STATE* p;

for (p = FoundState; p != Stats; p--)
{
SWAP(p[0], p[-1]);
}

p->Freq += 4;
SummFreq += 4;

EscFreq = SummFreq-p->Freq;

Adder = (OrderFall != 0 || MRMethod > MRM_FREEZE);
SummFreq = (p->Freq = (p->Freq + Adder) >> 1);

do
{
EscFreq -= (++p)->Freq;
SummFreq += (p->Freq = (p->Freq + Adder) >> 1);

if (p[0].Freq > p[-1].Freq)
{
StateCpy(tmp, *(p1 = p));

do
{
StateCpy(p1[0], p1[-1]);
} while (tmp.Freq > (--p1)[-1].Freq);

StateCpy(*p1,tmp);
}
} while (--i);


if (p->Freq == 0)
{
do
{
i++;
} while ((--p)->Freq == 0);

EscFreq += i;
OldNU = (NumStats + 2) >> 1;

if ((NumStats -= i) == 0)
{
StateCpy(tmp,*Stats);
tmp.Freq = (2 * tmp.Freq + EscFreq - 1) / EscFreq;

if (tmp.Freq > MAX_FREQ / 3)
{
tmp.Freq = MAX_FREQ / 3;
}

FreeUnits(Stats, OldNU);
StateCpy(oneState(), tmp);

Flags = (Flags & 0x10) + 0x08 * (tmp.Symbol >= 0x40);

FoundState = &oneState();

return;
}

Stats = (STATE*) ShrinkUnits(Stats, OldNU, (NumStats + 2) >> 1);
Flags &= ~0x08;

i = NumStats;
Flags |= 0x08 * ((p=Stats)->Symbol >= 0x40);

do
{
Flags |= 0x08 * ((++p)->Symbol >= 0x40);
} while (--i);
}

SummFreq += (EscFreq -= (EscFreq >> 1));
Flags |= 0x04;
FoundState = Stats;
}



Jetzt fallen mir spontan "ein paar" Dinge auf, wenn ich nur den Code dieser einen Funktion betrachte:


WAS wird hier rescaled
Wieso hat diese Funktion keine Parameter? Wieviel von was wird wo und überhaupt rescaled?
Wo kommt "NumStats" her, was zählt es? Number of...Statistics?
Was für Zustände speichert "Flags", wo kommt es her? Ist das global? It doesn't fucking tell!
Was zur Hölle ist "FoundState", "MRMethod", "OrderFall", welcher Typ? was mache ich damit? Kann oder DARF ich das verändern, was hat das für Auswirkungen wenn die Funktion das verändert? Warum sind all diese Variablen in keinster Weise gekennzeichnet?
Was ist ein "NU"?
Was added ein "Adder" ?
Wieso wird hier nirgends erklärt, WAS WIESO auf WELCHE ART verändert oder getan wird, wo sind die Kommentare?
OMFG


Dieser Code ist so unbeschreiblich beschissen, mir fehlen echt die Worte. Wie soll da jemals irgendwer wirklich nachvollziehen können, was an welcher Stelle passiert und was wofür verändert wird?

Aber die Variablennamen sind aussagekräftig (O-Ton pest). Und du kannst mir sicher jede einzelne Frage beantworten wenn du nur einmal kurz die Funktion ansiehst :rolleyes:

You really made my day... again :D

Kannst du vielleicht jetzt in irgendeiner Art nachvollziehen, warum gutes Design mit guter Benennung so fundamental wichtig ist? Jeder vernünftige Softwareentwickler wird dir das bestätigen.
Hättest du auch nur die blasseste Ahnung von Softwaredesign, würd ich die Frage gar nicht stellen. Tu dir lieber selbst einen Gefallen und hör auf dauernd solchen abstrusen Aussagen zu machen.

Trap
2009-03-21, 15:57:51
Jetzt mal in einer halbwegs lesbaren Form (OHNE Umbenennung, Auflösung der Verschachtelungen oder Sonstiges)
Ich find das Original lesbarer, allerdings irritiert mich die mehrspaltige Schreibweise auch etwas.

Ich antworte mal in rot in der Liste:


WAS wird hier rescaled
Wieso hat diese Funktion keine Parameter? Wieviel von was wird wo und überhaupt rescaled? Ob da Kommentar fehlt oder nicht kann man nur entscheiden wenn man die üblichen Beschreibungen von PPM kennt
Wo kommt "NumStats" her, was zählt es? Number of...Statistics? Das steht im Kommentar an der Definitionsstelle, die man mit einer Aktion in der IDE erreichen kann
Was für Zustände speichert "Flags", wo kommt es her? Ist das global? It doesn't fucking tell! Da fehlt ein Kommentar, richtig
Was zur Hölle ist "FoundState", "MRMethod", "OrderFall", welcher Typ? was mache ich damit? Kann oder DARF ich das verändern, was hat das für Auswirkungen wenn die Funktion das verändert? Warum sind all diese Variablen in keinster Weise gekennzeichnet?Definitionsstelle und Typ kann die IDE sofort zeigen. Da es eine file-static Variable ist, ist es ein Implementierungsdetail, ob da Dokumentation fehlt kann man nur entscheiden, wenn man den Algorithmus kennt.
Was ist ein "NU"?
Was added ein "Adder" ?
Wieso wird hier nirgends erklärt, WAS WIESO auf WELCHE ART verändert oder getan wird, wo sind die Kommentare? Es ist eine Implementierung eines bekannten Algorithmus, Dokumentation gibt es schon als wissenschaftliche Arbeiten.

RMC
2009-03-21, 16:35:22
Gähn Trap, das sind alles keine Erklärungen sondern schwache Ausflüchte...sehr schwach!


Ob da Kommentar fehlt oder nicht kann man nur entscheiden wenn man die üblichen Beschreibungen von PPM kennt


In der Beschreibung vom PPM Algorithmus steht drin, was sich der Autor beim schreiben SEINER Implementierung mit Zuhilfename einer Funktion gedacht hat, die er "rescale()" nennt? Lächerlich!

Noch was: Der Name "rescale()" gibt keinerlei Auskunft über irgendwas...rescaleMemory? rescaleFrequency? Und da sowohl Parameter und Kommentare fehlen, kann auch kein Mensch auf den ersten Blick daraus schließen, was die Funktion macht. Und das ist allermiesestes Design.


Das steht im Kommentar an der Definitionsstelle, die man mit einer Aktion in der IDE erreichen kann


Das rechtfertigt die schwache Namensgebung nicht und das weißt du.

Übrigens: Bei NumStats steht:


_BYTE NumStats, Flags; // Notes:
_WORD SummFreq; // 1. NumStats & NumMasked contain
_DWORD iStats; // number of symbols minus 1


Number of what Symbols?
Jetzt weiß ich aber noch immer nicht, was "Flags" speichert
Und wo ist die erwähnte Variable NumMasked? Oh...20 Zeilen drunter, in einer Wurst von Definitionen.

static BYTE CharMask[256], NumMasked, PrevSuccess, EscCount, PrintCount;




Definitionsstelle und Typ kann die IDE sofort zeigen.


*sigh*.. Glaubst du ernsthaft, es ist effektiv, während des Lesens zur Definitionsstelle von jeder Variable zu springen um zu sehen, was sie prinzipiell macht?

Das kann man alles mit sinnvollen Namen verhindern.


Da es eine file-static Variable ist


Ok, schön. Sowas kann man mit einem Präfix kennzeichnen. Genauso wie globale Variablen, Membervariablen, Referenzvariablen etc. pp. Dass das eine gängige Art zu Programmieren ist, sollte bekannt sein.


Es ist eine Implementierung eines bekannten Algorithmus, Dokumentation gibt es schon als wissenschaftliche Arbeiten.


Und du kannst mir nimmernoch nicht meine erste Frage beantworten, nämlich, was hier gescaled wird.
Das soll nicht irgendeine verkappte Beschreibung eines Algorithmus klären, sondern der Code!

Trap
2009-03-21, 17:18:03
In der Beschreibung vom PPM Algorithmus steht drin, was sich der Autor beim schreiben SEINER Implementierung mit Zuhilfename einer Funktion gedacht hat, die er "rescale()" nennt? Lächerlich!
Ich hab das PPM-Paper nicht gelesen und hab es auch nicht vor. Aber solche allgemein üblichen Namen für Funktionen sind bei komplexeren Algorithmen häufig. Bei heaps beispielsweise siftup() oder siftdown().
*sigh*.. Glaubst du ernsthaft, es ist effektiv, während des Lesens zur Definitionsstelle von jeder Variable zu springen um zu sehen, was sie prinzipiell macht?
Effektiv ist es sicherlich. Über Effizienz kann man sich streiten, ich würde erwarten, dass man ohne mehrere Stunden Einarbeitung sowieso keine funktionierende Änderung an dem Code machen kann, unabhängig davon wie er formatiert und benannt ist.
Ok, schön. Sowas kann man mit einem Präfix kennzeichnen. Genauso wie globale Variablen, Membervariablen, Referenzvariablen etc. pp. Dass das eine gängige Art zu Programmieren ist, sollte bekannt sein.
Ungarische Notation ist umstritten. Gängige Art zu programmieren ist sie vielleicht, aber sicher nicht die einzig richtige. Kritik für fehlende ungarische Notation ist ungefähr so sinnvoll wie Kritik für die Verwendung von C++.

RMC
2009-03-21, 17:46:02
Ich hab das PPM-Paper nicht gelesen und hab es auch nicht vor. Aber solche allgemein üblichen Namen für Funktionen sind bei komplexeren Algorithmen häufig. Bei heaps beispielsweise siftup() oder siftdown().

Kann sein, aber darum ist es noch lange nicht gut und noch lange keine Begründung, warum das so sein muss :)

Effektiv ist es sicherlich. Über Effizienz kann man sich streiten, ich würde erwarten, dass man ohne mehrere Stunden Einarbeitung sowieso keine funktionierende Änderung an dem Code machen kann, unabhängig davon wie er formatiert und benannt ist.

Jep, Effizienz...my bad.

Bei einem Algorithmus dieser Art braucht man sicher so seine Zeit, das steht außer Frage.

Und grad bei so einem dürftig formatiertem Code und einer so hohen generellen Einarbeitungszeit lässt sich mit wenig Aufwand da sogar extrem viel optimieren.

Ich denke nicht, dass man großartig darüber streiten braucht, denn eigentlich ist sowas offensichtlich. Aber wenn du eine Studie dazu brauchst, ich denke du wirst eine finden.


Ungarische Notation ist umstritten. Gängige Art zu programmieren ist sie vielleicht, aber sicher nicht die einzig richtige. Kritik für fehlende ungarische Notation ist ungefähr so sinnvoll wie Kritik für die Verwendung von C++.

Systems Hungarian oder eine andere ähnlich sinnvolle Abwandlung hätte schon gereicht, um dem Code bedeutend mehr Durchblick zu verschaffen.

pest
2009-03-21, 23:20:05
es handelt sich um den rescale des ppm-models, z.b. wenn der speicher voll ist oder die kompressionsrate sinkt. dazu werden ältere nodes gelöscht, andere runterskaliert usw.

genauso versteht man was variablen wie nummasked machen, wenn man halt ahnung von ppm hat :rolleyes:

deine fragen sind stellenweise so lächerlich, genauso wie iStats z.b., die halt für die Kontextstruktur Verantwortung tragen und die Anzahl der Symbole innerhalb eines Kontextes zählen, SumFreq=kumulative Frequenz usw...selber denken macht schlau, Flags ist nach groben drüberschauen übrigens nen Kontexthash

RMC
2009-03-22, 12:41:35
genauso versteht man was variablen wie nummasked machen, wenn man halt ahnung von ppm hat

Ich hab mir die ppmd lib runtergeladen. Da lag kein Algorithmus bei. Auch die weiterführenden Links zu den Papers enthielten natürlich nicht den Hinweis, was eine Variable wie "nummasked" macht. Wie denn auch.

Und genau das ist es, was keinen Sinn macht:

Die Implementierung wäre ja abhängig von externen Quellen.
Der Code an sich ist vollständig abhängig vom Autor, weil keinerlei Beschreibung, Kommentare oder Sonstige Erklärungen da sind.
Die Struktur und die Benennung sind abhängig von irgendwem, der den Algorithmus irgendwann mal verfasst hat - und das war ein Mathematiker und kein Entwickler,
was uns zu dem Problem bringt, dass eine solche Implementierung nicht wartbar ist. Angenommen es ändert sich etwas an den externen Quellen, und sei es nur, dass die Beschreibung nicht mehr verfügbar ist.

Das ist aus Entwicklersicht designtechnisch suboptimal, was sich aber vermeiden lässt.

deine fragen sind stellenweise so lächerlich

Aus der Sicht eines Softwareentwicklers sind die Fragen alle berechtigt.

Für mich wirkt es extrem lächerlich wenn ein Mathematiker versucht ein Programm zu schreiben, dann sieht man ja was dabei herauskommt :D
Das ist so als würde ein Blinder versuchen ein Auto zu fahren. Es funktioniert irgendwie für wenige Meter geradeaus, aber spätestens bei der ersten Kreuzung hast du einen Unfall mit Totalschaden.

Es gehört zum Programmieren sehr viel mehr dazu als einen Algorithmus einfach nur blind in Befehle umzusetzen. Ich spreche Leuten wie dir nicht die Fähigkeit ab, funktionsfähige Programme zu schreiben. Es ist das wie, das den ausschlaggebenden Unterschied macht ;)


genauso wie iStats z.b., die halt für die Kontextstruktur
Verantwortung tragen und die Anzahl der Symbole innerhalb eines Kontextes zählen,

Soll ich in meine Glaskugel schauen um das zu erraten, oder stundenlang ein Paper durchwühlen nur um draufzukommen, dass es eh nirgends beschrieben ist? :|


usw...selber denken macht schlau

Ne is klar ;D

pest, ich versuch dir hier schon seit ewig argumentativ zu erklären, warum eine Implementierung auf diese Art der letzte Schwachsinn ist, aber du bist entweder zu stur oder zu blöd oder beides, um dich kooperativ zu zeigen.

Du hast nicht einen einzigen haltbaren Punkt aufgezeigt und nur durch unglaubliches Rumgeprolle dein nicht vorhandenes Wissen über Softwaredesign preisgegeben.

Eigentlich wollte ich nicht dass du dumm stirbst, aber ich kann wohl nix dagegen machen.

Coda
2009-03-22, 12:50:47
Wie soll man sich bei dir kooperativ geben, wenn weiter oben Code nur anders hinformatierst und dann unten was von "besserer Softwarearchitektur" laberst?

Unglaublich echt.

Wie gesagt, wer meint Codeformatierung hätte irgendwas mit Codequalität zu tun hat es ganz einfach nicht kapiert. Vor allem wenn es nur um die Stellung der Klammern und ähnlichem geht.

RMC
2009-03-22, 13:08:40
Wie soll man sich bei dir kooperativ geben, wenn weiter oben Code nur anders hinformatierst und dann unten was von "besserer Softwarearchitektur" laberst?

Das war ja klar dass du nur die Hälfte lesen kannst. :mad:

Ich hab ihn einfach mal formatiert OHNE Umbenennung und Auflösung der Verschachtelung, das hab ich extra hingeschrieben.

Neben der miesen Struktur konnte man die Funktionen nicht als abgeschlossenes System betrachten (siehe "rescale()"). Es gibt keine Übersicht. Stattdessen wurden globale und statische Variablen querdurch verwendet, verändert, und wiederverwendet. Es gibt keine Datenkapselung, keine eingehaltenen Sichtbarkeitsregeln. Die Verbindungen zu anderen Programmteilen lassen sich graphsich gar nicht darstellen.

Das ist beschissene Softwarearchitektur höchsten Grades. Die Fragen dazu haben das reflektiert.

Was willst du eigentlich noch hören? Die Formatierung ist beschissen, die Benennung ist beschissen, es gibt überhaupt keine Architektur, nur einen abgeschriebenen Algorithmus, der beschissen prozedural umgesetzt ist.


Wie gesagt, wer meint Codeformatierung hätte irgendwas mit Codequalität zu tun hat es ganz einfach nicht kapiert.

Das hast du schon mal gesagt und es ist genauso langweilig wie beim ersten Mal.

Coda
2009-03-22, 13:22:00
Neben der miesen Struktur konnte man die Funktionen nicht als abgeschlossenes System betrachten (siehe "rescale()"). Es gibt keine Übersicht. Stattdessen wurden globale und statische Variablen querdurch verwendet, verändert, und wiederverwendet. Es gibt keine Datenkapselung, keine eingehaltenen Sichtbarkeitsregeln. Die Verbindungen zu anderen Programmteilen lassen sich graphsich gar nicht darstellen.
Gut, das gesteh ich dir ein - falls es wirklich so ist.

Ich mag deine Art wie du hier auftrittst trotzdem nicht, vor allem in Hinblick wie du über WebKit u.ä. lästerst. Das einzige was man da nach der Herangehensweise nämlich kritisieren könnte ist die Codeformatierung und Variablenbenennung, und das ist nun mal auch Geschmackssache bzw. Gewohnheit.

pest
2009-03-22, 13:40:53
Auch die weiterführenden Links zu den Papers enthielten natürlich nicht den Hinweis, was eine Variable wie "nummasked" macht. Wie denn auch.

Und genau das ist es, was keinen Sinn macht:

Die Implementierung wäre ja abhängig von externen Quellen.


lol, das ist ein ppm-algorithmus...wenn du wissen willst wie der code funktioniert, solltest du schon wissen wie ppm funktioniert

nummasked ist dann logischerweise die anzahl der symbole die von einem kürzeren kontext maskiert werden und deshalb zur wahrscheinlichkeitsberechnung ausmaskiert werden können.

und dmitry hat den algorithmus nicht blind abgetippt...er hat den ursprünglichen ppm-algorithmus verbessert. das heißt bevor du seine paper ließt, solltest du die anderen lesen.


Der Code an sich ist vollständig abhängig vom Autor, weil keinerlei Beschreibung, Kommentare oder Sonstige Erklärungen da sind.


wenn du keinen plan von dem algorithmus hast, solltest du dich nicht beschweren, leute wie du sollen an sowas auch nicht rumspielen, das ist nicht böse gemeint


Es funktioniert irgendwie für wenige Meter geradeaus, aber spätestens bei der ersten Kreuzung hast du einen Unfall mit Totalschaden.


deine arroganz ist lächerlich, und nicht mathematiker die coden


Soll ich in meine Glaskugel schauen um das zu erraten, oder stundenlang ein Paper durchwühlen nur um draufzukommen, dass es eh nirgends beschrieben ist


was stimmt eigentlich mit dir nicht? natürlich musst du paper lesen!
...scheinbar hört dein algorithmenverständnis bei quicksort auf
woher weiß ich denn was die variablen machen? ich habe da genauso lang draufgeschaut wie du...


Eigentlich wollte ich nicht dass du dumm stirbst, aber ich kann wohl nix dagegen machen.


ja mei, damit komme ich klar...
wie kann man erwarten das sich einem durch den quellcode ein komplizierter algo offenbart? ;D

das zeigt mir einfach nur das du noch nie etwas in die richtung getan hast, denn dann wüsstest du, das die erste "working" version oft sehr lesbar ist und
im optimierungsprozess vieles davon dem rotstift zum opfer fällt.
ich könnte dir zig beispiele von mir aus der vergangenheit nennen wo das der fall war...und auch beispiele posten, ob es wikisnippets sind oder ähnliches usw...

und da du jetzt wieder "nein das muss nicht sein" antworten wirst, bleibe ich bei meiner meinung

auf deine bornierte stupidität geb ich garnix, da muss erstmal was kommen, ausser dein gelaber...nenn mich gern prollig...ich hab gezeigt was ich kann, im gegensatz zu der heißen kuft von dir

und da ich schon ne verwarnung kassiert habe, bist du einfach nen neues mitglied auf meine igno :)

RMC
2009-03-22, 14:31:44
Ich mag deine Art wie du hier auftrittst trotzdem nicht, vor allem in Hinblick wie du über WebKit u.ä. lästerst. Das einzige was man da nach der Herangehensweise nämlich kritisieren könnte ist die Codeformatierung und Variablenbenennung, und das ist nun mal auch Geschmackssache bzw. Gewohnheit.

Macht nix, ich mag auch die Art vieler anderer hier nicht ;) Dass du das mit WebKit in den falschen Hals gekriegst hast mag daran liegen wie ich reagiert hab als du an mich auch nicht grad fein herangetreten bist ;)

Nö, WebKit ist ja sicherlich in Ordnung von seiner Architekturseite, das hab ich auch nie gemeint :). Auch ist es generell eh sauber geschrieben und kommentiert, muss ich schon sagen. Ich hab ja jetzt andere Abgründe gesehen ;) Ich bin es halt gewohnt, noch sauberer zu arbeiten und die Leute in meinem Umfeld tun selbiges.

Ja, man kann sicher noch etwas verbessern hinsichtlich der Überschaubarkeit und Benennung.

zB das hier ist ein klassisches Beispiel:

if (!BOp || !(isa<BinaryOperator>(BOp) || isa<CmpInst>(BOp)) ||
(unsigned)BOp->getOpcode() != Opc || !BOp->hasOneUse() ||
BOp->getParent() != CurBB->getBasicBlock() ||
!InBlock(BOp->getOperand(0), CurBB->getBasicBlock()) ||
!InBlock(BOp->getOperand(1), CurBB->getBasicBlock())) {


Oder eben die ellenlangen switches (die man sicherlich kürzen kann, und seis nur der Übersicht halber) in denen wichtige Funktionsparameter nicht gut benannt sind.

Sind jetzt natürlich nur Kleinigkeiten, aber grad weil der restliche Code sauberer ist fallen mir dann solche Sachen schneller auf.


@pest

baba und fall net.

#44
2009-03-22, 18:39:16
Effektiv ist es sicherlich. Über Effizienz kann man sich streiten, ich würde erwarten, dass man ohne mehrere Stunden Einarbeitung sowieso keine funktionierende Änderung an dem Code machen kann, unabhängig davon wie er formatiert und benannt ist. Formatierung an sich ist wirklich kein Thema. Gibt ja Tools die einem das so Zaubern wie man es bevorzugt.

Aber die Benennung macht dann nochmal einen 'Bonus' aus, den man Zusätzlich aufbringen muss um es zu verstehen. Was bei komplexem Code die Schwierigkeit weiter steigert.

Das man, wenn man will oder muss, fast alles verstehen kann, beweisen Deutschlehrer tagtäglich. Ich bezweifle aber, das sie nicht lieber Schiller & Co. lesen würden...


Ansonsten: http://www.osnews.com/story/19266/WTFs_m
:wink:

Trap
2009-03-22, 19:15:25
Aber die Benennung macht dann nochmal einen 'Bonus' aus, den man Zusätzlich aufbringen muss um es zu verstehen. Was bei komplexem Code die Schwierigkeit weiter steigert.
Wer versucht, den ppm-Code aus dem Code heraus zu verstehen, sollte daran sowieso besser nichts ändern.

Man muss die 2-3 gebräuchlichsten wissenschaftlichen Arbeiten zum Thema ppm gelesen und verstanden haben, dann kann man den Code angucken, nachvollziehen, kritisieren oder verändern. Vorher ist es völliger Unfug. Bisher hat niemand mit ppm Hintergrundwissen die Bennenungen kritisiert.

Die Kriterien zur Bewertung von Code müssen der Funktion des Code angepasst sein. Eine Bibliothek zur Implementierung bereits dokumentierter komplexer, generischer Algorithmen ist da was ganz anderes als anwendungsspezifische Sachen, die im Laufe des Projekts von vielen Leuten immer weiterentwickelt werden.

#44
2009-03-22, 20:31:27
Das mag sein, aber als sich die Diskussion ankündigte, (nach dem 2. Post) war von etwas so speziellem nicht die Rede.

robobimbo
2009-03-22, 21:32:28
Ohne hier jetzt auf die Diskussion eingehen zu wollen, weils ja eigentlich eh schon 3 Lichtjahre OffTopic ist, möcht ich hier noch einen Buchtipp anbringen, ich habs zuerst auch ein wenig mit schmunzeln gesehen - mir aber dann trotzdem zugelegt, und viele (nicht alle) anregungen da drinnen sind hilfreich und gute Denkanstösse.

Und nein, ich verdien nix dran ;)

http://www.amazon.de/Clean-Code-Handbook-Software-Craftsmanship/dp/0132350882/ref=sr_1_1?ie=UTF8&s=books-intl-de&qid=1237753811&sr=8-1