Dienstag, 27. April 2010

Cerlcius / Fahrenheit umrechnen mit regex

Da ich auch nebenbei ein regex-Buch durcharbeite, stoße ich auch dort auf Perl. Diese Programmiersprache ist sehr gut zur Nutzung von regulären Ausdrücken geeignet. Das folgende Programm erkennt durch regex, was für ein Temperaturtyp eingegeben wurde (C oder F), und rechnet ihn dann in den anderen um.


#!/usr/bin/perl -w
# Celcius in Fahrenheit umwandeln und umgekehrt
# http://perl-lernen.blogspot.com/
print "\nGeben Sie bitte eine Temperatur ein (zb 34C, 78F): ";
$temp=;
chomp ($temp);
# Pruefen, ob ein Wert in gewuenschtem Format angegeben wurde
# Die regex ist durch die inneren 2 Klammerpaare in 2 Teile eingeteilt
# Der Variablen $1 wird der Zahlenwert zugewiesen
# Der Variablen $2 wird der Buchstabe C oder F zugewiesen.
if ($temp =~ m/^([-+]?[0-9]*\.?[0-9]+)\s*([CF])$/i)
{
# Nun schreiben wir die durch die obige regex ausgelesenen Werte in feste Variablen rein
# Dies ist wichtig, da $1 und $2 bei der nächsten Verwendung von "=~" wieder überschrieben werden!
$zahl=$1;
$typ=$2;
# Falls C oder c hinter der Zahl eingegeben wurde:
if ( $typ =~ m/c/i)
{
$celcius = $zahl;
$fahrenheit = ( $celcius * 9 / 5) + 32;
}
# Andernfalls; ergo wurde F oder f als Kennung benutzt:
# eine explizite Pruefung auf F oder f ist unnoetig, da schon durch regex erledigt
else
{
$fahrenheit = $zahl;
$celcius = ( $fahrenheit - 32) * 5 / 9;
}
# Ausgabe der Ergebnisse:
printf "%.2f Celcius = %.2f Fahrenheit\n",$celcius,$fahrenheit;
}
# Ungueltiger Wert oder Buchstabe eingegeben:
else
{
printf "Ungueltiger Wert eingegeben; Abbruch!\n";
}

S69/3 - Unterfunktion fuer alle Zahlen ueber dem Durchschnitt

Es wird ein Programm gesucht, dass alle Zahlen einer Liste ausgibt, die über dem Durchschnitt dieser Liste liegen. Es wird also angeraten, erstmal eine Funktion anzulegen, die diesen Durchschnitt berechnet. Danach können die einzelnen items der Liste mit diesem Durchschnitt abgeglichen werden.


#!/usr/bin/perl -w
# Ausgeben der Zahlen, die ueber dem Durchschnitt liegen
# http://perl-lernen.blogspot.com/

my @fred = above_average(100, 1..10);
print "\nFolgende Zahlen liegen ueber dem Durchschnitt von \@fred: @fred\n";

sub above_average
{
# Durchschnitt mittels Unterfunktion "average" ermitteln:
my $average = average( @_ );
print "\nDurchschnitt: $average";
foreach $x ( @_ ) {
if ( $x > $average ) {
push @above, $x;
}
}
return @above;
}

sub average
{
my $summe = 0;

foreach $zahl ( @_ ) {
$summe += $zahl;
}
my $durchschnitt = $summe/@_;
return $durchschnitt;
}

S69/2 - Summierung aller Zahlen von 1 bis 1000

Die Unterfunktion aus der ersten Übung (S69/1) soll nun umgeschrieben werden, um damit alle Zahlen von 1 bis 1000 zu summieren.


#!/usr/bin/perl -w
# http://perl-lernen.blogspot.com/
# total numbers from 1 to 1000

my @tausend = (1..1000);
my $tausend_total = total(@tausend);
print "The total of 1 to 1000 is $tausend_total.\n";

sub total
{
my $summe=0;
foreach $zahl ( @_ )
{
$summe += $zahl ;
}
return $summe;
}

S69/1 - Zahlen einer Liste bzw der Standarteingabe summieren

In dieser Übung soll ein kleines Perl-Skript geschrieben werden, dass die Zahlen einer Liste addiert. Der Hauptteil wird vorgegeben, man soll eine funktionierene subroutine aka Unterfunktion schreiben.

#!/usr/bin/perl -w
# total of a list of numbers

my @fred = qw{ 1 3 5 7 9 };
my $fred_total = total(@fred);
print "The total of \@fred is $fred_total.\n";
print "Enter some numbers on separate lines (end with Strg-D: ";
my $user_total = total();
print "The total of those numbers is $user_total.\n";

sub total
{
$summe=0;
foreach $zahl ( @_ )
{
$summe += $zahl ;
}
return $summe;
}

Sonntag, 14. Februar 2010

Subroutines - Taschenrechner als Übung zu Unterfunktionen

Subroutines oder Unterfunktionen sind sehr nützlich. Als erste Übung habe ich einen einfachen Taschenrechner programmiert.


#!/usr/bin/perl
# Taschenrechner by Christian!
print "Bitte Zahl eingeben: ";
chomp($zahl1 = );
print "Rechenart eingeben (+,-,/,*)";
chomp($rechenart = );
print "Zweite Zahl eingeben: ";
chomp($zahl2 = );

if($rechenart eq '+') {
print "\nAddition wird durchgefuehrt.\n";
$ergebnis = &addition($zahl1, $zahl2);
}
elsif($rechenart eq '-') {
print "\nSubtraktion wird durchgeführt.\n";
$ergebnis = &subtraktion($zahl1, $zahl2);
}
elsif($rechenart eq '*') {
print "\nMultiplikation wird durchgeführt.\n";
$ergebnis = &multi($zahl1, $zahl2);
}
elsif($rechenart eq 'x') {
print "\nMultiplikation wird durchgeführt.\n";
$ergebnis = &multi($zahl1, $zahl2);
}
elsif($rechenart eq '/') {
print "\nDivision wird durchgeführt.\n";
$ergebnis = &division($zahl1, $zahl2);
}
elsif($rechenart eq ':') {
print "\nDivision wird durchgeführt.\n";
$ergebnis = &division($zahl1, $zahl2);
}


sub addition {
($_[0] + $_[1]);
}
sub subtraktion {
($_[0] - $_[1]);
}
sub multi {
($_[0] * $_[1]);
}
sub division {
($_[0] / $_[1]);
}

print "Das Ergebnis Ihrer Rechnung: " . $ergebnis . "!!!\n";

S54/3 - Wortliste alphabetisch sortieren (ASCII)

Wörter werden vom Benutzer nacheinander, durch ENTER getrennt, eingegeben. Das Prgramm soll diese alphabetisch (bzw ASCII-betisch) sortieren und ausgeben.

#!/usr/bin/perl

print "\nBitte Worte eingeben, durch Enter getrennt, Beenden mit Strg-D.\n";
@worte = ;
@sortiert = sort @worte;

print @sortiert;


Eine weitere Möglichkeit:

#!/usr/bin/perl
#Zweite Version, Sortierte Liste in einer Zeile ausgeben!
print "\nBitte Worte eingeben, durch Enter getrennt, Beenden mit Strg-D.\n";
chomp(@worte = ); #Worte liegen jetzt ohne \n in der Liste!
@sortiert = sort @worte;

# Leerzeichen an jedes Element anfügen:
foreach $sortiert (@sortiert)
{
$sortiert = $sortiert . " "; # Frage: warum nicht mit "+=" lösen möglich? vgl S.29!
}

# Ausgabe der kompletten Liste:
print "\nSortierte Worte: ",@sortiert,"\n";


Eine Frage, die mir noch offen geblieben ist: warum wird das Komma bei der Ausgabe der kompletten Liste benötigt?

S54/2 - Wörter einer Zahl zuordnen und ausgeben

In dieser Aufgabe von Seite 54 sollen Zahlen fest einem Wort zugeordnet (hardcoded) werden. Der Benutzer soll die 7 Zahlen in beliebeiger Reihenfolge eingeben, die Ausgabe der korrespondierenden Wörter erfolgt dann genau in dieser Reihenfolge.

#!/usr/bin/perl -w
# Aufgabe: Nummern einlesen in Liste und Ausgabe der passenden Namen.
@namen = qw! fred betty barney dino wilma pebbles bamm-bamm !;

print "Bitte Nummern von 1 bis 7 eingeben, durch ENTER getrennt: ";
chomp(@eingabe = ); # Eingabe beenden durch Strg-D.

foreach $eingabe (@eingabe)
{
print $namen[$eingabe - 1] . "\n";
# Frage: warum nicht (Perl gibt Verbesserungsvorschlag!)?:
# print @namen[$eingabe - 1] . "\n";
}