seahawk1986
Anmeldungsdatum: 27. Oktober 2006
Beiträge: 11179
Wohnort: München
|
Wie sieht denn so eine Zeile in der 100Zahlen.dat aus? Im Prinzip genügt es doch den Array der einzelnen Ziffern an die Subroutine zu übergeben und dann damit zu arbeiten - für die Summe der Ziffern z.B. so:
| sub calc_digit_sum {
my $digit_sum = 0;
foreach (@_){$digit_sum += $_;}
return $digit_sum;
}
|
|
davidik
(Themenstarter)
Anmeldungsdatum: 20. November 2014
Beiträge: 42
|
1
2
3
4
5
6
7
8
9
10
11
12 | open (100Zahlen,"100Zahlen.dat") or die $!;
my @Zahlen = <"100Zahlen">;
close (100Zahlen);
chomp my$Zahlen ;
sub Zeilensumme{
my $Zeilensumme =0;
foreach $Zeilensumme(@Zahlen)
{
$Zeilensumme += $$Zahlen[0]+$Zahlen[1]+$Zahlen[2];}
return $summe;
}
|
so sieht das jetzt bei mir aus meine 100Zahlen.dat ist folgendermaßen 195
719
954
912
527
439
326
986
103
887
274
237
976
63
489
65
396
842
551
619
117
30
492
744
550
386
288
462
278
852
639
213
302
202
593
856
986
999
342
532
135
891
350
160
573
842
865
454
84
188
681
735
800
771
276
736
156
518
200
846
81
801
471
78
620
363
258
321
522
938
459
349
707
634
308
905
682
799
258
113
46
410
371
426
796
393
6
491
192
243
671
699
143
739
70
502
633
85
252
230
|
seahawk1986
Anmeldungsdatum: 27. Oktober 2006
Beiträge: 11179
Wohnort: München
|
Also ist die Angabe im ersten Post falsch, es sind 100 Zahlen pro Zeile, nicht 100 Ziffern. Mir ist noch nicht klar, was du genau erreichen willst - brauchst du die Quersumme jeder Zahl in der Zeile und willst die addieren (was die Summe aller Ziffern wäre) oder willst du nur die Zahlen addieren? So könnte man die Zahlen in jeder Zeile zusammenzählen:
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 | #!/usr/bin/env perl -w -l
use strict;
use warnings;
# quit unless we have the correct number of command-line args
my $num_args = $#ARGV + 1;
if ($num_args != 1) {
print "\nUsage: calcsums.pl file_name\n";
exit;
}
my $file_name=$ARGV[0];
sub calc_sum {
my $line_sum = 0;
foreach (@_){$line_sum += $_;}
return $line_sum;
}
sub calc_alt_sum {
my $line_sum = 0;
my $prefix = 1;
foreach (@_){
$line_sum += ($prefix * $_);
$prefix *= -1;
}
return $line_sum;
}
open(my $data, "<", $file_name) or die $!;
my $counter = 0;
while (<$data>) {
chomp;
$counter += 1;
print "got line $counter: $_";
my @numbers=split(/ /, $_);
print "Summe Zeile $counter: ", calc_sum(@numbers);
print "alternierende Summe Zeile $counter: ", calc_alt_sum(@numbers);
}
close $data or die "$data: $!";
|
|
davidik
(Themenstarter)
Anmeldungsdatum: 20. November 2014
Beiträge: 42
|
Nein die Datei ist falsch, habe ich zu spät erst bemerkt also dann muss ich eine Datei erstmal erstellen die 20 Zeilen mit jeweisl 100 Ziffern also Zahlen enthält da fängt das Problem bei mir schon an wie ich zufällig 100 Zahlen pro Zeile generiere von 0-9 (max. 3-stellig) ich will die datei einlesen und jede einzelne Zeile die Summe der 100 Ziffern bilden also Ziffer 1 + Ziffer 2 + ... + Ziffer 100
ich weiß nicht wie ich die addition einer Zeile und genau nur einer Zeile angebe, also soll ich Arrays für jede Zeile erstellen oder mache ich das ich irgendwas mit $i oder mit $_ ? die zählung soll dann zeilenweise gelistet sein Summe Zeile 1 :
Summe Zeile 2 :
... dann 2 Testdurchläufe nochmal für diese Sache
|
seahawk1986
Anmeldungsdatum: 27. Oktober 2006
Beiträge: 11179
Wohnort: München
|
davidik schrieb: Nein die Datei ist falsch, habe ich zu spät erst bemerkt also dann muss ich eine Datei erstmal erstellen die 20 Zeilen mit jeweisl 100 Ziffern also Zahlen enthält da fängt das Problem bei mir schon an wie ich zufällig 100 Zahlen pro Zeile generiere von 0-9 (max. 3-stellig)
Also 20 Zeilen mit einer variablen Anzahl an Zahlen mit jeweils 1 - 3 Stellen mit insgesamt 100 Ziffern?
Wozu braucht es den Aufwand das in einzelne Zahlen zu packen, wenn man nur die Ziffern addieren will?
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 | #!/usr/bin/env perl -w -l
use Switch;
use strict;
use warnings;
# quit unless we have the correct number of command-line args
my $num_args = $#ARGV + 1;
if ($num_args != 1) {
print "\nUsage: generate_data.pl filename\n";
exit;
}
my $filename=$ARGV[0];
my @line = ();
my $counter = 0;
my $len = 100;
my $rand_max = 0;
my $number = 0;
open(my $fh, ">", $filename) or die $!;
until ($counter == 20){
until ( $len == 0 ){
if ($len >= 3) {$rand_max = 999;}
elsif ($len == 2) {$rand_max = 99;}
elsif ($len == 1) {$rand_max = 9;}
if ($len > 0){
$number = int(rand($rand_max));
$len -= length($number);
push(@line, $number);
}
}
$counter += 1;
print $fh "@line";
$len = 100;
$number = 0;
@line = ();
}
close($fh) or die $!;
|
ich will die datei einlesen und jede einzelne Zeile die Summe der 100 Ziffern bilden also Ziffer 1 + Ziffer 2 + ... + Ziffer 100 die zählung soll dann zeilenweise gelistet sein Summe Zeile 1 :
Summe Zeile 2 :
...
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 | #!/usr/bin/env perl -w -l
use strict;
use warnings;
# quit unless we have the correct number of command-line args
my $num_args = $#ARGV + 1;
if ($num_args != 1) {
print "\nUsage: calcsums.pl filename\n";
exit;
}
my $filename=$ARGV[0];
sub calc_sum {
my $sum = 0;
foreach (@_){$sum += $_;}
return $sum;
}
open(my $data, "<", $filename) or die $!;
my $counter = 0;
while (<$data>) {
chomp;
s/\s//g;
$counter += 1;
print "got line $counter: $_";
my @numbers=split('', $_);
print "Summe Zeile $counter: ", calc_sum(@numbers);
}
close $data or die "$data: $!";
|
dann 2 Testdurchläufe nochmal für diese Sache
Den Sinn der Testdurchläufe verstehe ich nicht, da kommt doch immer das gleiche raus?
|
davidik
(Themenstarter)
Anmeldungsdatum: 20. November 2014
Beiträge: 42
|
Ja das ist eigentlich für Basenpaare gedachte wenn ich eine Auszählung habe und dann die ACTG's zählen soll bzw. die Summe dieser zur weiteren Verarbeitung das sind nur so "Musterfragen" gilt ähnlich für die Test's 😛
also du bist auch ein etwas fortgeschrittener Programmierer, weshalb ich deinen ersten Programmier-Teil von der Komplexität auch nicht so Recht durchblicken kann leider
ich habe mir das einfacher überlegt | #!/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]
|
Frage ist nun 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=+ stehen. mfg Davidik
|
davidik
(Themenstarter)
Anmeldungsdatum: 20. November 2014
Beiträge: 42
|
Ich weiß nicht wie ich nachdem Einlesen der Datei fortfahren soll also ich lese die Datei zeilenweise ein
"chompe" diese ja sozusagen
wie baue ich das in eine Schleife ein sodass ich diese Zeilenumbrüche dann von den Zahlen am Ende der Zeile aufsummiere für jede Zeile ?!
|
seahawk1986
Anmeldungsdatum: 27. Oktober 2006
Beiträge: 11179
Wohnort: München
|
davidik schrieb: Ja das ist eigentlich für Basenpaare gedachte wenn ich eine Auszählung habe und dann die ACTG's zählen soll bzw. die Summe dieser zur weiteren Verarbeitung das sind nur so "Musterfragen" gilt ähnlich für die Test's 😛
Rein interessehalber, da ich mit Bioinformatik bislang kaum etwas zu tun hatte - wie bildet man die Basenpaare, in denen 4 (oder 5, wenn man mit RNA paart) Nukleotide vorkommen können mit Zahlen von 0-9 ab und wie hilft einem die Summe der Ziffern dabei? also du bist auch ein etwas fortgeschrittener Programmierer, weshalb ich deinen ersten Programmier-Teil von der Komplexität auch nicht so Recht durchblicken kann leider
Ich bin ein Perl-Einsteiger, der Google benutzen kann 😇 - was genau ist denn unklar? ich habe mir das einfacher überlegt | #!/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]
|
Frage ist nun habe ich die richtige Schleife ausgewählt ?
Welche Schleife? Das ist ja keine valide Perl-Syntax und mir ist daher nicht ganz klar, was du da machen willst. 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=+ stehen.
Versuchen wir es doch mal ohne Perl, damit wir wenigstens vom gleichen sprechen, denn mir ist die Aufgabe noch nicht ganz klar:
Dann kommentiere ich mein Skript mal etwas mehr: 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
45 | #!/usr/bin/env perl -w -l
use strict;
use warnings;
# Überprüfe, ob es genau ein Argument für den Programmaufruf gibt, sonst breche ab
my $num_args = $#ARGV + 1;
if ($num_args != 1) {
print "\nUsage: calcsums.pl filename\n";
exit;
}
# das erste Argument entspricht dem Namen der Datei, die geöffnet werden soll
my $filename=$ARGV[0];
# Subroutine, die ein Array der zu addierenden Zahlen übergeben bekommt
sub calc_sum {
my $sum = 0;
# führe für jede Zahl "$_" im übergebenen Array "@_" folgendes aus:
# Erhöhe den Wert der Variable $sum um den Wert der Variablen "$_"
foreach (@_){$sum += $_;}
# gibt die Variable $sum als Ergebnis zurück
return $sum;
}
# Öffne die Datei mit dem Namen $filename zum Lesen als Filehandle $data oder breche ab, wenn es einen Fehler gibt
open(my $data, "<", $filename) or die $!;
my $counter = 0;
# für jede Zeile im Filehandler $data
while (<$data>) {
# entferne das Zeilenende
chomp;
# ersetze alle Leerzeichen, Tabs usw.
s/\s//g;
$counter += 1;
print "got line $counter: $_";
# schreibe alle Ziffern als getrennte Werte in das Array @numbers
my @numbers=split('', $_);
# drucke den String und den Rückgabewert der Subroutine calc_sum, der das Array @numbers übergeben wird
print "Summe Zeile $counter: ", calc_sum(@numbers);
}
# schließe das Filehandle
close $data or die "$data: $!";
|
davidik schrieb: Ich weiß nicht wie ich nachdem Einlesen der Datei fortfahren soll also ich lese die Datei zeilenweise ein
"chompe" diese ja sozusagen
wie baue ich das in eine Schleife ein sodass ich diese Zeilenumbrüche dann von den Zahlen am Ende der Zeile aufsummiere für jede Zeile ?!
Tut mir leid, aber mir ist immer noch nicht ganz klar, was du erreichen willst - kannst du das mal schrittweise formulieren?
|
davidik
(Themenstarter)
Anmeldungsdatum: 20. November 2014
Beiträge: 42
|
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 Das Dokument mit den 100 Ziffern pro Zeile sollte ich zuerst erstellen, der Grund dafür ist Interesse und auch Aufgabenstellung.
Aber ich habe keine Ahnung welche Schleife sich am besten eignet, um die Datei einzulesen und in entweder "Zeilenarrays" zu splitten, also eine Zeichenkette zu erstellen die, die ersten 100Ziffern als Strings "entziffert" und zum Array verknüpft oder eine andere Überlegung ist die ersten 100 Ziffern von den restlichen 1900 zu trennen damit ich diese als "Stringkette" irgendwie mit i+= im parameter von einer Vorschleife laufen lasse Ich glaube ich sollte die Datei Einlesen und in demselben Moment daraus ein Array Erstellen mit der Gesamtlänge 2000 und anschließend in kleinere Arrays/Zeichenketten splitten und diese dann nach und nach aufsummieren lassen und zum schluß Printbefehl, aber ich weiß nicht wie das mit der Abbruchbedingung dann funktioniert
|
seahawk1986
Anmeldungsdatum: 27. Oktober 2006
Beiträge: 11179
Wohnort: München
|
davidik schrieb: 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
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 | #!/usr/bin/env perl -w -l
use strict;
use warnings;
my $num_args = $#ARGV + 1;
if ($num_args != 1) {
print "\nUsage: generate_data.pl filename\n";
exit;
}
my $filename = $ARGV[0];
open(my $fh, ">", $filename) or die $!;
my @line = ();
for (my $count = 0; $count <20; $count++){ # wiederhole 20 Mal
for (my $n = 0; $n <100; $n++){ # wiederhole 100 Mal
$number = int(rand(10)); # siehe http://perldoc.perl.org/functions/rand.html
push(@line, $number); # hänge Zufalls-Ziffer an Array @line an
}
print $fh @line; # schreibe das Array @line in die Datei (bildet eine Zeile)
@line = (); # leere das Array @line
}
close($fh) or die $!;
|
Aufruf:
$ ./generate_file.pl test.dat
$ cat test.dat
1894488116625003766102609455970073661424406757807289093909750239692089236360902136327929173534387766
2548394946198833173029063740287243593605563519627816210068139566889949733356902407122110176625082967
5923101430284419109728249892090199919431056311013174314518206710762696711411358561131378805216042157
1058808434765304005184417547973864291211320157259908977711062311003790075857072628428999083606861136
9913962750546207353188967810299550255216731584316856504272508277595854159829277857109955056263412079
8822280896230988614494973761510990666562485969315702859847949113938216738402488959676157956725045524
6686395192417378251320065129044542310822454805337142597380339919536275021262649383044848939651664742
3720081560722019207977950953415123742962878713113604365731043566472415751367953833556044178000301713
6155209067860680055683147379848948295795718772195487094889392016052931344879066085386018965127999260
7702613281783586199488979786635803637824765749340573080585577665631133952794452571884270589643084510
3507909775156277153566070661572336747218765094865888105475959278744192680969547951452066818175293611
1461865519475618223509505488355644422911385433830041188019042288646144804982317067913119695964406150
9309275764682474484241201143403687252358249171876940956392428799249567113544451903246410178999582988
2128479726697194947453026789840700104157461705563130787559854273873109611977201435702969250952376137
2581107187297225783973801732207133563919653978936098036954522845743087648563710412353856353860384008
9474011583487872548142249629574288116186950546006394620581309220085577261332069452441703853424221924
4072846404817138103255068933804724890117457415783553071078011259739379184631762915890077971794705603
3453824983888938004413903898088806937450977956396885395588518456367962771373626209245088073708053811
3303420812935342940298267120291076903388885682003830708904759451944137013694760105080882822377408274
7456748863105547016356858675231441799483805295644179523794164364189507348871863378652741844091391456 → 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
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
45
46
47
48
49
50
51
52
53
54
55
56 | #!/usr/bin/perl -w -l
use strict;
use warnings;
# Überprüfe, ob es genau ein Argument für den Programmaufruf gibt, sonst breche ab
my $num_args = $#ARGV + 1;
if ($num_args != 1) {
print "\nUsage: calcsums.pl filename\n";
exit;
}
# das erste Argument entspricht dem Namen der Datei, die geöffnet werden soll
my $filename=$ARGV[0];
# Subroutine, die ein Array der zu addierenden Zahlen übergeben bekommt
sub calc_sum {
my $sum = 0;
# führe für jede Zahl "$_" im übergebenen Array "@_" folgendes aus:
# Erhöhe den Wert der Variable $sum um den Wert der Variablen "$_"
foreach (@_){$sum += $_;}
# gibt die Variable $sum als Ergebnis zurück
return $sum;
}
sub test_result {
my $fh = $_[0];
seek($fh, 0, 0); # gehe an den Anfang der Datei
my $counter = 0;
# für jede Zeile im Filehandler $data
while (<$fh>) {
# entferne das Zeilenende
chomp;
# ersetze alle Leerzeichen, Tabs usw.
s/\s//g;
$counter += 1;
# schreibe alle Ziffern als getrennte Werte in das Array @numbers
my @numbers=split('', $_);
# drucke den String und den Rückgabewert der Subroutine calc_sum, der das Array @numbers übergeben wird
print "Summe Zeile $counter: ", calc_sum(@numbers);
}
}
# Öffne die Datei mit dem Namen $filename zum Lesen als Filehandle $data oder breche ab, wenn es einen Fehler gibt
open(my $data, "<", $filename) or die $!;
print "Durchlauf #1";
test_result($data);
print "Durchlauf #2";
test_result($data);
#my $counter = 0;
# schließe das Filehandle
close $data or die "$data: $!";
|
Aufruf:
$ ./line_sum.pl test.dat
Durchlauf #1
Summe Zeile 1: 452
Summe Zeile 2: 450
Summe Zeile 3: 385
Summe Zeile 4: 426
Summe Zeile 5: 471
Summe Zeile 6: 508
Summe Zeile 7: 432
Summe Zeile 8: 398
Summe Zeile 9: 501
Summe Zeile 10: 495
Summe Zeile 11: 488
Summe Zeile 12: 426
Summe Zeile 13: 474
Summe Zeile 14: 453
Summe Zeile 15: 454
Summe Zeile 16: 420
Summe Zeile 17: 441
Summe Zeile 18: 505
Summe Zeile 19: 418
Summe Zeile 20: 484
Durchlauf #2
Summe Zeile 1: 452
Summe Zeile 2: 450
Summe Zeile 3: 385
Summe Zeile 4: 426
Summe Zeile 5: 471
Summe Zeile 6: 508
Summe Zeile 7: 432
Summe Zeile 8: 398
Summe Zeile 9: 501
Summe Zeile 10: 495
Summe Zeile 11: 488
Summe Zeile 12: 426
Summe Zeile 13: 474
Summe Zeile 14: 453
Summe Zeile 15: 454
Summe Zeile 16: 420
Summe Zeile 17: 441
Summe Zeile 18: 505
Summe Zeile 19: 418
Summe Zeile 20: 484
|
davidik
(Themenstarter)
Anmeldungsdatum: 20. November 2014
Beiträge: 42
|
Dankeschön ich studiere gleich mal
und wie kann ich denn wie du googlen lernen 😛
|