Thread Array of Hashes aus Datei anlegen (53 answers)
Opened by Flips87 at 2020-02-04 11:19

Raubtier
 2020-02-06 00:28
#191318 #191318
User since
2012-05-04
1054 Artikel
BenutzerIn

user image
2020-02-05T19:23:49 hlubenow
2020-02-05T11:58:33 Raubtier
Ich frage mich, was du (hlubenow) da kompliziertes mit dem getCount erreichen willst.

Du findest meine Funktion kompliziert, ich finde
Code (perl): (dl )
++$wordCounter{$word};

kompliziert. Da muß man ja erstmal nachdenken.


Spannend, weil es mit genau andersrum geht.

Aber es ist nicht nur die Syntax, die ich meinte. Ich musste bei deinem Code erstmal verstehen, wie du das Problem überhaupt löst.

Überlegen wir doch erstmal, wie wir das Problem von Hand lösen würden. Also die Häufigkeit für jedes Wort aus einer Liste von Wörtern zu ermitteln. Nehmen wir mal eine ganze Buchseite als Beispiel.

Mein Programm schaut sich jedes Wort einmal an, guckt auf einer Strichliste nach und macht dort einen Strich hin. Wenn ich damit fertig bin, gebe ich die Strichliste zurück. Fertig. Dabei geht das Finden in der Strichliste schnell, weil diese als Hash gemacht ist. Es soll ja in der Aufgabe auch nicht zufällig ein Hash für Wort->Anzahl erzeugt werden.

Schauen wir mal an, wie dein Programm das macht. Du schaust dir zunächst das erste Wort an. Dann gehst du durch die gesamte Liste an Wörtern (von vorne bis hinten) und zählst, wie oft das Wort vorkommt und notierst das auf deiner Strichliste. Dann machst du das mit dem nächsten Wort und so weiter. Wenn du auf ein Wort triffst, für das du die Anzahl bereits kennst, streichst du den alten Eintrag in deiner Strichliste aus und zählst zur Sicherheit nochmal nach. Dann schreibst du diesen Wert wieder in die Strichliste.

Ich brauche also Anzahl_Wörter Schritte für die Lösung. Du brauchst Anzahl_Wörter*Anzahl_Wörter Schritte für deine Lösung. Das erscheint mir wesentlich komplizierter. Zumal du ja auch den Hash am Ende als Ergebnis hast, aber ihn unterwegs gar nicht nutzt.

Quote
Und das auch noch mit dem "++" davor, obwohl der Ausdruck gar nicht zugewiesen oder ausgewertet wird.


Naja, ++ davor sollte halt der Standard für 1 dazuaddieren sein. Meinetwegen schreibst du halt $hash{$key} += 1;, aber ich finde ein ++ schön kurz und einfach. Ich verstehe deinen obwohl-Satz nicht. Was meinst du damit?


Quote
Raubtier
Außerdem hast du extrem viele globale Variablen (schlecht!)

Och, bei so einem kurzen Skript fällt das, glaube ich, nicht weiter ins Gewicht. Ich nehm' mir halt so viele Variablen, wie ich möchte. Dann kann man auch später leichter nachvollziehen, was da vor sich ging.


Es ist eben unübersichtlich.

Warum bevorzugst du
Code (perl): (dl )
1
2
3
4
5
6
my $x;  # erzeuge Variable $x mit Wert undefined
for $x (@liste) {  # loope mit $x über die Liste
   ...
}
# hier ist $x immer noch gültig. Was für einen Wert hat es (war
# vielleicht ein last in der loop)? Wofür brauchst du hier noch das $x?

statt
Code (perl): (dl )
1
2
3
4
5
for my $x (@liste) {  # loope mit $x über die Liste
   # $x ist nur hier im Loop-Body gültig.
   ...
}
# $x nicht mehr da. Du brauchst die keine Gedanken mehr über $x zu machen


Also: Keep scopes small! (für C++ gilt das genauso, da steht das sogar in den C++ Core Guidelines und hier - das gilt aber für Perl ganz genau so)
Zitat von da: "Reason Readability. Minimize resource retention. Avoid accidental misuse of value." Das ganze Dokument ist übrigens lesenswert, viele Dinge davon kann man leicht auf andere Sprachen übertragen. Aber Achtung: natürlich gibt es auch Dinge, die man in anderen Sprachen anders macht. Also: Leseempfehlung, für die hier angesprochenden Dinge der Abschnitt ES.

Quote
Aber klar, ich bin nur ein Hobby-Programmierer, der Perl (und auch Python) eher so schreibt, wie Anfänger es tun würden.


Warnung: in Python ist Scoping anders! Da ist eine in einem Block (=in einer Einrückung) definierte Variable nicht am Einrückungsende weg, sondern lebt weiter.

Quote
Das auch absichtlich, wegen der Lesbarkeit.

Dann muss ich aber erstmal verstehen, was die vielen Zeilen für die Loop eigentlich erreichen wollen, denn kommentiert hast du nichts. Mein Ratschlag wäre dann: dokumentiere für jede Funktion (die nicht komplett selbsterklärend ist), was sie tut und was ihre Eingabe- und Ausgabewerte sind. Und gutes Naming! getCount klingt nach einem Getter. Und getCount kann alles mögliche sein. Ein besserer Name wäre zum Beispiel gewesen: countElementInList oder ähnlich. Boah, lang und clumsy. Naming ist erschreckend schwierig.

Ginge übrigens auch so:
Code (perl): (dl )
1
2
3
4
5
6
7
use List::Util qw(sum);
my @words = qw(hallo du hallo sonstwer);
my $anzahlHallo = sum map {$_ eq "hallo"} @words;

# oder auch
use List::MoreUtils qw(true);  # hier hätte ich n_true o.ä. besser gefunden als Namen
my $anzahlHallo = true {$_ eq "hallo"} @words;


Es schadet also auch nicht, ggf. mal zu schauen, ob es eine entsprechende Funktion bereits fertig gibt :-)

Quote
Aber gerade bei solchen Aufgaben findet der Lehrer es bestimmt nicht schlecht, wenn man nicht alles verkürzt oder im Extremfall einen Code hat, der z.B. nur noch aus RegExes und map()-Zeilen besteht.


Schon, aber hier soll ein Hash erzeugt werden und du machst eine selbstgemachte Loop, ohne die Hash-Vorteile zu nutzen. Erscheint seltsam.
Last edited: 2020-02-06 00:48:26 +0100 (CET)

View full thread Array of Hashes aus Datei anlegen