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";
}

Freitag, 12. Februar 2010

Aufgabe S54/1: Liste einlesen und rückwärts ausgeben

Seite 54, Aufgabe 1

Schreiben Sie ein Programm, dass mehrere Worte (strings) Zeilenweise einliest (getrennt durch Enter-Taste). Nach Beendigung der Eingabe (end-of-input, zB durch Tastenkombination Strg-D (Linux) oder Strg-Z (Windows)) sollen die Worte in Umgekehrter Reihenfolge ausgegeben werden.

#!/usr/bin/perl -w

@lines = ; # Abbrechen mit Strg-D!

@lines = reverse @lines;
print "Rueckwaertsausgabe:\n";
print @lines;

Mittwoch, 20. Januar 2010

Übung S.38

1. Schreibe ein Programm, dass den Umfang eines Kreises mit Radius 12,5 feststellt (die Einheit ist egal!). Umfang ist Radius*2*PI.

#!/usr/bin/perl -w

$pi = 3.141592654;
$umfang = 12.5*2*$pi;
print "Der Umfang ist $umfang groß";
Theoretisch könnte man mit mehr oder weniger Veriablen arbeiten. Ein guter Ansatz ist es aber immer, feste Variablen, die man evtl. nochmal braucht (vgl PI!) als Variable am Anfang des Programms festzulegen.

2. Modifiziere das obige Programm, so dass der Nutzer den Radius per Standart-Input (STDIN) bekannt geben muss.
#!/usr/bin/perl -w

print "Bitte Radius eingeben: ";
$radius = ;
$pi = 3.141592654;
$umfang = $radius*2*$pi;
print "Der Umfang ist $umfang groß";
3. Modifizieren Sie obiges Programm erneut, so dass bei einer Eingabe kleiner als Null kein negativer Wert ausgegeben wird, sondern 0.
#!/usr/bin/perl -w
$pi = 3.141592654;

print "Bitte Radius eingeben: ";
$radius = ;
if ( $radius lt 0 )
{
$umfang = 0;
}
else
{
$umfang = $radius*2*$pi;
}
print "Der Umfang ist $umfang groß";
4. Schreiben Sie ein Programm, dass 2 Zahlen einließt und das Produkt dieser Zahlen als Ergebnis ausgibt.
#!/usr/bin/perl -w

print "\nBitte Zahl 1 eingeben: ";
$zahl1 = ;
print "\nBitte Zahl 2 eingeben: ";
$zahl2 = ;
$ergebnis = $zahl1 * $zahl2;
print "\nDas Produkt dieser Zahlen lautet: $ergebnis";
5. Schreibe ein Programm, dass eine Zahl und ein Wort einliest (jeweils eigene Eingabeaufforderung). Anschließend soll X mal das Wort auf einer eigenen Zeile ausgegeben werden.
#!/usr/bin/perl -w

print "\nBitte Zahl eingeben: ";
$zahl = ;
print "\nBitte Wort eingeben: ";
$wort = ;
print $wort x $zahl;
Warum werden automatisch Zeilenumsprünge gedruckt? Ganz einfach, das "\n" wird bei STDIN mit eingelesen! Durch den chomp-Befehl könnten wir diesen Zeilensprung entfernen, aber da er von der Aufgabenstellung verlangt wird, ist er in unserer Situation nützlich!

Eingabe / Ausgabe

Wenn man den Inhalt einer Variablen ausgeben möchte, sollten die "quote marks", also Anführungszeichen weggelassen werden.
$zahl = 6;
print "$zahl";
besser:
print $zahl;

Dienstag, 19. Januar 2010

Externe Programme ausführen

Um ein Programm auf dem jew. Server auszuführen, muss der Befehl in backticks gestellt werden.

Damit hat man die umfangreichen Möglichkeiten der shell-Programmierung zu Verfügung. Nachfolgend ein Beispiel:
print `ls -la`;
-> Zeigt uns als Ergebnis den Verzeichnisinhalt an:
insgesamt 28
drwxr-xr-x 2 dirk dirk 4096 2010-01-19 17:01 .
drwxrwxrwx 14 root root 4096 2010-01-19 16:28 ..
-rwxr-xr-x 1 dirk dirk 59 2010-01-19 16:50 perl_1
-rw-r--r-- 1 dirk dirk 58 2010-01-19 16:30 perl_1~
-rw-r--r-- 1 dirk dirk 58 2010-01-19 16:30 perl_1.pl
-rw-r--r-- 1 dirk dirk 38 2010-01-19 17:01 perl_2
-rw-r--r-- 1 dirk dirk 38 2010-01-19 17:00 perl_2~

Perl - der Anfang

Perl ist eine Programmiersprache. Ich versuche sie mit dem Buch "Learning Perl - 5th edition" zu lernen. Das Buch ist in englischer Sprache geschrieben.

Den Start mache ich mit dem Programm "Hello World".

#!/usr/bin/perl -w
use strict;

print "Hello World!\n"
Ein super Start, oder?! ;)