Textverarbeitung mit Perl

Perl Praxis 5

In dieser Übung wird weiter mit tr/// gearbeitet, mit Hashes experimentiert und geübt, wie Dateien per "file handles" eingelesen und geschrieben werden können. Weiterhin muss ein Programm eigenständig geplant und ausgeführt werden.


Programmierpraxis
Bei der folgenden Aufgabenstellung habt ihr schon alle notwendigen Perlkenntnisse, um diese Aufgabe zu lösen. Es geht hier darum, ein Programm eigentständig zu planen und dann auszuführen.

Übung 5.1. Schreib ein Programm, das das längste und kürzeste Wort von emerald.txt oder hexe.txt ausgibt.
Übung 5.2. Falls es mehr als ein kürzestes oder längstes Wort gibt, dann merke dir all diese (in einer Liste, z.B.) und gib sie in alphabetischer Ordnung aus.

Das folgende Programm ist eine Version von lists.pl aus Perl Praxis 4. Ein Unterschied ist, dass es den Benutzer nach der gewünschten Anzahl von Buchstaben fragt, und die Datei innerhalb des Programms aufruft. Weiterhin werden die gefundenen Worte nicht einfach im Terminal ausgedruckt (STDOUT=standard output), sondern werden in eine Datei geschrieben und dort abgespeichert. Dieses Programm muss also nur einfach so aufgerufen werden: perl lists2.pl.

File Handles
#!/usr/local/bin/perl

#sucht nach Worten mit N Buchstaben, und tut sie in eine Liste. 
#liest von einer Datei

#lists2.pl 

    print "Wieviele Buchstaben sollen die Worte haben?\t"; 
    $num = <STDIN>;
    chomp $num; 
print "Die Worte sollen $num Buchstaben haben.\n\n"; 


open FILE, "hexe.txt";   #oeffnet unsere Datei 


while (<FILE>) {   #geht durch die Datei
    chomp;
    tr/;:,.!-'"'?//d;
    foreach $w (split) {
    	if (length($w) == $num) {
            push @words, $w; 
            $score++;
        }
    }        
}         

close FILE;  #schliesst die gelesene Datei

#oeffnet eine andere Datei zum schreiben

open OUTPUT, ">hexe-resultat.txt" or die("not possible"); 

print OUTPUT "@words\n"; 

close OUTPUT;
          
print "\n$score Worte mit $num Buchstaben in dieser Datei.\n";
print "Die Worte sind in der Datei hexe-resultat.txt.\n\n";

Übung 5.3. Kopiere oder tippe das Programm in einen Editor und probiere es aus. Sei dir sicher, dass du das Programm verstehst. Die Datei hexe-resultat.txt kann man entweder im Editor aufrufen und inspizieren, oder mit dem Unix Kommando more am Prompt: more hexe-resultat.txt.
Übung 5.4. Ändere das Programm, so dass die if-Kontrollstruktur durch ein else erweitert wird. Der Effekt sollte der sein, dass wenn ein Wort nicht auf die Spezifierung passt, es in eine andere Liste getan wird. z.B. @otherwords.
Übung 5.5. Ändere das Programm weiter, so dass diese Liste von anderen Worten auch in eine Datei gesschrieben wird. Dem Benutzer sollte gesagt werden, wie diese Datei heisst.
Übung 5.6. Nun ändere das Programm, so dass der Benutzer eingeben kann, wie die Output-Datei zu heissen hat. D.h., frage den Benutzer und hebe die Antwort in einer Variable auf, z.B. $output (analog zu der Frage nach der Zahl). Dann öffne die Datei mittels open so: open OUTPUT, ">$output" und schreibe die Resultate da hinein (Strategie wie bisher, aber dem Benutzer muss natürlich nochmal gesagt werden, in welcher Datei das Resultat jetzt ist).


Das nächste Programm zeigt, wie man mit Hashes arbeiten kann.

Hash Datenstruktur
#!/usr/local/bin/perl
#erstellt Wortfrequenzen 

#wordcount.pl FILE

while (<>) {
    chomp;
    tr/A-Z/a-z/;    #alles klein geschrieben
    tr/;:,.!-'"'?{}{}//d;   #Satzzeichen weg
    foreach $wd (split) {   #fuer jedes Wort
        $count{$wd}++;     #zaehle es.  $wd ist der key
	                   # wie oft es aufgetaucht ist der value 
                           # count ist der Name des Hash
                           #Neue Elemente werden generell so in den
                           #Hash getan (coins Beispiel:)
                           #  $coins{Penny} = 1;  Penny ist Key, 1 ist Value
                           # Was hier passiert ist eigentlich:   $count{$wd} = $count($wd) + 1
                           #d.h., zu dem Wert/value von $wd (key) im Hash %count wird plus 1 hinzugezaehlt. 
                           #es wird gezaehlt und das Gezaehlte
                           #wird gleichzeitig in den Hash %count als Wert/Value getan. 
    }        
}         

foreach $w (keys %count) {    #fuer jedes Wort ($w = key), gehe durch den
                              #Hash %count durch, und drucke den Wert/value
                              #($count{$w}, wo $w den key repraesentiert
                              #wert=wie oft es das Wort im Text gab
    print "$count{$w} : $w\n";
}

Übung 5.7. Kopiere oder tippe das Programm in einen Editor und probiere es mit hexe.txtoder emerald.txt aus.
Übung 5.8. So wie das Programm jetzt steht, ist der Output relativ unsortiert. Sortiere den Output mittels sort, so dass die Worte alphabetisch wiedergegeben werden: foreach $w (sort keys %count).
Übung 5.9. Man kann den Hash auch noch trickreicher einsetzen. Z.B. könnte man anstatt dem Wort, etwas anderes als key benutzen. Nimm als key die Länge des Wortes (per length operator). Als Wert, zähle nach, wie oft ein Wort dieser Länge gefunden wurde. Dann drucke das Resultat aus, z.B., dass man folgendes erfährt:
39 Worte mit 2 Buchstaben
11 Worte mit 10 Buchstaben


Julius Caesar hatte einen privaten Verschlüsselungscode benutzt. Der ging so:

A -> C
B -> D
C -> E
...
X -> Z
Y -> A
Z -> B

Zur Erinnerung: der tr/// Operator
#/usr/local/bin/perl -w
#playing with tr///
#tr.pl

$text = 'some cheese';
$text =~ tr/ce/XY/;
print "$text\n";

Das Program zeigt ein Beispiel, wie der tr/// Operator funktioniert. Der Binding Operator wird durch =~ kodiert. Der Effect dieses Operators ist es, Muster zu vergleichen (pattern matching): das Muster (bzw. der Text) auf der linken Seite des Operators (also $text oben), wird mit dem in tr/// angegeben Muster verglichen. Default Vergleich für Perl ist $_.
Übung 5.10. Schreibe ein Programm, dass die Verschlüsselung mittels dem tr/// Operator umsetzt. Probiere das Program an emerald.txt oder hexe.txt aus und schreib die Resultate in eine Datei aus.



Bitte die Übungen bis 2.7. an Anja Leiderer schicken!

Ende