davidik
Anmeldungsdatum: 20. November 2014
Beiträge: 42
|
Sehr geehrte Perl Nutzer und Versteher, Ich würde gerne eine .dat datei erstellen mit 20 zufällig generierten Zeilen mit jeweils 100 Ziffern.
Diese will ich dann einlesen und für jede einzelne Zeile die Summe bilden als für alle 100 Ziffern → Das Ergebnis soll im Terminal folgendermaßen ausgegeben werden → Summe Zeile 1: ... Summe Zeile 2: etc. - Einen Test für die Subroutine schreiben, welche 2 Durchführungen ausführt bzw. automatisch mir diese Operation berechnet Ich habe bei der Herangehensweise und bei der Überlegung wie ich das Anstellen soll schon meine Probleme Das Dokument mit den 100 Ziffern mit 20 Zeilen kann ich später irgendwie erstellen, aber ich habe gerade keine Ahnung welche Schleife ich am besten Auswählen sollte für meine zeilenweise Addition der 100 Ziffern ! | #!/usr/bin/perl -w -l
use strict;
use warnings;
my@Zeilensumme=0
for (i=[0];i=+)
my$Zeilensumme=$i[0]+$i[1]+$i[2]+$i[3]+$i[4]
|
habe ich die richtige Schleife ausgewählt ?
soll ich das mit den restlichen Zeilen dann auch so machen oder geht es nicht einfacher ?
ich bin echt gerade ohne Idee habe schon sehr lange sowas nichtmehr gemacht
und soll ich in der for-schleife als Bedingung i++ oder i=+
|
verdooft
Anmeldungsdatum: 15. September 2012
Beiträge: 3991
|
Hallo, ich würde erstmal 3 Zeilen mit jeweils 5 Zahlen nehmen, da kannst du das Ergebnis leicht im Kopf kontrollieren und passt nachher nur die Werte an.
|
davidik
(Themenstarter)
Anmeldungsdatum: 20. November 2014
Beiträge: 42
|
Hm, aber ich würde schon gerne wissen welche Schleife gut ist
|
user_unknown
Anmeldungsdatum: 10. August 2005
Beiträge: 17548
Wohnort: Berlin
|
Ach - die Überschrift nicht gesehen, dass es um Perl geht. Dann kann ich ja mit weniger Spielverderberpotential eine Bashlösung posten: 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 | for r in {1..20}; do echo -n "echo \$(("; for z in {1..100}; do echo -n $((RANDOM%10))+; done; echo 0"))"; done
echo $((9+3+6+2+4+9+3+3+7+9+0+3+6+4+4+0+4+5+6+2+1+2+6+3+3+3+9+6+9+6+1+6+5+2+3+5+9+7+4+4+5+4+4+4+1+4+2+0+1+1+9+4+0+2+3+9+4+8+0+2+8+4+8+5+4+9+5+6+0+2+9+3+0+7+8+3+1+2+0+7+9+0+0+5+7+7+4+4+3+8+8+3+5+4+3+5+2+7+9+4+0))
echo $((8+1+1+6+4+5+7+8+8+2+4+7+5+5+9+5+0+3+0+8+2+2+5+4+1+4+5+6+7+3+8+3+6+2+0+0+1+6+7+8+6+8+2+1+5+4+2+6+4+2+2+1+3+3+6+3+5+0+5+4+0+2+1+1+2+2+9+1+6+2+3+4+7+2+4+8+6+2+7+3+3+5+4+9+6+1+6+4+6+0+9+8+0+9+0+4+8+7+1+4+0))
echo $((3+0+9+5+2+3+4+9+0+2+9+2+2+8+1+6+6+2+3+6+5+7+7+1+4+2+3+3+7+6+1+1+5+3+7+5+3+2+9+3+3+8+6+5+5+3+2+8+2+0+6+9+0+9+9+2+8+3+2+2+4+2+8+3+9+6+8+3+3+0+8+6+8+3+7+1+3+9+6+6+2+4+3+9+5+3+1+6+8+1+9+9+9+2+7+5+3+9+2+8+0))
echo $((1+7+7+8+8+8+5+0+9+7+2+7+1+2+5+2+5+4+8+9+9+3+3+0+3+2+4+3+6+5+5+8+7+7+7+2+8+4+9+5+6+1+4+3+1+8+9+2+8+2+1+7+4+4+0+4+6+5+7+0+8+2+5+1+4+5+4+2+9+0+5+0+6+4+6+0+2+4+4+5+1+8+7+6+9+5+3+0+5+3+9+6+7+2+7+5+7+7+9+1+0))
echo $((2+9+4+9+5+4+3+7+9+6+1+7+1+3+2+8+5+4+9+1+1+9+7+7+4+9+3+5+8+6+6+0+9+5+5+2+2+3+6+1+0+6+2+2+1+3+1+0+2+2+2+0+4+1+4+6+7+2+4+5+8+1+3+4+1+3+8+3+7+4+1+5+4+2+1+0+6+2+3+5+1+0+6+4+9+2+1+3+0+6+2+2+4+4+5+2+5+3+7+0+0))
echo $((7+0+3+8+1+9+9+1+7+3+3+2+5+8+5+1+2+6+6+0+4+9+7+7+9+0+7+3+9+6+6+5+1+6+6+9+3+1+4+3+5+6+0+0+9+3+7+7+5+6+8+8+2+0+1+8+6+7+3+8+0+6+1+3+2+7+1+8+2+9+8+4+3+8+7+1+8+6+2+1+4+4+2+1+6+4+1+3+8+5+1+9+7+5+6+5+4+7+3+1+0))
echo $((3+2+2+2+6+0+1+5+3+6+6+6+9+7+8+0+0+6+0+3+4+6+9+9+5+6+7+1+5+5+2+3+9+7+9+1+5+2+9+5+9+4+6+8+3+2+8+3+1+8+5+2+0+2+8+5+3+3+9+9+2+9+4+0+1+5+5+1+5+1+0+5+9+8+8+5+0+9+2+4+5+8+9+6+1+8+1+1+3+5+2+7+3+0+0+9+5+1+7+0+0))
echo $((0+7+3+5+0+0+7+1+5+0+7+5+0+3+2+8+7+5+2+6+4+3+2+1+3+1+6+9+8+7+5+0+4+0+0+7+0+4+0+8+2+3+1+7+8+4+7+4+1+6+8+5+1+3+2+1+4+0+2+0+0+6+3+9+3+7+6+5+7+6+6+6+5+4+0+3+8+0+7+9+4+0+2+9+6+6+7+8+5+3+9+4+5+6+7+5+7+4+4+1+0))
echo $((7+0+7+3+3+3+5+4+8+9+1+1+0+2+0+9+9+9+7+8+9+3+6+0+4+2+2+4+3+7+6+2+0+5+0+1+9+0+0+4+3+5+1+8+8+0+0+3+3+6+3+7+8+5+0+7+1+4+6+6+3+5+7+9+1+4+5+9+9+0+9+9+2+4+2+5+7+1+7+0+5+1+4+9+8+3+0+6+8+4+7+9+5+4+0+0+1+4+8+0+0))
echo $((6+8+7+2+7+4+3+1+8+5+0+1+4+7+2+5+2+7+3+9+0+7+6+9+9+0+3+8+1+1+1+9+2+8+8+5+9+3+8+5+3+3+8+6+9+0+6+4+4+0+4+8+1+8+0+4+6+3+5+5+4+1+6+7+9+4+6+8+2+0+0+7+4+3+7+6+6+3+4+7+7+6+2+8+9+1+4+9+8+9+2+5+3+9+7+4+6+8+2+8+0))
echo $((9+0+6+7+4+5+8+8+0+5+3+1+3+3+4+3+7+5+4+6+7+7+7+5+0+1+4+9+0+7+4+0+1+9+9+7+9+6+4+9+4+1+2+6+7+4+7+6+1+2+3+3+1+8+0+6+0+9+2+0+4+8+5+9+3+8+4+2+0+5+4+2+2+5+5+8+6+2+3+4+4+1+0+6+2+2+2+2+2+8+8+5+3+6+2+9+0+9+8+8+0))
echo $((8+8+0+4+9+8+5+3+4+0+5+9+7+7+4+5+5+9+4+8+2+3+9+7+8+9+6+3+2+7+8+8+5+4+6+7+2+4+3+6+5+8+5+6+4+2+7+7+1+3+3+2+9+7+1+5+4+8+0+8+3+4+9+9+2+7+0+9+9+5+1+1+5+4+7+8+1+9+7+9+2+0+3+7+1+0+5+3+2+7+7+0+9+4+0+3+1+5+6+0+0))
echo $((9+5+3+8+6+3+4+7+3+2+4+7+4+6+7+9+5+0+8+1+4+7+1+7+6+8+6+8+7+7+9+4+6+4+0+6+8+0+5+5+0+8+2+5+8+4+6+4+8+3+3+4+4+4+0+8+9+8+0+7+7+5+6+7+5+7+8+5+9+4+2+6+1+7+4+4+6+5+6+6+0+0+3+7+4+3+8+5+7+0+9+6+2+0+9+8+0+7+7+7+0))
echo $((1+6+6+8+1+2+6+8+1+0+1+3+3+9+8+3+5+9+0+0+2+5+1+7+0+1+3+1+5+7+2+4+8+7+5+9+8+3+5+9+9+3+4+4+3+2+8+7+9+3+1+8+2+5+2+9+1+7+2+3+3+9+0+7+4+8+1+7+3+4+2+0+2+6+6+1+3+1+0+4+4+0+3+0+9+0+8+7+2+5+9+6+6+4+2+2+7+5+8+9+0))
echo $((4+0+2+8+2+3+5+3+0+4+1+4+6+3+3+9+9+7+0+5+2+9+4+1+6+6+4+2+4+6+6+3+5+7+4+9+1+5+1+2+1+1+3+8+4+6+2+8+1+9+2+0+7+1+7+8+8+0+3+8+5+2+0+0+0+0+9+8+7+0+8+9+6+5+8+6+6+0+6+1+6+2+7+1+5+1+2+6+4+8+1+6+4+7+8+4+6+0+5+4+0))
echo $((5+3+5+9+7+3+1+9+4+8+5+8+4+8+9+4+7+7+0+2+2+2+4+1+0+3+1+1+7+9+6+7+9+2+4+1+4+0+8+2+4+3+2+3+3+8+4+7+0+7+8+1+2+9+5+3+9+2+8+7+1+4+1+8+4+9+2+2+9+9+6+1+1+1+2+1+1+1+6+7+1+8+5+8+8+3+5+4+5+5+9+5+8+4+5+9+3+1+3+1+0))
echo $((3+8+7+5+0+6+8+4+6+4+9+1+9+3+8+2+9+9+6+1+7+8+4+5+5+2+5+9+2+1+4+6+5+5+6+8+0+1+9+5+5+9+7+1+4+1+3+6+3+5+1+6+3+7+5+2+7+3+6+5+3+2+9+2+8+9+5+0+2+4+8+1+1+0+2+6+7+5+5+4+7+9+4+2+0+6+2+2+9+0+7+2+9+7+4+5+6+8+6+5+0))
echo $((6+1+0+5+3+9+6+9+5+1+0+8+0+4+2+2+0+3+0+5+9+0+6+2+2+8+0+2+3+5+8+1+9+1+3+5+6+9+6+3+2+1+9+0+5+3+4+8+2+5+4+9+7+7+0+2+0+6+6+7+5+0+0+3+0+8+3+8+8+8+2+9+4+0+6+7+2+6+7+1+6+0+5+7+3+8+2+7+0+6+4+9+1+6+9+4+5+0+8+2+0))
echo $((9+7+2+5+1+5+2+6+4+0+2+5+2+4+0+9+7+4+4+5+1+8+7+6+3+2+7+0+6+7+2+4+5+3+2+4+0+9+1+6+8+0+5+2+1+6+6+1+5+8+4+9+2+3+6+1+7+9+4+6+6+8+1+5+2+4+7+4+1+1+1+6+2+7+1+1+7+0+0+9+8+1+7+4+6+0+5+8+3+2+7+6+2+7+3+3+3+4+8+0+0))
echo $((8+3+3+0+2+5+9+1+3+6+5+5+0+1+8+0+5+7+5+4+0+5+3+9+9+4+8+9+7+9+3+0+7+0+5+6+1+9+8+1+3+5+4+8+5+6+5+9+8+9+4+8+0+9+1+7+4+1+1+6+9+4+2+3+9+0+8+6+5+6+6+9+7+4+2+8+6+1+7+9+7+6+7+3+3+7+6+0+2+1+0+3+6+6+4+8+9+5+5+8+0))
thinkpux:~/proj/mini/forum/tmp > echo $((9+3+6+2+4+9+3+3+7+9+0+3+6+4+4+0+4+5+6+2+1+2+6+3+3+3+9+6+9+6+1+6+5+2+3+5+9+7+4+4+5+4+4+4+1+4+2+0+1+1+9+4+0+2+3+9+4+8+0+2+8+4+8+5+4+9+5+6+0+2+9+3+0+7+8+3+1+2+0+7+9+0+0+5+7+7+4+4+3+8+8+3+5+4+3+5+2+7+9+4+0))
438
thinkpux:~/proj/mini/forum/tmp > echo $((8+1+1+6+4+5+7+8+8+2+4+7+5+5+9+5+0+3+0+8+2+2+5+4+1+4+5+6+7+3+8+3+6+2+0+0+1+6+7+8+6+8+2+1+5+4+2+6+4+2+2+1+3+3+6+3+5+0+5+4+0+2+1+1+2+2+9+1+6+2+3+4+7+2+4+8+6+2+7+3+3+5+4+9+6+1+6+4+6+0+9+8+0+9+0+4+8+7+1+4+0))
414
thinkpux:~/proj/mini/forum/tmp > echo $((3+0+9+5+2+3+4+9+0+2+9+2+2+8+1+6+6+2+3+6+5+7+7+1+4+2+3+3+7+6+1+1+5+3+7+5+3+2+9+3+3+8+6+5+5+3+2+8+2+0+6+9+0+9+9+2+8+3+2+2+4+2+8+3+9+6+8+3+3+0+8+6+8+3+7+1+3+9+6+6+2+4+3+9+5+3+1+6+8+1+9+9+9+2+7+5+3+9+2+8+0))
466
|
usw. - sollte im Mittel 450 pro Zeile ergeben. In Perl wirst Du eher nicht die Zahlen in einen String speichern und diesen mit eval evaluieren, sondern vor der inneren Schleife "sum=0" sagen, und in der inneren "sum+=RAND" - wie immer man das in Perl sagt.
Nach der inneren Schleife dann print sum.
|
elostio
Anmeldungsdatum: 2. Februar 2006
Beiträge: 424
Wohnort: Guayaquil
|
Hi dieser Code liest die Datei mit dem namen 'test.dat' ein, summiert die darin enthaltenen Zahlen und gibt am Schluss die Summe aus: 1
2
3
4
5
6
7
8
9
10
11
12
13
14
15 | #!/usr/bin/perl
use warnings;
use strict;
use autodie;
open(my $fh, '<', 'test.dat');
my $sum = 0;
while (<$fh>) {
chomp;
$sub += $_;
}
close($fh);
print "$sum\n";
|
Interessant für dich ist schon die erste Zeile, ich habe weder die Flags '-l' noch '-w' benutzt, weil ich dafür keinen Grund sehe. Zusätzlich habe ich auch das Pragma "aoutodie" benutzt, welches mir automatischeine "Exception" erzeugt sollte es einen Fehler beim Öffnen der Datei geben. Als Schleife habe ich eine "while" schleife benutzt welche so lange über den Filehandle "$fh" iteriert bis dieser keine zusätzlichen Zeilen zu lesen hat und einen false-Wert zurückgibt. In der Variablen $_ befindet sich der Inhalt der jeweiligen Zeile.
Bei vielen Befehlen muss ich $_ nicht implizit angeben, es wird automatisch benutzt, wie zum Beispiel bei chomp. chomp entfernt die newlines ('\n') am Ende eines Strings. So das ist Perl. Viel Magie, selbst bei kleinen Codestücken muss man viel erklären - wenn man das nicht täglich benutzt wird es nie intuitive verständlich werden. Wenn du irgendwie die Wahl hast, entscheide dich dazu lieber eine andere Sprache wie Python zu benutzen.
|
seahawk1986
Anmeldungsdatum: 27. Oktober 2006
Beiträge: 11176
Wohnort: München
|
elostio schrieb: Hi dieser Code liest die Datei mit dem namen 'test.dat' ein, summiert die darin enthaltenen Zahlen und gibt am Schluss die Summe aus: 1
2
3
4
5
6
7
8
9
10
11
12
13
14
15 | #!/usr/bin/perl
use warnings;
use strict;
use autodie;
open(my $fh, '<', 'test.dat');
my $sum = 0;
while (<$fh>) {
chomp;
$sub += $_;
}
close($fh);
print "$sum\n";
|
Müsste es in Zeile 11 nicht $sum statt $sub heißen? Es gibt schon diesen fast gleichnamigen Thread von davidk: http://forum.ubuntuusers.de/topic/perl-programmieren-grundlagen/ Da war die tatsächliche Anforderung an das Skript nach zähem Nachfragen diese: http://forum.ubuntuusers.de/post/7151728/
|
davidik
(Themenstarter)
Anmeldungsdatum: 20. November 2014
Beiträge: 42
|
@Elostio DANKE,ich habe mir das ungefähr auch so vorgestellt aber ich bin schon einige Zeit nichtmehr so richtig vertraut aber grundsätzlich war das auch meine Überlegung mit dem += Operator und ich finde es sehr nett das du eine Beschreibung zur Nachvollziehbarkeit eingetippt hast !!!
|
elostio
Anmeldungsdatum: 2. Februar 2006
Beiträge: 424
Wohnort: Guayaquil
|
ja muss natürlich $sum heißen, danke.
|
rklm
Projektleitung
Anmeldungsdatum: 16. Oktober 2011
Beiträge: 12801
|
Die Lösung von elostio hat allerdings das Problem, dass sie die Aufgabenstellung nicht löst - soweit ich das sehe. Es geht ja darum, innerhalb einer Zeile die Quersumme zu bilden (also alle Ziffern einer Zeile zu summieren). Ich hätte da eine Lösung, möchte aber nicht zu früh spoilen. Ich komme mit 18 Zeilen verhältnismäßig leserlichem Perl aus, das sogar aus mehreren Dateien liest. ☺ davidik schrieb:
Das Dokument mit den 100 Ziffern mit 20 Zeilen kann ich später irgendwie erstellen, aber ich habe gerade keine Ahnung welche Schleife ich am besten Auswählen sollte für meine zeilenweise Addition der 100 Ziffern !
Ich habe das so gelöst, dass ich mit einem Regulären Ausdruck durch die Zeile gegangen bin, der jeweils nur eine Ziffer erkennt. Dann kann man sogar noch Leerzeichen oder anderes einfügen und das Programm funktioniert noch (wenn denn das gewünscht ist). Ciao robert
|
davidik
(Themenstarter)
Anmeldungsdatum: 20. November 2014
Beiträge: 42
|
@rklm wäre ganz gut weil regular expressions das arbeiten mit perl ja vereinfachen und auch einfach sinnvoll sind
|
elostio
Anmeldungsdatum: 2. Februar 2006
Beiträge: 424
Wohnort: Guayaquil
|
Sorry das hab ich überlesen. Hier als Entschuldigung ein Programm welches dir die Quersumme eines Strings mit Ziffern berechnet. 1
2
3
4
5
6
7
8
9
10
11
12
13 | #!/usr/bin/perl
use strict;
use warnings;
my $sum = 0;
my $line = "012345";
my @arr = split //, $line;
for ( @arr ) {
$sum += $_;
}
print "$sum\n";
|
|
elostio
Anmeldungsdatum: 2. Februar 2006
Beiträge: 424
Wohnort: Guayaquil
|
Hi hab nun auch nachdem ich festgestellt habe das List::Util zu den Coremodulen gehört habe ich eine meiner Meinung nach viel schönere Lösung erstellt. | #!/usr/bin/perl
use strict;
use warnings;
use List::Util qw(reduce); #qw = quoted words, das macht man aus Faulheit/Gewohnheit anstatt jedes Element einzeln zu quoten
my $line = "012345";
my @arr = split //, $line;
my $sum = reduce { $a + $b } @arr;
print "$sum\n";
|
Ich erklär dir auch noch was reduce macht. Reduce nimmt eine liste @arr und führt im ersten Schritt den Ausdruck zwischen den geschwungenen Klammern aus indem $a das erste Element zugewiesen bekommt und $b das zweite. Das Ergebnis ist wird in $a festgehalten. Für jeden weiteren Schritt wird ab nun ein neues Element der Liste benutzt und $b zugewiesen, $a ist das Ergebnis der vorherigen Berechung. Ist kein Element mehr vorhanden dann wird $a zurückgegeben. Das klingt komplizierter als es ist, es wird klar wenn wir es für unser Beispiel einfach kurz durchgehen. reduce bekommt @arr als Liste und { $a + $b } als Funktion übergeben
im Ersten Schritt ist noch kein alter Wert einer Berechung vorhanden also ist $a := 0 und $b := 1. die Berechung wird durchgeführt und in $a gespeichert $a = $a + $b = 1 im Zweiten Schritt ist bereits ein alter Wert einer Berechung vorhanden also gibt es bereits $a, $b wird der nächste unbenutzte Wert der Liste zugewiesen also $b := 2 Nun wird die Berechung durchgeführt $a = $a + $b = 1 + 2 = 3 $a = $a + $b = 3 + 3 = 6 $a = $a + $b = 6 + 4 = 10 $a = $a + $b = 10+ 5 = 15 kein Element mehr vorhanden $sum = $a = 15
|
elostio
Anmeldungsdatum: 2. Februar 2006
Beiträge: 424
Wohnort: Guayaquil
|
Weil ich gerade Zeit hatte hier noch ein "one-liner" | perl -wpl -e 'use List::Util qw(sum);$_ = sum split //' < test.dat
|
oder | perl -wpl -e 'use List::Util qw(sum);$_ = sum split //' test.dat
|
|
rklm
Projektleitung
Anmeldungsdatum: 16. Oktober 2011
Beiträge: 12801
|
elostio schrieb: Weil ich gerade Zeit hatte hier noch ein "one-liner"
Hübsch! Ich finde ja Ruby immer noch lesbarer: $ cat x
12345
4567
$ ruby -ne 'p $_.scan(/\d/).inject(0) {|s,x|s+x.to_i}' x
15
22 Ciao robert
|
xubuntufriese
Anmeldungsdatum: 3. Mai 2014
Beiträge: 340
|
rklm schrieb: Ich finde ja Ruby immer noch lesbarer:
Ruby finde ich völlig unverständlich! $ cat x
12345
4567
$ awk 'BEGIN{FS=""}{s=0;for(i=1;i<=NF;i++)s=s+$(i);print s}' x
15
22 awk rules!
|