Schrift
[thread]724[/thread]

Perlskript

Leser: 1


<< >> 9 Einträge, 1 Seite
Gast Gast
 2006-05-09 22:39
#7549 #7549
Hi.

Ich bin Anfänger in Programmierung. Im Programm geht es um's Berechnen von dem arithmetischen Mittel der Buchstaben in einem englischen Text. Ich versuche das Programm zu verstehen.
Hier ist der Skript:
#Perlskript "word_stat.pl":
#########################################################################
Code: (dl )
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
#!/usr/bin/perl
use strict;
for(my $i=0; $i<@ARGV; $i++) { process($ARGV[$i]); }
sub process {
     my ($file, $n, $avg, $s2, $median, %len_stat) = $_[0];
     open(FILE, $file) or die;
     foreach my $line (<FILE>) {
           chomp($line);
           if($line =~ /(\w+)$/) { # verarbeitet auch Frequenzlisten
                my $len = length($1);
                $len_stat{$len}++;
                $avg += $len;
                $n++;
           }
     }
     close(FILE);
     # arithmetisches Mittel
     $avg /= $n;
print("$avg\n");
}


Meine Fragen:
1) Was könnte @ARGV sein. Wenn ich das richtig verstehe, sollte es ein Array sein, aber was ist den da gespeichert und warum wurde er vorher nicht deklariert
2) Was bedeutet volgende Zeile
my ($file, $n, $avg, $s2, $median, %len_stat) = $_[0];
und zwar '$_[0]'
3) was wird hier gemacht
{ process($ARGV[$i]); }
4)Die 'print' Funktion hab ich selbst dazugeschrieben, wenn ich aber das Programm starte, wird kein Ergebnis ausgegeben

Ich freue mich um die Antworten und bitte um möglichst dettalierte Erklärungen
Danke\n\n

<!--EDIT|GwenDragon|1147200170-->
GwenDragon
 2006-05-09 22:48
#7550 #7550
User since
2005-01-17
14533 Artikel
Admin1
[Homepage]
user image
1) In @ARGV stehen die Parameter der Kommandozeile, die an das Perlskript übergeben werden
2) $_[0] enthält die an die Funktion process übergebene Parameter
3) Es wird die Funktion process mit dem Parametern aus @ARGV aufgerufen
4) es fehlen die Parameter, die du beim Starten des Skripts eingeben musst\n\n

<!--EDIT|GwenDragon|1147201339-->
die Drachin, Gwendolyn


Unterschiedliche Perl-Versionen auf Windows (fast wie perlbrew) • Meine Perl-Artikel

lichtkind
 2006-05-09 23:15
#7551 #7551
User since
2004-03-22
5679 Artikel
ModeratorIn + EditorIn
[Homepage]
user image
das skript berechnet die durchschnittliche wortlänge und legt eine statistik darüber an wie oft welche länge vorkam
Wiki:Tutorien in der Wiki, mein zeug:
kephra, baumhaus, garten, gezwitscher

Es beginnt immer mit einer Entscheidung.
Gast Gast
 2006-05-10 12:34
#7552 #7552
[quote=GwenDragon,09.May.2006, 20:48]1) In @ARGV stehen die Parameter der Kommandozeile, die an das Perlskript übergeben werden[/quote]
cat tok_? | tee tokens | sort | uniq -ci | sort -nr > frequenz
./word_stat.pl tok* freq*

Das war der Aufruf für das Program. Wird dann der Array @ARGV immer Automatisch erzeugt. Wenn 'ja', an welcher Stelle?
lichtkind
 2006-05-10 12:48
#7553 #7553
User since
2004-03-22
5679 Artikel
ModeratorIn + EditorIn
[Homepage]
user image
@ARGV existiert immer ob leer oder nicht, und befüllt wird er bevor eine zeile deines codes ausgeführt wird.

was sollen die sternchen eigentlich in deinen parametern. ich nehme an sie werden nicht das tun was du beabsichtigst.
Wiki:Tutorien in der Wiki, mein zeug:
kephra, baumhaus, garten, gezwitscher

Es beginnt immer mit einer Entscheidung.
Taulmarill
 2006-05-10 13:16
#7554 #7554
User since
2004-02-19
1750 Artikel
BenutzerIn

user image
ok, also erst mal zur zeile
Code: (dl )
for(my $i=0; $i<@ARGV; $i++) { process($ARGV[$i]); }

wenn man über einen array iteriert kann man das auch direkt tun, mit foreach. da for ein alias für foreach ist, können wir das folgendermassen schreiben
Code: (dl )
for my $arg ( @ARGV ) { process( $arg ) }

jetzt müssen wir nur noch was mit den sternchen machen, da diese nicht von der shell, sondern von deinem program in eine liste von dateinamen umgewandelt werden muss. dafür kann man die funktion glob benutzen, das bringt uns zu folgendem
Code: (dl )
1
2
3
4
5
for my $glob ( @ARGV ) {
for my $file ( glob $glob ) {
process $file;
}
}

oder etwas abgekürzt:
Code: (dl )
process $_ for map glob, @ARGV;

ich hoffe das bringt dich schon mal einen schritt weiter.
$_=unpack"B*",~pack"H*",$_ and y&1|0& |#&&print"$_\n"for@.=qw BFA2F7C39139F45F78
0A28104594444504400 0A2F107D54447DE7800 0A2110453444450500 73CF1045138445F4800 0
F3EF2044E3D17DE 8A08A0451412411 F3CF207DF41C79E 820A20451412414 83E93C4513D17D2B
bloonix
 2006-05-10 13:29
#7555 #7555
User since
2005-12-17
1615 Artikel
HausmeisterIn
[Homepage]
user image
[quote=Katya,09.05.2006, 20:39]Ich freue mich um die Antworten und bitte um möglichst dettalierte Erklärungen[/quote]
Erklärungen gab es ja schon genug... ich hätte da ein paar
Dinge zur Syntax auf dem Herzen... :)

Code: (dl )
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
#!/usr/bin/perl
use strict;
use warnings;

# In @ARGV stehen standardmaessig alle Argumente, die ueber die
# Kommandozeile mitgegeben wurden. Hier wird das @ARGV Array
# mittels der for-Schleife durchlaufen. Jedes Element wird
# im Angeloperator $_ abgelegt. Uebersetzt koennte man es so
# beschreiben:
#    schreibe den Rueckgabewert von process($_) fuer jedes Element von @ARGV
print process($_), "\n" for @ARGV;

sub process {
  # mit shift wird das Array @_ um den ersten Wert gekürzt und
  # dieser Wert wird in $file gespeichert.
  # In @_ sind die Argumente abgelegt, die der Funktion mitgegeben
  # werden. @_ kann man mit @ARGV vergleichen.
  my $file = shift;
  my ($n,$avg);

  # ich habe deine runden Klammern etc. einfach mal weggelassen,
  # weil es mein Schreibstil ist und es mir optisch besser gefaellt :-)
  # wenn ein Skript mit "or die" beendet wird, dann vergiss
  # $! nicht, denn darin steht, weshabl "open" eventuell fehlschlägt
  open FILE,'<',$file or die $!;

  # Filehandles sollten immer mit einer while-Schleife durchlaufen
  # werden. Das hat wohl was mit dem Erkennen von eof (End-of-File)
  # zu tun...
  while (my $line = <FILE>) {
     chomp($line);

     # ein 'next' ist in diesem Fall optimal, damit sofort die
     # naechste Zeile bearbeitet werden kann und die Schleife
     # nicht erst noch nach Anweisungen nach deinem if sucht
     next unless $line =~ /(\w+)$/;
     my $len = length($1);
     $avg += $len;
     $n++;
  }
  close FILE;
  # arithmetisches Mittel + Rueckgabe des Wertes
  return $avg / $n;
}
\n\n

<!--EDIT|opi|1147262454-->
What is a good module? That's hard to say.
What is good code? That's also hard to say.
One man's Thing of Beauty is another's man's Evil Hack.
Dubu
 2006-05-11 10:00
#7556 #7556
User since
2003-08-04
2145 Artikel
ModeratorIn + EditorIn

user image
[quote=Taulmarill,10.05.2006, 11:16]jetzt müssen wir nur noch was mit den sternchen machen, da diese nicht von der shell, sondern von deinem program in eine liste von dateinamen umgewandelt werden muss.[/quote]
Nö, dafür ist die Shell zuständig.
Dubu
 2006-05-11 10:06
#7557 #7557
User since
2003-08-04
2145 Artikel
ModeratorIn + EditorIn

user image
[quote=opi,10.05.2006, 11:29]
Code: (dl )
1
2
3
   # Filehandles sollten immer mit einer while-Schleife durchlaufen
  # werden. Das hat wohl was mit dem Erkennen von eof (End-of-File)
  # zu tun...
[/quote]
Nein.
Das hat damit zu tun, dass bei einer for- bzw. foreach-Schleife erst die zugehörige Liste aufgebaut wird. Wenn man also über einen Diamond-Operator iteriert, wird erst die gesamte Datei eingelesen, bevor die Schleife anfängt. Bei einer while-Schleife wird die Datei dagegen Element für Element, also normalerweise zeilenweise eingelesen.
<< >> 9 Einträge, 1 Seite



View all threads created 2006-05-09 22:39.