From 95dd18a427164a566dbca9e12e919919acf6c20a Mon Sep 17 00:00:00 2001 From: Kursmester Date: Wed, 5 Mar 2025 11:15:13 +0100 Subject: [PATCH] Recover from microbel --- README.md | 16 + foiler.html | 1032 ++++++++++++++++ foiler.pl | 1016 +++++++++++++++ foiler/01_velkommen.pl | 26 + foiler/02_whatis.pl | 27 + foiler/03_what.pl | 24 + foiler/04_syntaks.pl | 22 + foiler/05_vars.pl | 23 + foiler/06_quoting.pl | 13 + foiler/07_joining.pl | 25 + foiler/08_multiline.pl | 26 + foiler/09_logikk.pl | 25 + foiler/10_tekstlogikk.pl | 25 + foiler/11_while.pl | 19 + foiler/12_foreach.pl | 25 + foiler/13_break.pl | 26 + foiler/14_break2.pl | 15 + foiler/15_shebang.pl | 23 + foiler/16_strict.pl | 15 + foiler/17_nonstrict_eks.pl | 27 + foiler/18_warnings.pl | 15 + foiler/19_pekere.pl | 25 + foiler/20_pekere2.pl | 25 + foiler/21_todimensjonalt.pl | 26 + foiler/22_todimensjonalt2.pl | 20 + foiler/23_lesing.pl | 21 + foiler/24_lesing2.pl | 19 + foiler/25_chomp.pl | 22 + foiler/26_print.pl | 25 + foiler/27_printf.pl | 27 + foiler/28_split.pl | 26 + foiler/29_join.pl | 18 + foiler/30_magiske_variable.pl | 24 + foiler/31_subrutiner.pl | 18 + foiler/32_subrutiner2.pl | 26 + foiler/33_subrutiner_return.pl | 22 + foiler/34_subrutiner_array.pl | 18 + foiler/35_subrutiner_hash.pl | 25 + foiler/36_subrutiner_multivar.pl | 26 + foiler/37_subrutiner_dual_arrays.pl | 25 + foiler/38_prototyping.pl | 20 + foiler/39_prototyping2.pl | 20 + foiler/40_subrutiner_epilog.pl | 17 + plakat.html | 88 ++ plakat.pdf | Bin 0 -> 4412 bytes plakat.ps | 1787 +++++++++++++++++++++++++++ 46 files changed, 4835 insertions(+) create mode 100644 README.md create mode 100644 foiler.html create mode 100644 foiler.pl create mode 100644 foiler/01_velkommen.pl create mode 100644 foiler/02_whatis.pl create mode 100644 foiler/03_what.pl create mode 100644 foiler/04_syntaks.pl create mode 100644 foiler/05_vars.pl create mode 100644 foiler/06_quoting.pl create mode 100644 foiler/07_joining.pl create mode 100644 foiler/08_multiline.pl create mode 100644 foiler/09_logikk.pl create mode 100644 foiler/10_tekstlogikk.pl create mode 100644 foiler/11_while.pl create mode 100644 foiler/12_foreach.pl create mode 100644 foiler/13_break.pl create mode 100644 foiler/14_break2.pl create mode 100644 foiler/15_shebang.pl create mode 100644 foiler/16_strict.pl create mode 100644 foiler/17_nonstrict_eks.pl create mode 100644 foiler/18_warnings.pl create mode 100644 foiler/19_pekere.pl create mode 100644 foiler/20_pekere2.pl create mode 100644 foiler/21_todimensjonalt.pl create mode 100644 foiler/22_todimensjonalt2.pl create mode 100644 foiler/23_lesing.pl create mode 100644 foiler/24_lesing2.pl create mode 100644 foiler/25_chomp.pl create mode 100644 foiler/26_print.pl create mode 100644 foiler/27_printf.pl create mode 100644 foiler/28_split.pl create mode 100644 foiler/29_join.pl create mode 100644 foiler/30_magiske_variable.pl create mode 100644 foiler/31_subrutiner.pl create mode 100644 foiler/32_subrutiner2.pl create mode 100644 foiler/33_subrutiner_return.pl create mode 100644 foiler/34_subrutiner_array.pl create mode 100644 foiler/35_subrutiner_hash.pl create mode 100644 foiler/36_subrutiner_multivar.pl create mode 100644 foiler/37_subrutiner_dual_arrays.pl create mode 100644 foiler/38_prototyping.pl create mode 100644 foiler/39_prototyping2.pl create mode 100644 foiler/40_subrutiner_epilog.pl create mode 100644 plakat.html create mode 100644 plakat.pdf create mode 100644 plakat.ps diff --git a/README.md b/README.md new file mode 100644 index 0000000..2540e8c --- /dev/null +++ b/README.md @@ -0,0 +1,16 @@ +# Nybegynnerkurs i Perl + +- **Dato:** Torsdag 28. oktober 2004 +- **Tid:** 18 til 20 +- **Sted:** Auditorium R8, Gløshaugen +- **Pris:** 50,- / 0,- (ikke-medlem / medlem) +- **Påmelding:** [kurs@pvv.org](mailto://kurs@pvv.org) + +PVV arrangerer et nybegynnerkurs i programmeringsspråket Perl. Kurset gjør +et forsøk på å lære deltakerene hvordan de kan lage enkle script, og gi et +grunnlag for å lære seg mer selv. Forutsetter litt programmeringserfaring. +Kurset er beregnet på folk som har litt erfaring med programmering fra før (å +kunne Java fra programmeringsfag burde være nok). + +Det er ikke nødvendig å sende påmelding, men det hadde vært fint slik at +vi fikk en viss oversikt over hvor mange som kommer. diff --git a/foiler.html b/foiler.html new file mode 100644 index 0000000..d5b174a --- /dev/null +++ b/foiler.html @@ -0,0 +1,1032 @@ + + +Foiler fra Perl-kurset 2004-10-28 + + + + +

Foiler fra Perl-kurset 2004-10-28

+

+Her er foilene fra perl-kurset 28. oktober 2004. HTML-en er dessverre full av ekle ting, men det +var nå sånn vim genererte den. Fy på vim! +

+
+#!/usr/bin/perl
+use strict;
+use warnings;
+
+my $msg = <<'EOF';
+
+
+
+    __     __   _ _                                        
+    \ \   / /__| | | _____  _ __ ___  _ __ ___   ___ _ __  
+     \ \ / / _ \ | |/ / _ \| '_ ` _ \| '_ ` _ \ / _ \ '_ \ 
+      \ V /  __/ |   < (_) | | | | | | | | | | |  __/ | | |
+       \_/ \___|_|_|\_\___/|_| |_| |_|_| |_| |_|\___|_| |_|
+                                                           
+             _   _ _   ____           _       _                   _ 
+            | |_(_) | |  _ \ ___ _ __| |     | | ___   _ _ __ ___| |
+            | __| | | | |_) / _ \ '__| |_____| |/ / | | | '__/ __| |
+            | |_| | | |  __/  __/ |  | |_____|   <| |_| | |  \__ \_|
+             \__|_|_| |_|   \___|_|  |_|     |_|\_\\__,_|_|  |___(_)
+                                                                    
+
+
+
+EOF
+
+print $msg;
+
+# ----------------------------------------------------------------------------------
+
+#!/usr/bin/perl
+use strict; use warnings;
+print <<'EOF';
+                              HVA ER PERL?
+    
+  * Betyr: Practical Extraction and Reporting Language
+  * Alternativt: Pathologically Eclectic Rubbish Lister
+  * Et cross-platform scriptingspråk skrevet av Larry Wall (han er kul)
+  * Virker i UNIX, Windows, på Mac, i VMS, etc etc
+  * Kildekoden til perl er åpen (GPL)
+  * Et tolket språk (kompileres ikke, "kompileres" hver gang det kjøres).
+
+                              HVORFOR PERL?
+
+  * Veldig kraftig, du kan gjøre mye med lite kode
+  * Kjapt å skrive
+  * Svært mange ferdige biblioteker ( http://search.cpan.org )
+  * Det er kult
+
+                            HVORFOR IKKE PERL?
+  
+  * Ting kan fort bli litt grisete om man er syk i hodet eller ikke tenker
+  * Veldig mye ulik syntaks (flere måter å gjøre det samme på)
+  * Det blir en del krangling med Python-folk
+  * Python-folkene kommer sikkert på mer...
+
+EOF
+
+# ----------------------------------------------------------------------------------
+
+#!/usr/bin/perl
+use strict;
+use warnings;
+
+print <<'EOF'
+
+                        HVA VI SKAL HA I DETTE KURSET
+
+   Det finnes to typer perl:
+   * Oneliner-perl (kjappe triks man bare skal bruke en gang (eller ha på
+     t-skjorta))
+   * Produksjonskode-perl (relativt pen, leselig kode)
+
+   Ikke alle ser denne forskjellen. De som ikke ser denne forskjellen er
+   grunnen til at perl har rykte på seg for å være uleselig og grisete,
+   såkalt "write once".
+
+   Jeg er ikke så glad i dem som ikke ser forskjellen. Spesielt ikke når jeg
+   må fikse på koden deres.
+
+   I dette kurset skal vi lære om produksjonskode-perl. Oneliner-perl lærer
+   dere tidsnok selv ;-)
+
+EOF
+
+# ----------------------------------------------------------------------------------
+
+#!/usr/bin/perl
+use strict;
+use warnings;
+
+print <<"EOF"
+# Enkel syntaks:
+
+ * Minner veldig om C, PHP og Java. 
+ * { og } deler inn blokker, 
+ * ( og ) rundt argumenter, etc (MEN: valgfrie). 
+ * Alle statements avsluttes med semikolon
+ 
+EOF
+
+# Parenteser rundt er valgfrie. Begge disse virker:
+
+print "hei\n";
+print("hei\n");
+
+# Parenteser brukes for å angi skop. Dette er spesielt nyttig når man har 
+# flere kommandoer nøstet inni hverandre. Lurer du på om det funker uten 
+# parentes? Da beholder du parentesene. Lesbar kode er viktig.
+
+# ----------------------------------------------------------------------------------
+
+#!/usr/bin/perl
+use strict;
+use warnings;
+
+## Variabler og slikt
+# Variabler, arrays og hasher deklareres med ordet "my". Det holder med ett 
+# ord for å deklarere, siden Perl ikke bryr seg så mye om innholdet i 
+# variabler. Om det er et heltall, et desimaltall eller tekst tas litt på
+# gefühlen.
+
+# En vanlig variabel (såkalt "skalar):
+my $tall = 15;
+my $tekst = 'hei';
+
+# En array:
+my @array;
+@array = (15, 'hei');    # Definer alle verdier
+$array[2] = 'gunnar';    # Sett tredje element
+
+# En hash:
+my %hash = ('ottar' => 15, 'pelle' => 17);  # Definer alle verdier
+$hash{'bjarne'} = 13;                       # Sett verdi for bjarne
+
+
+# ----------------------------------------------------------------------------------
+
+#!/usr/bin/perl
+use strict; use warnings;
+
+## Quoting
+# Ulike hermetegn oppfører seg forskjellig, på samme måte som i PHP 
+# (PHP rappet det av Perl). 
+
+my $test = 'ottar';
+
+print "hei $test\n";   # printer dette: hei ottar
+print 'hei $test\n';   # printer dette: hei $test\n
+
+
+
+# ----------------------------------------------------------------------------------
+
+#!/usr/bin/perl
+use strict; use warnings;
+
+## Hvordan slå sammen tekst (også likt som i PHP, av samme grunn)
+
+# Flere tekststrenger slås sammen med punktum (Java bruker pluss).
+my $fornavn = "Kjell Magne";
+my $etternavn = "Bondevik";
+my $fulltnavn = $fornavn . ' ' . $etternavn;
+
+# Vi kunne selvsagt også brukt dette, som også er mye vanligere å bruke:
+$fulltnavn = "$fornavn $etternavn";
+
+# Men av og til er "" upraktisk, som f.eks. om du skal printe ut HTML, 
+# eller har verdiene i noe annet enn variabler.
+my %verdier = ('uid' => 1015, 'bnavn' => 'kjellmangle');
+
+# Dette:
+print '<a href="' . $verdier{'uid'} . '">' . $verdier{'bnavn'} . "</a>\n";
+
+# Er penere enn dette:
+print "<a href=\"$verdier{'uid'}\">$verdier{'bnavn'}</a>\n";
+
+# Men begge virker, selv om highlightingen min ikke tror det.
+# At noe virker men blir highlightet feil er ofte et hint. Ta hintet.
+
+# ----------------------------------------------------------------------------------
+
+#!/usr/bin/perl
+use strict; use warnings;
+
+## Ting på flere linjer: bruk enten punktum eller <<"EOF";.
+
+# Punktum (Som regel best):
+my $test = "ottar";
+my $langvariabel = "Denne teksten på flere linjer er dedikert til\n"
+                 . "min gode venn og følgesvenn $test\n";
+
+# <<"EOF"; (Bruk bare når det er _store_ greier, og punktum blir veldig
+# tungvint. Ikke spesielt viktig å kunne, men greit å vite om):
+
+$langvariabel = <<"EOF";
+Denne teksten på flere linjer er dedikert til
+min gode venn og følgesvenn $test
+EOF
+
+$langvariabel = <<'EOG';
+Denne teksten på flere linjer er dedikert til
+min gode venn og følgesvenn $test
+EOG
+
+# Det inni hermetegnene er et merke. Alt helt ned til merket blir med i 
+# variabelen. Hva som skjer med teksten inni avhenger av hermetegnene rundt 
+# merket. Husk å bruke samme merke bare en gang! Pass på semikolonet!
+
+# ----------------------------------------------------------------------------------
+
+#!/usr/bin/perl
+use strict;
+use warnings;
+
+## Logikk med tallverdier
+# Logikk i perl ligner veldig på andre språk som C, PHP og Java.
+# 0, tom streng og udefinert er false, det meste annet er true (som i PHP).
+# IKKE utnytt dette for mye. Det blir vanskelig å lese. Test bare rett på 
+# variabelen om du bruker variabelen som en boolean.
+
+# Booleans (1 = sant, 0 = usant):
+my $boolean = 1;
+if ($boolean) {
+    print "\$boolean er sann!\n";  # Dette skjer.
+} else {
+    print "\$boolean er usann!\n"; # Dette skjer ikke.
+}
+
+my $tall = 15;
+if ($tall > 10) {
+    print "\$tall er over 10!\n";
+}
+elsif ($tall < 5) {                # elsif står for "else if"
+    print "\$tall under over 5!\n";
+}
+
+# ----------------------------------------------------------------------------------
+
+#!/usr/bin/perl
+use strict;
+use warnings;
+
+## Logikk med tekstverdier
+
+# Dere som kan PHP er vant til å bruke "==" på tekststrenger. Det virker 
+# IKKE i Perl! I Perl er det egne greier for å sammenligne ord.
+
+# De viktigste:
+#  eq: er lik
+#  ne: er ikke lik
+
+my $tekst = "banan";
+if ($tekst eq "banan") {
+    print "\$tekst er lik banan\n";
+}
+
+if ($tekst ne "eple") {
+    print "\$tekst er ikke lik eple\n";
+}
+
+if (length($tekst) > 3) {
+    print "\$tekst er mer enn tre tegn lang\n";
+}
+
+# ----------------------------------------------------------------------------------
+
+#!/usr/bin/perl
+use strict;
+use warnings;
+
+## While-loop
+# En while-loop i perl virker akkurat som i andre språk. Yay!
+
+my $counter = 0;
+while ($counter < 10) {
+    print "tallet er $counter\n";
+    $counter++;                       # Øker $counter med 1
+}
+
+## For-loop
+# Virker også som i andre språk! Hurra!
+
+for (my $tall = 0; $tall < 10; $tall++) {
+    print "tallet er $tall\n";
+}
+
+# ----------------------------------------------------------------------------------
+
+#!/usr/bin/perl
+use strict;
+use warnings;
+
+## Foreach-loopen
+# Denne er litt spesiell. Man har noe lignende i PHP, men syntaksen er ulik.
+# Foreach går gjennom hvert element i en liste.
+
+my @array = ('gunnar', 'ottar', 'per ulf');
+
+# Legg merke til at løpevariabelen $verdi angis utenfor parentesen!
+foreach my $verdi (@array) {
+    print "$verdi\n";
+}
+
+# Man kan også bruke foreach til å løpe over alle nøklene i en hash:
+my %hash = ( 'uid' => 3425, 'bnavn' => 'ottar', 'rnavn' => 'Ottar Evje' );
+
+# Kommandoen "keys" gir ut en array med alle nøklene i hashen, så dette er 
+# egentlig akkurat det samme.
+foreach my $key (keys %hash) {
+    print $key . " = " . $hash{$key} . "\n";
+}
+
+# Foreach er dritnyttig!
+
+# ----------------------------------------------------------------------------------
+
+#!/usr/bin/perl
+use strict; use warnings;
+
+## Å bryte ut av looper i Perl
+# Når man skal bryte ut av looper er Perl litt rart. Alt heter noe annet enn
+# det gjør i andre språk! Dette er jo skikkelig teit, men man venner seg
+# til det ganske fort. Jeg tipper grunnen er at perl ble laget for å parse
+# tekst, og da virket disse navnene mer logiske.
+#
+# En liten tabell: 
+#     +------+-------------+---------------------------------------------+
+#     | Perl | Andre språk | Betydning                                   |
+#     +------+-------------+---------------------------------------------+
+#     | next | continue    | Hopp over det som er nedenfor og kjør neste |
+#     |      |             | runde i loopen                              |
+#     +------+-------------+---------------------------------------------+
+#     | last | break       | Avbryt kjøringen av hele loopen             |
+#     +------+-------------+---------------------------------------------+
+
+# Eksempel på next:
+foreach my $tall (1, 2, 3) {
+    if ($tall == 2) {
+        next;
+    }
+    print "tallet er $tall!\n";
+}
+
+# ----------------------------------------------------------------------------------
+
+#!/usr/bin/perl
+use strict;
+use warnings;
+
+# Eksempel på "last": Rakettutskyting med forviklinger
+
+for (my $tall = 10; $tall > 0; $tall--) {
+    print "$tall...\n";
+
+    # Oh no! Når vi kommer til 5 eksploderer raketten!
+    if ($tall == 5) {
+        print "Boom!\n";
+        last; # Her avbryter loopen
+    }
+}
+
+# ----------------------------------------------------------------------------------
+
+#!/usr/bin/perl
+use strict;
+use warnings;
+
+### Hva er egentlig det greiene på toppen av alle foilene?
+
+## Shebangen
+#
+# #!/usr/bin/perl er en såkalt shebang. Den forteller hva slags språk
+# scriptet er skrevet i, og hva slags program som skal brukes til å tolke 
+# det.
+#
+# Om ikke shebangen var det ville vi måttet vite hva scriptet var skrevet i,
+# og selv kjørt programmet med filen som argument.
+#
+# Uten shebang:
+#   perl program.pl
+#
+# Med shebang:
+#   ./program.pl
+#
+# For at programmet skal kunne kjøres direkte må det også være kjørbart.
+# "chmod +x program.pl" fikser den biffen.
+
+# ----------------------------------------------------------------------------------
+
+#!/usr/bin/perl
+use strict;
+use warnings;
+
+## use strict:
+#
+# Uten use strict trenger man ikke å deklarere variabler. Variabler blir 
+# bare opprettet når de trengs av seg selv. Kjekt? Nei.
+#
+# Alle variabler som er implisitt deklarert blir nemlig globale. 
+# Globale variabler er ikke bra.
+#
+# Dessuten blir det plutselig mulig å bruke samme variabel til flere ting 
+# uten å merke det. Det er heller ikke bra.
+
+
+# ----------------------------------------------------------------------------------
+
+#!/usr/bin/perl
+use warnings;
+
+# Eksempel uten strict. Merk at det ikke er noen "use strict" øverst.
+# Vi tenker oss en webtjeneste der brukeren kan logge inn. Brukeren er 
+# innlogget som "rob-geir".
+$user = "rob-geir";
+print "Du er logget inn som: $user\n";
+
+# maaaange linjer kode med magi og ting. Vi har helt glemt $user.
+
+# Hoi, systemet har en funksjon som lister opp alle som er innlogget.
+# Akkurat nå er det disse tre:
+@users = ('ottar', 'rob-geir', 'dan-børge' );
+
+# Vi lister opp alle brukerene. Men hold an! Her brukte vi jo $user på nytt!
+print "Brukere innlogget: ";
+for ($i = 0; $i < scalar @users; $i++){
+    $user = $users[$i];
+    print "$user ";
+}
+print "\n";
+
+# Maaange linjer med kode. Nå har vi glemt brukerlisten.
+
+# Nederst på siden vil vi vise hvem som er logget inn en gang til.
+print "Du er logget inn som: $user\n";
+
+# ----------------------------------------------------------------------------------
+
+#!/usr/bin/perl
+use warnings;
+
+# Warnings betyr akkurat det som står: Advarsler. Det gjør at perl advarer 
+# når noe ser rart ut. Du vil ha det. Om koden din gir advarsler er det fordi
+# du har gjort noe du ikke burde gjøre.
+#
+# Jeg fjernet use strict denne gangen, så det skulle bli lettere å gjøre
+# noe dumt warnings kunne oppdage.
+
+# Eksempel på hvorfor warnings er bra:
+
+my $foo = "bar";
+
+print "hei, jeg er $bar\n"; # Å nei! Feil variabelnavn!
+
+# ----------------------------------------------------------------------------------
+
+#!/usr/bin/perl
+use strict;
+use warnings;
+
+## Kompliserte datastrukturer i Perl
+# Perl versjon 4 (som ingen bruker lenger) hadde ingen støtte for å nøste
+# arrays og lignende. Todimensjonale arrays var ikke mulig. Folk brukte all
+# verdens grisete triks for å få til noe tilsvarende. Æsj!
+#
+# Perl versjon 5 har egentlig heller ikke støtte for flerdimensjonale arrays
+# eller sånne ting, men det merker vi ikke stort til. Nå har vi nemlig pekere!
+#
+# Pekere i perl kan minne om pointere i C eller objektreferanser i Java.
+
+# Vi har arrayen @array
+my @array = ('ottar', 'spiser', 'fisk');
+
+# Vi lager en referanse
+my $ref = [ @array ]; # Firkantparenteser til array, akkurat som ved henting
+                      # av verdier
+
+# Vi får tilbake arrayen med @{}:
+my @sammearray = @{$ref};  # denne sier: $ref er egentlig en array, altså!
+
+# Det samme gjelder for hasher, men med { %hash } og %{$ref}
+
+# ----------------------------------------------------------------------------------
+
+#!/usr/bin/perl
+use strict;
+use warnings;
+
+# Vi kan også gjøre ting litt mer direkte, uten å lage @array først:
+my $arrayref = [ 'geir', 'liker', 'sko' ];
+
+# Og så kan vi hente ut verdier direkte på to måter. De er omtrent like bra,
+# så det er bare å velge den du liker best. Personlig derefererer jeg gjerne 
+# referansen og bruker arrayen/hashen direkte etterpå, som på forrige foil.
+print @{$arrayref}[0] . "\n"; # Bruker @{} som før
+print $arrayref->[0] . "\n";  # Derefererer peker med ->, som i C.
+
+# Det samme virker for hasher:
+my $hashref = { 'name' => 'ottar', 'liker' => 'sko' };
+my %hash = %{$hashref};
+
+print %{$hashref}->{'name'} . "\n"; # Perl liker ikke }{, så vi må ha pil.
+print $hashref->{'name'} . "\n";
+print $hash{'name'} . "\n";
+
+# Legg merke til at den første bare er stygg, og de to siste ligner ganske
+# mye på hverandre. Ukritisk bruk av referanser kan være en potensiell
+# feilkilde, siden det er lett å blingse. Bare lag en vanlig hash eller
+# array, så unngår du problemet.
+
+# ----------------------------------------------------------------------------------
+
+#!/usr/bin/perl
+use strict;
+use warnings;
+
+## Så, til poenget: Hvordan lage todimensjonale ting?
+# Todimensjonale arrays i Perl 5 er en array med arrayreferanser i.
+# Hva merker vi til dette? Ingen ting. Perl fikser det for oss automatisk.
+
+my @array;
+$array[0] = [ 'rob-geir' ]; # Vi legger en array-referanse fremst i arrayen.
+
+# Om vi printer ut $array[0] nå, får vi bare en referanse, omtrent som når vi
+# printer et rart objekt i Java. Den ser slik ut: "ARRAY(0x814cd28)"
+print $array[0] . "\n";
+
+# Dette er altså egentlig en referanse. Men vent nå litt, da kan vi jo bruke
+# pil-notasjonen fra forrige foil!
+print $array[0]->[0] . "\n";
+
+# Men denne pilen er jo kjedelig å skrive. Det fikser Perl! Det virker nemlig
+# uten også!
+print $array[0][0] . "\n";
+
+# Og vips, vi merker ingen ting til dette rare referanse-greiene!
+# Men, det er jo kjekt å vite om dem. Vi kan nemlig bruke dem andre steder
+# også.
+
+# ----------------------------------------------------------------------------------
+
+#!/usr/bin/perl
+use strict;
+use warnings;
+
+# Men av og til må vi likevel vite om dette rare med pekerene. Si vi lager en
+# todimensjonal array med navn i:
+my @array = (
+        [ 'gunnar', 'ottar', 'bengt-åke' ],
+        [ 'kåre', 'ole-rånni', 'per' ],
+        [ 'kåbbai-laila', 'per-kristian foss' ]
+    );
+
+# Og så vil vi gå gjennom alle verdiene:
+foreach my $ref (@array) {
+    my @navn = @{$ref};   # Foreach gir oss referansen, så vi lager en array
+    foreach my $navn (@navn) {
+        print "$navn\n";
+    }
+    print "\n";           # Printer et linjeskift etter hver gruppe
+}
+
+# ----------------------------------------------------------------------------------
+
+#!/usr/bin/perl
+use strict;
+use warnings;
+
+## Å lese inn ting med perl
+# Noe av det man gjør oftest i perl er å lese inn data. Dette gjør man med 
+# "<>". Omtrent sånn:
+
+## Lese fra standard in
+# En og en linje:
+while (my $linje = <STDIN>) {
+    print $linje;
+}
+
+# Alt inn i en stor array (krever mer minne, unngå om du kan):
+my @array = <STDIN>;
+foreach my $linje (@array) {
+    print $linje;
+}
+
+
+
+# ----------------------------------------------------------------------------------
+
+#!/usr/bin/perl
+use strict;
+use warnings;
+
+## Å lese fra en fil:
+# Åpne filen, eller dø om det ikke virket.
+open(my $FILDESKRIPTOR, "test.txt") or die("Kunne ikke åpne test.txt: $!");
+
+# Les, og print ut med "> " foran:
+while(my $linje = <$FILDESKRIPTOR>) {
+    print "> $linje";
+}
+
+# Lukk.
+close($FILDESKRIPTOR);
+
+# Hett tips: open kan også brukes for å åpne ting for skriving.
+# Kjør kommandoen "perldoc -f open" for å få masse info om alt du
+# kan gjøre med open.
+
+# ----------------------------------------------------------------------------------
+
+#!/usr/bin/perl
+use strict;
+use warnings;
+
+## Fjerne linjeskift fra det du leser
+# Til forskjell fra f.eks. sed og grep, fjerner ikke perl linjeskift av seg
+# selv. Om du ikke vil ha dem, må du fjerne dem.
+# Til dette har vi kommandoen chomp.
+
+while (my $linje = <STDIN>) {
+    chomp($linje);
+    print "$linje\n"; # ok, litt unyttig å bare sette på igjen linjeskiftet.
+}
+
+# chomp kan også kjøres rett på en hel array. Da fikser den alle verdiene.
+
+my @array = <STDIN>;
+chomp(@array);
+
+# NB! Det er veldig vanlig å glemme chomp, og så fortsette i god tro.
+# Det kan føre til ekle bugs der linjeskift dukker opp på rare steder.
+# Jeg vet dette fordi jeg gjør det hele tiden selv ;-)
+
+# ----------------------------------------------------------------------------------
+
+#!/usr/bin/perl
+use strict;
+use warnings;
+
+## Printing i Perl
+# Hittil har vi bare sett på basic bruk av print. Men print kan brukes til 
+# mer. For eksempel en fildeskriptor:
+
+# Dette burde gi morosakene ut på standard error.
+# PS: Det er IKKE komma etter fildeskriptoren når du printer!
+print STDERR "Aaaah! Venstre motor brenner!\n";
+
+
+# Om du åpner noe med skrivetilgang med open kan og også bruke print der.
+# Dette overskriver test.txt:
+open(my $DESKR, ">test.txt") or die ("feil ved åpning av test.txt: $!");
+
+print $DESKR "Hei, har du det bra?\n";
+
+close($DESKR);
+
+
+# Print på en array printer alle verdiene:
+my @linjer = ("hei\n", "ost\n", "banan\n");
+print @linjer;
+
+# ----------------------------------------------------------------------------------
+
+#!/usr/bin/perl
+use strict; use warnings;
+
+## Printf: Fancy-schmancy printing
+# Der sitter du med et digert desimaltall, og vil printe det ut med to
+# desimaler. Printf to the rescue!
+my $tall = 3.1415;
+printf("pi: %.2f\n", $tall);
+
+# Eller du har en masse tallverdier med ulik lengde, og vil høyurejustere:
+my @tall = (3, 1337, 25, 254);
+foreach my $tall (@tall) {
+    printf("tall: %4d\n", $tall);  # juksa litt: hardkodet inn maksbredde fire
+}
+
+# Eller du vil printe ut et tall i hex, oktal og desimal, null-paddet til 
+# åtte sifre:
+printf("hex: %08x %08o %08d\n", 255, 255, 255);
+
+# Du kan også lagre resultatet i en annen variabel med sprintf:
+my $leet = sprintf("%03.2f", 13.37890);
+print $leet, "\n";
+# Dette er litt for omfattende til at vi kan herje veldig mye med det.
+# "perldoc -f sprintf" har mer info.
+#
+# Pass på! Det er lurere å bruke print om du ikke trenger ekstra formatering!
+# Printf er tregere, og det er lettere å gjøre feil.
+
+# ----------------------------------------------------------------------------------
+
+#!/usr/bin/perl
+use strict; use warnings;
+
+## Splitting av tekststrenger
+# Ofte har man en lang greie man vil splitte inn i en array. No problem!
+
+my $string = "www.pvv.ntnu.no";
+my @deler = split(".", $string);
+# nå inneholder @deler dette: ('www', 'pvv', 'ntnu', 'no');
+
+# Man kan også splitte på flere tegn:
+my $verdier = "en, to, tre, fire, fem";
+my @verdier = split(", ", $verdier);
+
+# I stedet for å skrive en string som tegnet man kan splitte på, kan man også
+# skrive et regulært uttrykk. Vi tar kanskje noe om regulære uttrykk senere,
+# hvis vi rekker det.
+
+# Å splitte på " " (mellomrom) er litt spesielt. Da oppfører perl seg som awk,
+# og gir deg alle ordene, uansett hvor mye whitespace det er mellom. 
+my $setn = "hei, jeg  er    ikke så   flink    med      mellomrom";
+my @setn = split(" ", $setn);
+
+# Om du vil at det skal bli som i cut, med blanke felter mellom spaces som er 
+# inntil hverandre, bruk regulæruttrykket / /:
+@setn = split(/ /, $setn);
+
+# ----------------------------------------------------------------------------------
+
+#!/usr/bin/perl
+use strict;
+use warnings;
+
+## Join, det motsatte av split
+# Hvis du har en array, og skal lage en tekststreng av verdiene, er join
+# tingen for deg. Den setter sammen alle feltene, med en tekststreng mellom.
+
+my @koner = ("magda", "gunhild", "gunda");
+my $penliste = join(", ", @koner);
+print "Koner: $penliste\n";
+
+# Ut kommer dette: "Koner: magda, gunhild, gunda"
+
+
+# Gammelt jegertriks for å lage en diger variabel av en array du har lest inn:
+my @linjer = <STDIN>;
+my $digervariabel = join("", @linjer); # Vi joiner på tom streng
+
+# ----------------------------------------------------------------------------------
+
+#!/usr/bin/perl
+use strict;
+use warnings;
+
+## Magiske variabler i Perl
+# De magiske variablene i Perl er beryktet, og flittig kritisert av 
+# Python-brukere. Og ja, de er litt ekle. Ikke bruk dem mer enn du må,
+# og husk å kommentere kode der du eventuelt bruker dem.
+
+# Disse tre dukker opp relativt ofte, og man forventes vel egentlig å kunne
+# dem, så de trenger man ikke forklare i koden. Men husk å forklare eventuelle
+# andre utskeielser!
+
+    $_ # Default-variabelen. Om ikke noe er angitt, brukes som regel
+       # denne. Kan stort sett unngås, men av og til lurer den seg inn.
+
+    @_ # Default-arrayen. Dukker stort sett bare opp som argumentene til
+       # subrutiner (mer om dem senere, om vi rekker det)
+
+    $! # Feilmelding. Denne variabelen inneholder siste feilmelding.
+       # Den ble brukt etter open for et par foiler siden.
+
+# Det er hauger av andre magiske variabler også, men disse tre får holde 
+# inntil videre. Er du nysgjerrig på mer, kjør kommandoen "perldoc perlvar".
+
+# ----------------------------------------------------------------------------------
+
+#!/usr/bin/perl
+use strict;
+use warnings;
+
+## Subrutiner (også kjent som funksjoner eller metoder)
+# Subrutiner er veldig kjekke for å strukturere scripts. De har litt
+# annerledes syntaks enn det vi er vant til, men ikke så veldig.
+
+# Vi lager en subrutine
+sub hei () {
+    print "hei!\n";
+}
+
+# ...og vi kjører den.
+hei();
+
+# ...og en gang til:
+hei();
+
+# ----------------------------------------------------------------------------------
+
+#!/usr/bin/perl
+use strict;
+use warnings;
+
+# Men vi vil kanskje gjerne gi subrutinen noen argumenter. For å fortelle 
+# subrutinen at den skal ta inn to variabler, gir vi den to $-tegn i 
+# parentesen:
+
+sub hei($$) {
+    my ($navn, $adjektiv) = @_;            # Oi, hva er dette?
+
+    print "Hei $navn, du er $adjektiv!\n";
+}
+
+# Og så hilser vi på noen
+hei("ottar", "kul");
+hei("pål", "illeluktende");
+
+# Nå dukket det opp litt nytt, spesielt den rare greia som heter @_. 
+# @_ er en magisk array der alle argumentene ligger. Jeg vet at det er to 
+# argumenter (det står jo "$$" i parentesen), så jeg kan bare hente dem ut 
+# direkte med to variabler inni en parentes.
+#
+# Denne parentesen er kanskje litt rar, men det er egentlig bare 
+# array-snarveien baklengs. Husk at vi kan si 
+my @array = ('per', 'pål');
+
+# ----------------------------------------------------------------------------------
+
+#!/usr/bin/perl
+use strict;
+use warnings;
+
+# Vi vil jo ofte returnere noe fra subrutinene våre. Det er lett. Bare bruk 
+# return $variabel:
+
+# Vi lager subrutinen fjortis, som setter masse utropstegn bakerst på
+# tekst:
+sub fjortis ($) {
+    my ( $tekst ) = @_;
+    return "$tekst!!!11";
+}
+
+# Hent ut fjortis-tegnsatt variabel
+my $fjortis = fjortis("hei");
+
+# Print den.
+print "$fjortis\n";
+
+# Print en dobbeltfjortis variabel
+print fjortis(fjortis("hallo")) . "\n";
+
+# ----------------------------------------------------------------------------------
+
+#!/usr/bin/perl
+use strict;
+use warnings;
+
+# Å sende inn og ut arrays fra subrutiner er lett:
+
+# En skikkelig unødvendig og teit subrutine som sorterer mot alfabetet:
+sub descsort (@) {
+    my @array = @_;
+    my @output = reverse sort @array;
+    return @output;
+}
+
+my @array = ('hei', '', 'aha');
+foreach my $ord (descsort(@array)) {
+    print "$ord\n";
+}
+
+
+# ----------------------------------------------------------------------------------
+
+#!/usr/bin/perl
+use strict;
+use warnings;
+
+# Å leke med en hash er også temmelig likt:
+
+sub print_hash (%) {
+    my %hash = @_;                 # Hold an! Hva er dette? Hash = Array? Hæ?
+
+    foreach my $key (keys %hash) {
+        print "$key = " . $hash{$key} . "\n";
+    }
+}
+
+my %hash = ( 'fnavn' => 'herodes', 'enavn' => 'falsk' );
+print_hash(%hash);
+
+# Dette med "%hash = @_" virker jo litt sært. Men legg merke til at vi bruker
+# de samme parentesene for å lage arrays og hasher. Faktisk er det bare piler
+# stedet for kommaer på annenhver for at det skal bli lettere å se hva som er
+# hva.
+#
+# Når du legger masse verdier inn i en hash gir du den altså bare en array
+# med verdier, og så blir annenhver verdi nøkkel og innhold.
+# (dette virker på samme måten i PHP).
+
+# ----------------------------------------------------------------------------------
+
+#!/usr/bin/perl
+use strict;
+use warnings;
+
+# Men hva om vi for eksempel vil gi inn to variabler og en array?
+
+sub felleseie ($$@) {
+    my $han = shift;              # Hva er denne shift?
+    my $hun = shift;
+    my @eiendeler = @_;
+    print "$han og $hun eier sammen dette:\n";
+    foreach my $ting (@eiendeler) {
+        print "\t$ting\n";
+    }
+}
+
+my @eiendeler = ('sofa', 'tv', 'stereo');
+felleseie("per", "kari", @eiendeler);
+
+# shift(@array) tar første verdi i @array, fjerner den fra arrayen og
+# returnerer den. ('en', 'to', 'tre') blir altså ('to', 'tre') etter shift.
+# Slik kan vi fjerne de to første variablene, og sitte igjen med resten, som
+# er til arrayen.
+# 
+# Grunnen til at det må gjøres slik er at @_ bare inneholder alle verdiene, 
+# den har ikke system på hva som er hva.
+
+# ----------------------------------------------------------------------------------
+
+#!/usr/bin/perl
+use strict;
+use warnings;
+
+# Men hva med to arrays? @_ vet jo ikke når den ene slutter og den andre 
+# begynner! Da må vi til med referanser igjen!
+
+sub tell_penisforlengere (\@\@) {
+    my @biler = @{ $_[0] };
+    my @baater = @{ $_[1] };
+
+    print "Det er ".scalar @biler." bilær og ".scalar @baater."båtær\n";
+}
+
+my @biler = ('mercedes', 'porsche', 'austin martin');
+my @baater = ('sjekte', 'campingcruiser', 'yacht', 'pråm');
+
+tell_penisforlengere(\@biler, \@baater);
+
+# Hva er disse backslashene? Bare en annen måte å lage referanser på.
+# I C ville de tilsvart '&var'. Hvilken du bruker er hipp som happ. 
+# Disse gjør det samme:
+my $biler;
+$biler = [ @biler ];
+$biler = \@biler;
+
+# ----------------------------------------------------------------------------------
+
+#!/usr/bin/perl
+use strict;
+use warnings;
+
+# Hittil har vi hatt funksjonen øverst i scriptet. Men da må vi jo scrolle
+# forbi masse drit for å se hva selve programmet gjør (man *skal* gi 
+# subrutinene så logiske navn at man skjønner hva de gjør ut fra navnet.
+
+# Dette fikser vi med en prototype. De er omtrent som i C:
+sub hei ($$);
+
+# Og så bruker vi den
+hei('rob-geir', 'tøff');
+hei('gunnar', 'sexy');
+
+# Og her kommer den.
+sub hei ($$) {
+    my ($navn, $adjektiv) = @_;
+    print "Hei $navn, du er $adjektiv!\n";
+}
+
+# ----------------------------------------------------------------------------------
+
+#!/usr/bin/perl
+use strict;
+use warnings;
+
+# Om du skriver rekursive funksjoner må du uansett prototype. 
+# La oss se på denne greia som teller nedover (på en skikkelig teit måte):
+
+sub tellned ($);
+
+sub tellned ($) {
+    my $tall = shift;
+
+    print "$tall...\n";
+
+    if ($tall > 0) {
+        tellned($tall-1);
+    }
+}
+
+tellned(10);
+
+# ----------------------------------------------------------------------------------
+
+#!/usr/bin/perl
+use strict;
+use warnings;
+
+## Noen siste ord om subrutiner
+# 
+# I en del gammel eller dårlig kode vil du kanskje oppdage at alle 
+# subrutinekall er med '&' foran, og at ingenting er prototypet.
+#
+# Dette var slik subrutiner virket før. De sjekket ikke antall argumenter 
+# eller noe som helst, og man sa fra om at de var subrutiner med &.
+# Det er fremdeles mulig å gjøre det slik av hensyn til bakoverkompatibilitet,
+# men IKKE GJØR DET!
+#
+# Om man gjør dette forsvinner nemlig alle former for feilsjekking rett i
+# rett i dass, siden &subrutine() slår av sjekking av antall argumenter og
+# slikt. Dette er et kjempetriks for å skjule bugs. Just don't do it, okay?
+
+# ----------------------------------------------------------------------------------
+
+
+ + diff --git a/foiler.pl b/foiler.pl new file mode 100644 index 0000000..65ba50c --- /dev/null +++ b/foiler.pl @@ -0,0 +1,1016 @@ +#!/usr/bin/perl +use strict; +use warnings; + +my $msg = <<'EOF'; + + + + __ __ _ _ + \ \ / /__| | | _____ _ __ ___ _ __ ___ ___ _ __ + \ \ / / _ \ | |/ / _ \| '_ ` _ \| '_ ` _ \ / _ \ '_ \ + \ V / __/ | < (_) | | | | | | | | | | | __/ | | | + \_/ \___|_|_|\_\___/|_| |_| |_|_| |_| |_|\___|_| |_| + + _ _ _ ____ _ _ _ + | |_(_) | | _ \ ___ _ __| | | | ___ _ _ __ ___| | + | __| | | | |_) / _ \ '__| |_____| |/ / | | | '__/ __| | + | |_| | | | __/ __/ | | |_____| <| |_| | | \__ \_| + \__|_|_| |_| \___|_| |_| |_|\_\\__,_|_| |___(_) + + + + +EOF + +print $msg; + +# ---------------------------------------------------------------------------------- + +#!/usr/bin/perl +use strict; use warnings; +print <<'EOF'; + HVA ER PERL? + + * Betyr: Practical Extraction and Reporting Language + * Alternativt: Pathologically Eclectic Rubbish Lister + * Et cross-platform scriptingspråk skrevet av Larry Wall (han er kul) + * Virker i UNIX, Windows, på Mac, i VMS, etc etc + * Kildekoden til perl er åpen (GPL) + * Et tolket språk (kompileres ikke, "kompileres" hver gang det kjøres). + + HVORFOR PERL? + + * Veldig kraftig, du kan gjøre mye med lite kode + * Kjapt å skrive + * Svært mange ferdige biblioteker ( http://search.cpan.org ) + * Det er kult + + HVORFOR IKKE PERL? + + * Ting kan fort bli litt grisete om man er syk i hodet eller ikke tenker + * Veldig mye ulik syntaks (flere måter å gjøre det samme på) + * Det blir en del krangling med Python-folk + * Python-folkene kommer sikkert på mer... + +EOF + +# ---------------------------------------------------------------------------------- + +#!/usr/bin/perl +use strict; +use warnings; + +print <<'EOF' + + HVA VI SKAL HA I DETTE KURSET + + Det finnes to typer perl: + * Oneliner-perl (kjappe triks man bare skal bruke en gang (eller ha på + t-skjorta)) + * Produksjonskode-perl (relativt pen, leselig kode) + + Ikke alle ser denne forskjellen. De som ikke ser denne forskjellen er + grunnen til at perl har rykte på seg for å være uleselig og grisete, + såkalt "write once". + + Jeg er ikke så glad i dem som ikke ser forskjellen. Spesielt ikke når jeg + må fikse på koden deres. + + I dette kurset skal vi lære om produksjonskode-perl. Oneliner-perl lærer + dere tidsnok selv ;-) + +EOF + +# ---------------------------------------------------------------------------------- + +#!/usr/bin/perl +use strict; +use warnings; + +print <<"EOF" +# Enkel syntaks: + + * Minner veldig om C, PHP og Java. + * { og } deler inn blokker, + * ( og ) rundt argumenter, etc (MEN: valgfrie). + * Alle statements avsluttes med semikolon + +EOF + +# Parenteser rundt er valgfrie. Begge disse virker: + +print "hei\n"; +print("hei\n"); + +# Parenteser brukes for å angi skop. Dette er spesielt nyttig når man har +# flere kommandoer nøstet inni hverandre. Lurer du på om det funker uten +# parentes? Da beholder du parentesene. Lesbar kode er viktig. + +# ---------------------------------------------------------------------------------- + +#!/usr/bin/perl +use strict; +use warnings; + +## Variabler og slikt +# Variabler, arrays og hasher deklareres med ordet "my". Det holder med ett +# ord for å deklarere, siden Perl ikke bryr seg så mye om innholdet i +# variabler. Om det er et heltall, et desimaltall eller tekst tas litt på +# gefühlen. + +# En vanlig variabel (såkalt "skalar): +my $tall = 15; +my $tekst = 'hei'; + +# En array: +my @array; +@array = (15, 'hei'); # Definer alle verdier +$array[2] = 'gunnar'; # Sett tredje element + +# En hash: +my %hash = ('ottar' => 15, 'pelle' => 17); # Definer alle verdier +$hash{'bjarne'} = 13; # Sett verdi for bjarne + + +# ---------------------------------------------------------------------------------- + +#!/usr/bin/perl +use strict; use warnings; + +## Quoting +# Ulike hermetegn oppfører seg forskjellig, på samme måte som i PHP +# (PHP rappet det av Perl). + +my $test = 'ottar'; + +print "hei $test\n"; # printer dette: hei ottar +print 'hei $test\n'; # printer dette: hei $test\n + + + +# ---------------------------------------------------------------------------------- + +#!/usr/bin/perl +use strict; use warnings; + +## Hvordan slå sammen tekst (også likt som i PHP, av samme grunn) + +# Flere tekststrenger slås sammen med punktum (Java bruker pluss). +my $fornavn = "Kjell Magne"; +my $etternavn = "Bondevik"; +my $fulltnavn = $fornavn . ' ' . $etternavn; + +# Vi kunne selvsagt også brukt dette, som også er mye vanligere å bruke: +$fulltnavn = "$fornavn $etternavn"; + +# Men av og til er "" upraktisk, som f.eks. om du skal printe ut HTML, +# eller har verdiene i noe annet enn variabler. +my %verdier = ('uid' => 1015, 'bnavn' => 'kjellmangle'); + +# Dette: +print '' . $verdier{'bnavn'} . "\n"; + +# Er penere enn dette: +print "$verdier{'bnavn'}\n"; + +# Men begge virker, selv om highlightingen min ikke tror det. +# At noe virker men blir highlightet feil er ofte et hint. Ta hintet. + +# ---------------------------------------------------------------------------------- + +#!/usr/bin/perl +use strict; use warnings; + +## Ting på flere linjer: bruk enten punktum eller <<"EOF";. + +# Punktum (Som regel best): +my $test = "ottar"; +my $langvariabel = "Denne teksten på flere linjer er dedikert til\n" + . "min gode venn og følgesvenn $test\n"; + +# <<"EOF"; (Bruk bare når det er _store_ greier, og punktum blir veldig +# tungvint. Ikke spesielt viktig å kunne, men greit å vite om): + +$langvariabel = <<"EOF"; +Denne teksten på flere linjer er dedikert til +min gode venn og følgesvenn $test +EOF + +$langvariabel = <<'EOG'; +Denne teksten på flere linjer er dedikert til +min gode venn og følgesvenn $test +EOG + +# Det inni hermetegnene er et merke. Alt helt ned til merket blir med i +# variabelen. Hva som skjer med teksten inni avhenger av hermetegnene rundt +# merket. Husk å bruke samme merke bare en gang! Pass på semikolonet! + +# ---------------------------------------------------------------------------------- + +#!/usr/bin/perl +use strict; +use warnings; + +## Logikk med tallverdier +# Logikk i perl ligner veldig på andre språk som C, PHP og Java. +# 0, tom streng og udefinert er false, det meste annet er true (som i PHP). +# IKKE utnytt dette for mye. Det blir vanskelig å lese. Test bare rett på +# variabelen om du bruker variabelen som en boolean. + +# Booleans (1 = sant, 0 = usant): +my $boolean = 1; +if ($boolean) { + print "\$boolean er sann!\n"; # Dette skjer. +} else { + print "\$boolean er usann!\n"; # Dette skjer ikke. +} + +my $tall = 15; +if ($tall > 10) { + print "\$tall er over 10!\n"; +} +elsif ($tall < 5) { # elsif står for "else if" + print "\$tall under over 5!\n"; +} + +# ---------------------------------------------------------------------------------- + +#!/usr/bin/perl +use strict; +use warnings; + +## Logikk med tekstverdier + +# Dere som kan PHP er vant til å bruke "==" på tekststrenger. Det virker +# IKKE i Perl! I Perl er det egne greier for å sammenligne ord. + +# De viktigste: +# eq: er lik +# ne: er ikke lik + +my $tekst = "banan"; +if ($tekst eq "banan") { + print "\$tekst er lik banan\n"; +} + +if ($tekst ne "eple") { + print "\$tekst er ikke lik eple\n"; +} + +if (length($tekst) > 3) { + print "\$tekst er mer enn tre tegn lang\n"; +} + +# ---------------------------------------------------------------------------------- + +#!/usr/bin/perl +use strict; +use warnings; + +## While-loop +# En while-loop i perl virker akkurat som i andre språk. Yay! + +my $counter = 0; +while ($counter < 10) { + print "tallet er $counter\n"; + $counter++; # Øker $counter med 1 +} + +## For-loop +# Virker også som i andre språk! Hurra! + +for (my $tall = 0; $tall < 10; $tall++) { + print "tallet er $tall\n"; +} + +# ---------------------------------------------------------------------------------- + +#!/usr/bin/perl +use strict; +use warnings; + +## Foreach-loopen +# Denne er litt spesiell. Man har noe lignende i PHP, men syntaksen er ulik. +# Foreach går gjennom hvert element i en liste. + +my @array = ('gunnar', 'ottar', 'per ulf'); + +# Legg merke til at løpevariabelen $verdi angis utenfor parentesen! +foreach my $verdi (@array) { + print "$verdi\n"; +} + +# Man kan også bruke foreach til å løpe over alle nøklene i en hash: +my %hash = ( 'uid' => 3425, 'bnavn' => 'ottar', 'rnavn' => 'Ottar Evje' ); + +# Kommandoen "keys" gir ut en array med alle nøklene i hashen, så dette er +# egentlig akkurat det samme. +foreach my $key (keys %hash) { + print $key . " = " . $hash{$key} . "\n"; +} + +# Foreach er dritnyttig! + +# ---------------------------------------------------------------------------------- + +#!/usr/bin/perl +use strict; use warnings; + +## Å bryte ut av looper i Perl +# Når man skal bryte ut av looper er Perl litt rart. Alt heter noe annet enn +# det gjør i andre språk! Dette er jo skikkelig teit, men man venner seg +# til det ganske fort. Jeg tipper grunnen er at perl ble laget for å parse +# tekst, og da virket disse navnene mer logiske. +# +# En liten tabell: +# +------+-------------+---------------------------------------------+ +# | Perl | Andre språk | Betydning | +# +------+-------------+---------------------------------------------+ +# | next | continue | Hopp over det som er nedenfor og kjør neste | +# | | | runde i loopen | +# +------+-------------+---------------------------------------------+ +# | last | break | Avbryt kjøringen av hele loopen | +# +------+-------------+---------------------------------------------+ + +# Eksempel på next: +foreach my $tall (1, 2, 3) { + if ($tall == 2) { + next; + } + print "tallet er $tall!\n"; +} + +# ---------------------------------------------------------------------------------- + +#!/usr/bin/perl +use strict; +use warnings; + +# Eksempel på "last": Rakettutskyting med forviklinger + +for (my $tall = 10; $tall > 0; $tall--) { + print "$tall...\n"; + + # Oh no! Når vi kommer til 5 eksploderer raketten! + if ($tall == 5) { + print "Boom!\n"; + last; # Her avbryter loopen + } +} + +# ---------------------------------------------------------------------------------- + +#!/usr/bin/perl +use strict; +use warnings; + +### Hva er egentlig det greiene på toppen av alle foilene? + +## Shebangen +# +# #!/usr/bin/perl er en såkalt shebang. Den forteller hva slags språk +# scriptet er skrevet i, og hva slags program som skal brukes til å tolke +# det. +# +# Om ikke shebangen var det ville vi måttet vite hva scriptet var skrevet i, +# og selv kjørt programmet med filen som argument. +# +# Uten shebang: +# perl program.pl +# +# Med shebang: +# ./program.pl +# +# For at programmet skal kunne kjøres direkte må det også være kjørbart. +# "chmod +x program.pl" fikser den biffen. + +# ---------------------------------------------------------------------------------- + +#!/usr/bin/perl +use strict; +use warnings; + +## use strict: +# +# Uten use strict trenger man ikke å deklarere variabler. Variabler blir +# bare opprettet når de trengs av seg selv. Kjekt? Nei. +# +# Alle variabler som er implisitt deklarert blir nemlig globale. +# Globale variabler er ikke bra. +# +# Dessuten blir det plutselig mulig å bruke samme variabel til flere ting +# uten å merke det. Det er heller ikke bra. + + +# ---------------------------------------------------------------------------------- + +#!/usr/bin/perl +use warnings; + +# Eksempel uten strict. Merk at det ikke er noen "use strict" øverst. +# Vi tenker oss en webtjeneste der brukeren kan logge inn. Brukeren er +# innlogget som "rob-geir". +$user = "rob-geir"; +print "Du er logget inn som: $user\n"; + +# maaaange linjer kode med magi og ting. Vi har helt glemt $user. + +# Hoi, systemet har en funksjon som lister opp alle som er innlogget. +# Akkurat nå er det disse tre: +@users = ('ottar', 'rob-geir', 'dan-børge' ); + +# Vi lister opp alle brukerene. Men hold an! Her brukte vi jo $user på nytt! +print "Brukere innlogget: "; +for ($i = 0; $i < scalar @users; $i++){ + $user = $users[$i]; + print "$user "; +} +print "\n"; + +# Maaange linjer med kode. Nå har vi glemt brukerlisten. + +# Nederst på siden vil vi vise hvem som er logget inn en gang til. +print "Du er logget inn som: $user\n"; + +# ---------------------------------------------------------------------------------- + +#!/usr/bin/perl +use warnings; + +# Warnings betyr akkurat det som står: Advarsler. Det gjør at perl advarer +# når noe ser rart ut. Du vil ha det. Om koden din gir advarsler er det fordi +# du har gjort noe du ikke burde gjøre. +# +# Jeg fjernet use strict denne gangen, så det skulle bli lettere å gjøre +# noe dumt warnings kunne oppdage. + +# Eksempel på hvorfor warnings er bra: + +my $foo = "bar"; + +print "hei, jeg er $bar\n"; # Å nei! Feil variabelnavn! + +# ---------------------------------------------------------------------------------- + +#!/usr/bin/perl +use strict; +use warnings; + +## Kompliserte datastrukturer i Perl +# Perl versjon 4 (som ingen bruker lenger) hadde ingen støtte for å nøste +# arrays og lignende. Todimensjonale arrays var ikke mulig. Folk brukte all +# verdens grisete triks for å få til noe tilsvarende. Æsj! +# +# Perl versjon 5 har egentlig heller ikke støtte for flerdimensjonale arrays +# eller sånne ting, men det merker vi ikke stort til. Nå har vi nemlig pekere! +# +# Pekere i perl kan minne om pointere i C eller objektreferanser i Java. + +# Vi har arrayen @array +my @array = ('ottar', 'spiser', 'fisk'); + +# Vi lager en referanse +my $ref = [ @array ]; # Firkantparenteser til array, akkurat som ved henting + # av verdier + +# Vi får tilbake arrayen med @{}: +my @sammearray = @{$ref}; # denne sier: $ref er egentlig en array, altså! + +# Det samme gjelder for hasher, men med { %hash } og %{$ref} + +# ---------------------------------------------------------------------------------- + +#!/usr/bin/perl +use strict; +use warnings; + +# Vi kan også gjøre ting litt mer direkte, uten å lage @array først: +my $arrayref = [ 'geir', 'liker', 'sko' ]; + +# Og så kan vi hente ut verdier direkte på to måter. De er omtrent like bra, +# så det er bare å velge den du liker best. Personlig derefererer jeg gjerne +# referansen og bruker arrayen/hashen direkte etterpå, som på forrige foil. +print @{$arrayref}[0] . "\n"; # Bruker @{} som før +print $arrayref->[0] . "\n"; # Derefererer peker med ->, som i C. + +# Det samme virker for hasher: +my $hashref = { 'name' => 'ottar', 'liker' => 'sko' }; +my %hash = %{$hashref}; + +print %{$hashref}->{'name'} . "\n"; # Perl liker ikke }{, så vi må ha pil. +print $hashref->{'name'} . "\n"; +print $hash{'name'} . "\n"; + +# Legg merke til at den første bare er stygg, og de to siste ligner ganske +# mye på hverandre. Ukritisk bruk av referanser kan være en potensiell +# feilkilde, siden det er lett å blingse. Bare lag en vanlig hash eller +# array, så unngår du problemet. + +# ---------------------------------------------------------------------------------- + +#!/usr/bin/perl +use strict; +use warnings; + +## Så, til poenget: Hvordan lage todimensjonale ting? +# Todimensjonale arrays i Perl 5 er en array med arrayreferanser i. +# Hva merker vi til dette? Ingen ting. Perl fikser det for oss automatisk. + +my @array; +$array[0] = [ 'rob-geir' ]; # Vi legger en array-referanse fremst i arrayen. + +# Om vi printer ut $array[0] nå, får vi bare en referanse, omtrent som når vi +# printer et rart objekt i Java. Den ser slik ut: "ARRAY(0x814cd28)" +print $array[0] . "\n"; + +# Dette er altså egentlig en referanse. Men vent nå litt, da kan vi jo bruke +# pil-notasjonen fra forrige foil! +print $array[0]->[0] . "\n"; + +# Men denne pilen er jo kjedelig å skrive. Det fikser Perl! Det virker nemlig +# uten også! +print $array[0][0] . "\n"; + +# Og vips, vi merker ingen ting til dette rare referanse-greiene! +# Men, det er jo kjekt å vite om dem. Vi kan nemlig bruke dem andre steder +# også. + +# ---------------------------------------------------------------------------------- + +#!/usr/bin/perl +use strict; +use warnings; + +# Men av og til må vi likevel vite om dette rare med pekerene. Si vi lager en +# todimensjonal array med navn i: +my @array = ( + [ 'gunnar', 'ottar', 'bengt-åke' ], + [ 'kåre', 'ole-rånni', 'per' ], + [ 'kåbbai-laila', 'per-kristian foss' ] + ); + +# Og så vil vi gå gjennom alle verdiene: +foreach my $ref (@array) { + my @navn = @{$ref}; # Foreach gir oss referansen, så vi lager en array + foreach my $navn (@navn) { + print "$navn\n"; + } + print "\n"; # Printer et linjeskift etter hver gruppe +} + +# ---------------------------------------------------------------------------------- + +#!/usr/bin/perl +use strict; +use warnings; + +## Å lese inn ting med perl +# Noe av det man gjør oftest i perl er å lese inn data. Dette gjør man med +# "<>". Omtrent sånn: + +## Lese fra standard in +# En og en linje: +while (my $linje = ) { + print $linje; +} + +# Alt inn i en stor array (krever mer minne, unngå om du kan): +my @array = ; +foreach my $linje (@array) { + print $linje; +} + + + +# ---------------------------------------------------------------------------------- + +#!/usr/bin/perl +use strict; +use warnings; + +## Å lese fra en fil: +# Åpne filen, eller dø om det ikke virket. +open(my $FILDESKRIPTOR, "test.txt") or die("Kunne ikke åpne test.txt: $!"); + +# Les, og print ut med "> " foran: +while(my $linje = <$FILDESKRIPTOR>) { + print "> $linje"; +} + +# Lukk. +close($FILDESKRIPTOR); + +# Hett tips: open kan også brukes for å åpne ting for skriving. +# Kjør kommandoen "perldoc -f open" for å få masse info om alt du +# kan gjøre med open. + +# ---------------------------------------------------------------------------------- + +#!/usr/bin/perl +use strict; +use warnings; + +## Fjerne linjeskift fra det du leser +# Til forskjell fra f.eks. sed og grep, fjerner ikke perl linjeskift av seg +# selv. Om du ikke vil ha dem, må du fjerne dem. +# Til dette har vi kommandoen chomp. + +while (my $linje = ) { + chomp($linje); + print "$linje\n"; # ok, litt unyttig å bare sette på igjen linjeskiftet. +} + +# chomp kan også kjøres rett på en hel array. Da fikser den alle verdiene. + +my @array = ; +chomp(@array); + +# NB! Det er veldig vanlig å glemme chomp, og så fortsette i god tro. +# Det kan føre til ekle bugs der linjeskift dukker opp på rare steder. +# Jeg vet dette fordi jeg gjør det hele tiden selv ;-) + +# ---------------------------------------------------------------------------------- + +#!/usr/bin/perl +use strict; +use warnings; + +## Printing i Perl +# Hittil har vi bare sett på basic bruk av print. Men print kan brukes til +# mer. For eksempel en fildeskriptor: + +# Dette burde gi morosakene ut på standard error. +# PS: Det er IKKE komma etter fildeskriptoren når du printer! +print STDERR "Aaaah! Venstre motor brenner!\n"; + + +# Om du åpner noe med skrivetilgang med open kan og også bruke print der. +# Dette overskriver test.txt: +open(my $DESKR, ">test.txt") or die ("feil ved åpning av test.txt: $!"); + +print $DESKR "Hei, har du det bra?\n"; + +close($DESKR); + + +# Print på en array printer alle verdiene: +my @linjer = ("hei\n", "ost\n", "banan\n"); +print @linjer; + +# ---------------------------------------------------------------------------------- + +#!/usr/bin/perl +use strict; use warnings; + +## Printf: Fancy-schmancy printing +# Der sitter du med et digert desimaltall, og vil printe det ut med to +# desimaler. Printf to the rescue! +my $tall = 3.1415; +printf("pi: %.2f\n", $tall); + +# Eller du har en masse tallverdier med ulik lengde, og vil høyurejustere: +my @tall = (3, 1337, 25, 254); +foreach my $tall (@tall) { + printf("tall: %4d\n", $tall); # juksa litt: hardkodet inn maksbredde fire +} + +# Eller du vil printe ut et tall i hex, oktal og desimal, null-paddet til +# åtte sifre: +printf("hex: %08x %08o %08d\n", 255, 255, 255); + +# Du kan også lagre resultatet i en annen variabel med sprintf: +my $leet = sprintf("%03.2f", 13.37890); +print $leet, "\n"; +# Dette er litt for omfattende til at vi kan herje veldig mye med det. +# "perldoc -f sprintf" har mer info. +# +# Pass på! Det er lurere å bruke print om du ikke trenger ekstra formatering! +# Printf er tregere, og det er lettere å gjøre feil. + +# ---------------------------------------------------------------------------------- + +#!/usr/bin/perl +use strict; use warnings; + +## Splitting av tekststrenger +# Ofte har man en lang greie man vil splitte inn i en array. No problem! + +my $string = "www.pvv.ntnu.no"; +my @deler = split(".", $string); +# nå inneholder @deler dette: ('www', 'pvv', 'ntnu', 'no'); + +# Man kan også splitte på flere tegn: +my $verdier = "en, to, tre, fire, fem"; +my @verdier = split(", ", $verdier); + +# I stedet for å skrive en string som tegnet man kan splitte på, kan man også +# skrive et regulært uttrykk. Vi tar kanskje noe om regulære uttrykk senere, +# hvis vi rekker det. + +# Å splitte på " " (mellomrom) er litt spesielt. Da oppfører perl seg som awk, +# og gir deg alle ordene, uansett hvor mye whitespace det er mellom. +my $setn = "hei, jeg er ikke så flink med mellomrom"; +my @setn = split(" ", $setn); + +# Om du vil at det skal bli som i cut, med blanke felter mellom spaces som er +# inntil hverandre, bruk regulæruttrykket / /: +@setn = split(/ /, $setn); + +# ---------------------------------------------------------------------------------- + +#!/usr/bin/perl +use strict; +use warnings; + +## Join, det motsatte av split +# Hvis du har en array, og skal lage en tekststreng av verdiene, er join +# tingen for deg. Den setter sammen alle feltene, med en tekststreng mellom. + +my @koner = ("magda", "gunhild", "gunda"); +my $penliste = join(", ", @koner); +print "Koner: $penliste\n"; + +# Ut kommer dette: "Koner: magda, gunhild, gunda" + + +# Gammelt jegertriks for å lage en diger variabel av en array du har lest inn: +my @linjer = ; +my $digervariabel = join("", @linjer); # Vi joiner på tom streng + +# ---------------------------------------------------------------------------------- + +#!/usr/bin/perl +use strict; +use warnings; + +## Magiske variabler i Perl +# De magiske variablene i Perl er beryktet, og flittig kritisert av +# Python-brukere. Og ja, de er litt ekle. Ikke bruk dem mer enn du må, +# og husk å kommentere kode der du eventuelt bruker dem. + +# Disse tre dukker opp relativt ofte, og man forventes vel egentlig å kunne +# dem, så de trenger man ikke forklare i koden. Men husk å forklare eventuelle +# andre utskeielser! + + $_ # Default-variabelen. Om ikke noe er angitt, brukes som regel + # denne. Kan stort sett unngås, men av og til lurer den seg inn. + + @_ # Default-arrayen. Dukker stort sett bare opp som argumentene til + # subrutiner (mer om dem senere, om vi rekker det) + + $! # Feilmelding. Denne variabelen inneholder siste feilmelding. + # Den ble brukt etter open for et par foiler siden. + +# Det er hauger av andre magiske variabler også, men disse tre får holde +# inntil videre. Er du nysgjerrig på mer, kjør kommandoen "perldoc perlvar". + +# ---------------------------------------------------------------------------------- + +#!/usr/bin/perl +use strict; +use warnings; + +## Subrutiner (også kjent som funksjoner eller metoder) +# Subrutiner er veldig kjekke for å strukturere scripts. De har litt +# annerledes syntaks enn det vi er vant til, men ikke så veldig. + +# Vi lager en subrutine +sub hei () { + print "hei!\n"; +} + +# ...og vi kjører den. +hei(); + +# ...og en gang til: +hei(); + +# ---------------------------------------------------------------------------------- + +#!/usr/bin/perl +use strict; +use warnings; + +# Men vi vil kanskje gjerne gi subrutinen noen argumenter. For å fortelle +# subrutinen at den skal ta inn to variabler, gir vi den to $-tegn i +# parentesen: + +sub hei($$) { + my ($navn, $adjektiv) = @_; # Oi, hva er dette? + + print "Hei $navn, du er $adjektiv!\n"; +} + +# Og så hilser vi på noen +hei("ottar", "kul"); +hei("pål", "illeluktende"); + +# Nå dukket det opp litt nytt, spesielt den rare greia som heter @_. +# @_ er en magisk array der alle argumentene ligger. Jeg vet at det er to +# argumenter (det står jo "$$" i parentesen), så jeg kan bare hente dem ut +# direkte med to variabler inni en parentes. +# +# Denne parentesen er kanskje litt rar, men det er egentlig bare +# array-snarveien baklengs. Husk at vi kan si +my @array = ('per', 'pål'); + +# ---------------------------------------------------------------------------------- + +#!/usr/bin/perl +use strict; +use warnings; + +# Vi vil jo ofte returnere noe fra subrutinene våre. Det er lett. Bare bruk +# return $variabel: + +# Vi lager subrutinen fjortis, som setter masse utropstegn bakerst på +# tekst: +sub fjortis ($) { + my ( $tekst ) = @_; + return "$tekst!!!11"; +} + +# Hent ut fjortis-tegnsatt variabel +my $fjortis = fjortis("hei"); + +# Print den. +print "$fjortis\n"; + +# Print en dobbeltfjortis variabel +print fjortis(fjortis("hallo")) . "\n"; + +# ---------------------------------------------------------------------------------- + +#!/usr/bin/perl +use strict; +use warnings; + +# Å sende inn og ut arrays fra subrutiner er lett: + +# En skikkelig unødvendig og teit subrutine som sorterer mot alfabetet: +sub descsort (@) { + my @array = @_; + my @output = reverse sort @array; + return @output; +} + +my @array = ('hei', 'hå', 'aha'); +foreach my $ord (descsort(@array)) { + print "$ord\n"; +} + + +# ---------------------------------------------------------------------------------- + +#!/usr/bin/perl +use strict; +use warnings; + +# Å leke med en hash er også temmelig likt: + +sub print_hash (%) { + my %hash = @_; # Hold an! Hva er dette? Hash = Array? Hæ? + + foreach my $key (keys %hash) { + print "$key = " . $hash{$key} . "\n"; + } +} + +my %hash = ( 'fnavn' => 'herodes', 'enavn' => 'falsk' ); +print_hash(%hash); + +# Dette med "%hash = @_" virker jo litt sært. Men legg merke til at vi bruker +# de samme parentesene for å lage arrays og hasher. Faktisk er det bare piler +# stedet for kommaer på annenhver for at det skal bli lettere å se hva som er +# hva. +# +# Når du legger masse verdier inn i en hash gir du den altså bare en array +# med verdier, og så blir annenhver verdi nøkkel og innhold. +# (dette virker på samme måten i PHP). + +# ---------------------------------------------------------------------------------- + +#!/usr/bin/perl +use strict; +use warnings; + +# Men hva om vi for eksempel vil gi inn to variabler og en array? + +sub felleseie ($$@) { + my $han = shift; # Hva er denne shift? + my $hun = shift; + my @eiendeler = @_; + print "$han og $hun eier sammen dette:\n"; + foreach my $ting (@eiendeler) { + print "\t$ting\n"; + } +} + +my @eiendeler = ('sofa', 'tv', 'stereo'); +felleseie("per", "kari", @eiendeler); + +# shift(@array) tar første verdi i @array, fjerner den fra arrayen og +# returnerer den. ('en', 'to', 'tre') blir altså ('to', 'tre') etter shift. +# Slik kan vi fjerne de to første variablene, og sitte igjen med resten, som +# er til arrayen. +# +# Grunnen til at det må gjøres slik er at @_ bare inneholder alle verdiene, +# den har ikke system på hva som er hva. + +# ---------------------------------------------------------------------------------- + +#!/usr/bin/perl +use strict; +use warnings; + +# Men hva med to arrays? @_ vet jo ikke når den ene slutter og den andre +# begynner! Da må vi til med referanser igjen! + +sub tell_penisforlengere (\@\@) { + my @biler = @{ $_[0] }; + my @baater = @{ $_[1] }; + + print "Det er ".scalar @biler." bilær og ".scalar @baater."båtær\n"; +} + +my @biler = ('mercedes', 'porsche', 'austin martin'); +my @baater = ('sjekte', 'campingcruiser', 'yacht', 'pråm'); + +tell_penisforlengere(\@biler, \@baater); + +# Hva er disse backslashene? Bare en annen måte å lage referanser på. +# I C ville de tilsvart '&var'. Hvilken du bruker er hipp som happ. +# Disse gjør det samme: +my $biler; +$biler = [ @biler ]; +$biler = \@biler; + +# ---------------------------------------------------------------------------------- + +#!/usr/bin/perl +use strict; +use warnings; + +# Hittil har vi hatt funksjonen øverst i scriptet. Men da må vi jo scrolle +# forbi masse drit for å se hva selve programmet gjør (man *skal* gi +# subrutinene så logiske navn at man skjønner hva de gjør ut fra navnet. + +# Dette fikser vi med en prototype. De er omtrent som i C: +sub hei ($$); + +# Og så bruker vi den +hei('rob-geir', 'tøff'); +hei('gunnar', 'sexy'); + +# Og her kommer den. +sub hei ($$) { + my ($navn, $adjektiv) = @_; + print "Hei $navn, du er $adjektiv!\n"; +} + +# ---------------------------------------------------------------------------------- + +#!/usr/bin/perl +use strict; +use warnings; + +# Om du skriver rekursive funksjoner må du uansett prototype. +# La oss se på denne greia som teller nedover (på en skikkelig teit måte): + +sub tellned ($); + +sub tellned ($) { + my $tall = shift; + + print "$tall...\n"; + + if ($tall > 0) { + tellned($tall-1); + } +} + +tellned(10); + +# ---------------------------------------------------------------------------------- + +#!/usr/bin/perl +use strict; +use warnings; + +## Noen siste ord om subrutiner +# +# I en del gammel eller dårlig kode vil du kanskje oppdage at alle +# subrutinekall er med '&' foran, og at ingenting er prototypet. +# +# Dette var slik subrutiner virket før. De sjekket ikke antall argumenter +# eller noe som helst, og man sa fra om at de var subrutiner med &. +# Det er fremdeles mulig å gjøre det slik av hensyn til bakoverkompatibilitet, +# men IKKE GJØR DET! +# +# Om man gjør dette forsvinner nemlig alle former for feilsjekking rett i +# rett i dass, siden &subrutine() slår av sjekking av antall argumenter og +# slikt. Dette er et kjempetriks for å skjule bugs. Just don't do it, okay? + +# ---------------------------------------------------------------------------------- + diff --git a/foiler/01_velkommen.pl b/foiler/01_velkommen.pl new file mode 100644 index 0000000..6d1908d --- /dev/null +++ b/foiler/01_velkommen.pl @@ -0,0 +1,26 @@ +#!/usr/bin/perl +use strict; +use warnings; + +my $msg = <<'EOF'; + + + + __ __ _ _ + \ \ / /__| | | _____ _ __ ___ _ __ ___ ___ _ __ + \ \ / / _ \ | |/ / _ \| '_ ` _ \| '_ ` _ \ / _ \ '_ \ + \ V / __/ | < (_) | | | | | | | | | | | __/ | | | + \_/ \___|_|_|\_\___/|_| |_| |_|_| |_| |_|\___|_| |_| + + _ _ _ ____ _ _ _ + | |_(_) | | _ \ ___ _ __| | | | ___ _ _ __ ___| | + | __| | | | |_) / _ \ '__| |_____| |/ / | | | '__/ __| | + | |_| | | | __/ __/ | | |_____| <| |_| | | \__ \_| + \__|_|_| |_| \___|_| |_| |_|\_\\__,_|_| |___(_) + + + + +EOF + +print $msg; diff --git a/foiler/02_whatis.pl b/foiler/02_whatis.pl new file mode 100644 index 0000000..3aace28 --- /dev/null +++ b/foiler/02_whatis.pl @@ -0,0 +1,27 @@ +#!/usr/bin/perl +use strict; use warnings; +print <<'EOF'; + HVA ER PERL? + + * Betyr: Practical Extraction and Reporting Language + * Alternativt: Pathologically Eclectic Rubbish Lister + * Et cross-platform scriptingspråk skrevet av Larry Wall (han er kul) + * Virker i UNIX, Windows, på Mac, i VMS, etc etc + * Kildekoden til perl er åpen (GPL) + * Et tolket språk (kompileres ikke, "kompileres" hver gang det kjøres). + + HVORFOR PERL? + + * Veldig kraftig, du kan gjøre mye med lite kode + * Kjapt å skrive + * Svært mange ferdige biblioteker ( http://search.cpan.org ) + * Det er kult + + HVORFOR IKKE PERL? + + * Ting kan fort bli litt grisete om man er syk i hodet eller ikke tenker + * Veldig mye ulik syntaks (flere måter å gjøre det samme på) + * Det blir en del krangling med Python-folk + * Python-folkene kommer sikkert på mer... + +EOF diff --git a/foiler/03_what.pl b/foiler/03_what.pl new file mode 100644 index 0000000..ca1e11c --- /dev/null +++ b/foiler/03_what.pl @@ -0,0 +1,24 @@ +#!/usr/bin/perl +use strict; +use warnings; + +print <<'EOF' + + HVA VI SKAL HA I DETTE KURSET + + Det finnes to typer perl: + * Oneliner-perl (kjappe triks man bare skal bruke en gang (eller ha på + t-skjorta)) + * Produksjonskode-perl (relativt pen, leselig kode) + + Ikke alle ser denne forskjellen. De som ikke ser denne forskjellen er + grunnen til at perl har rykte på seg for å være uleselig og grisete, + såkalt "write once". + + Jeg er ikke så glad i dem som ikke ser forskjellen. Spesielt ikke når jeg + må fikse på koden deres. + + I dette kurset skal vi lære om produksjonskode-perl. Oneliner-perl lærer + dere tidsnok selv ;-) + +EOF diff --git a/foiler/04_syntaks.pl b/foiler/04_syntaks.pl new file mode 100644 index 0000000..65eeaa3 --- /dev/null +++ b/foiler/04_syntaks.pl @@ -0,0 +1,22 @@ +#!/usr/bin/perl +use strict; +use warnings; + +print <<"EOF" +# Enkel syntaks: + + * Minner veldig om C, PHP og Java. + * { og } deler inn blokker, + * ( og ) rundt argumenter, etc (MEN: valgfrie). + * Alle statements avsluttes med semikolon + +EOF + +# Parenteser rundt er valgfrie. Begge disse virker: + +print "hei\n"; +print("hei\n"); + +# Parenteser brukes for å angi skop. Dette er spesielt nyttig når man har +# flere kommandoer nøstet inni hverandre. Lurer du på om det funker uten +# parentes? Da beholder du parentesene. Lesbar kode er viktig. diff --git a/foiler/05_vars.pl b/foiler/05_vars.pl new file mode 100644 index 0000000..bcd7f8c --- /dev/null +++ b/foiler/05_vars.pl @@ -0,0 +1,23 @@ +#!/usr/bin/perl +use strict; +use warnings; + +## Variabler og slikt +# Variabler, arrays og hasher deklareres med ordet "my". Det holder med ett +# ord for å deklarere, siden Perl ikke bryr seg så mye om innholdet i +# variabler. Om det er et heltall, et desimaltall eller tekst tas litt på +# gefühlen. + +# En vanlig variabel (såkalt "skalar): +my $tall = 15; +my $tekst = 'hei'; + +# En array: +my @array; +@array = (15, 'hei'); # Definer alle verdier +$array[2] = 'gunnar'; # Sett tredje element + +# En hash: +my %hash = ('ottar' => 15, 'pelle' => 17); # Definer alle verdier +$hash{'bjarne'} = 13; # Sett verdi for bjarne + diff --git a/foiler/06_quoting.pl b/foiler/06_quoting.pl new file mode 100644 index 0000000..c27f7e8 --- /dev/null +++ b/foiler/06_quoting.pl @@ -0,0 +1,13 @@ +#!/usr/bin/perl +use strict; use warnings; + +## Quoting +# Ulike hermetegn oppfører seg forskjellig, på samme måte som i PHP +# (PHP rappet det av Perl). + +my $test = 'ottar'; + +print "hei $test\n"; # printer dette: hei ottar +print 'hei $test\n'; # printer dette: hei $test\n + + diff --git a/foiler/07_joining.pl b/foiler/07_joining.pl new file mode 100644 index 0000000..db8261b --- /dev/null +++ b/foiler/07_joining.pl @@ -0,0 +1,25 @@ +#!/usr/bin/perl +use strict; use warnings; + +## Hvordan slå sammen tekst (også likt som i PHP, av samme grunn) + +# Flere tekststrenger slås sammen med punktum (Java bruker pluss). +my $fornavn = "Kjell Magne"; +my $etternavn = "Bondevik"; +my $fulltnavn = $fornavn . ' ' . $etternavn; + +# Vi kunne selvsagt også brukt dette, som også er mye vanligere å bruke: +$fulltnavn = "$fornavn $etternavn"; + +# Men av og til er "" upraktisk, som f.eks. om du skal printe ut HTML, +# eller har verdiene i noe annet enn variabler. +my %verdier = ('uid' => 1015, 'bnavn' => 'kjellmangle'); + +# Dette: +print '' . $verdier{'bnavn'} . "\n"; + +# Er penere enn dette: +print "$verdier{'bnavn'}\n"; + +# Men begge virker, selv om highlightingen min ikke tror det. +# At noe virker men blir highlightet feil er ofte et hint. Ta hintet. diff --git a/foiler/08_multiline.pl b/foiler/08_multiline.pl new file mode 100644 index 0000000..ae9d9fd --- /dev/null +++ b/foiler/08_multiline.pl @@ -0,0 +1,26 @@ +#!/usr/bin/perl +use strict; use warnings; + +## Ting på flere linjer: bruk enten punktum eller <<"EOF";. + +# Punktum (Som regel best): +my $test = "ottar"; +my $langvariabel = "Denne teksten på flere linjer er dedikert til\n" + . "min gode venn og følgesvenn $test\n"; + +# <<"EOF"; (Bruk bare når det er _store_ greier, og punktum blir veldig +# tungvint. Ikke spesielt viktig å kunne, men greit å vite om): + +$langvariabel = <<"EOF"; +Denne teksten på flere linjer er dedikert til +min gode venn og følgesvenn $test +EOF + +$langvariabel = <<'EOG'; +Denne teksten på flere linjer er dedikert til +min gode venn og følgesvenn $test +EOG + +# Det inni hermetegnene er et merke. Alt helt ned til merket blir med i +# variabelen. Hva som skjer med teksten inni avhenger av hermetegnene rundt +# merket. Husk å bruke samme merke bare en gang! Pass på semikolonet! diff --git a/foiler/09_logikk.pl b/foiler/09_logikk.pl new file mode 100644 index 0000000..f90eefa --- /dev/null +++ b/foiler/09_logikk.pl @@ -0,0 +1,25 @@ +#!/usr/bin/perl +use strict; +use warnings; + +## Logikk med tallverdier +# Logikk i perl ligner veldig på andre språk som C, PHP og Java. +# 0, tom streng og udefinert er false, det meste annet er true (som i PHP). +# IKKE utnytt dette for mye. Det blir vanskelig å lese. Test bare rett på +# variabelen om du bruker variabelen som en boolean. + +# Booleans (1 = sant, 0 = usant): +my $boolean = 1; +if ($boolean) { + print "\$boolean er sann!\n"; # Dette skjer. +} else { + print "\$boolean er usann!\n"; # Dette skjer ikke. +} + +my $tall = 15; +if ($tall > 10) { + print "\$tall er over 10!\n"; +} +elsif ($tall < 5) { # elsif står for "else if" + print "\$tall under over 5!\n"; +} diff --git a/foiler/10_tekstlogikk.pl b/foiler/10_tekstlogikk.pl new file mode 100644 index 0000000..7d465f7 --- /dev/null +++ b/foiler/10_tekstlogikk.pl @@ -0,0 +1,25 @@ +#!/usr/bin/perl +use strict; +use warnings; + +## Logikk med tekstverdier + +# Dere som kan PHP er vant til å bruke "==" på tekststrenger. Det virker +# IKKE i Perl! I Perl er det egne greier for å sammenligne ord. + +# De viktigste: +# eq: er lik +# ne: er ikke lik + +my $tekst = "banan"; +if ($tekst eq "banan") { + print "\$tekst er lik banan\n"; +} + +if ($tekst ne "eple") { + print "\$tekst er ikke lik eple\n"; +} + +if (length($tekst) > 3) { + print "\$tekst er mer enn tre tegn lang\n"; +} diff --git a/foiler/11_while.pl b/foiler/11_while.pl new file mode 100644 index 0000000..56b2694 --- /dev/null +++ b/foiler/11_while.pl @@ -0,0 +1,19 @@ +#!/usr/bin/perl +use strict; +use warnings; + +## While-loop +# En while-loop i perl virker akkurat som i andre språk. Yay! + +my $counter = 0; +while ($counter < 10) { + print "tallet er $counter\n"; + $counter++; # Øker $counter med 1 +} + +## For-loop +# Virker også som i andre språk! Hurra! + +for (my $tall = 0; $tall < 10; $tall++) { + print "tallet er $tall\n"; +} diff --git a/foiler/12_foreach.pl b/foiler/12_foreach.pl new file mode 100644 index 0000000..4c3741b --- /dev/null +++ b/foiler/12_foreach.pl @@ -0,0 +1,25 @@ +#!/usr/bin/perl +use strict; +use warnings; + +## Foreach-loopen +# Denne er litt spesiell. Man har noe lignende i PHP, men syntaksen er ulik. +# Foreach går gjennom hvert element i en liste. + +my @array = ('gunnar', 'ottar', 'per ulf'); + +# Legg merke til at løpevariabelen $verdi angis utenfor parentesen! +foreach my $verdi (@array) { + print "$verdi\n"; +} + +# Man kan også bruke foreach til å løpe over alle nøklene i en hash: +my %hash = ( 'uid' => 3425, 'bnavn' => 'ottar', 'rnavn' => 'Ottar Evje' ); + +# Kommandoen "keys" gir ut en array med alle nøklene i hashen, så dette er +# egentlig akkurat det samme. +foreach my $key (keys %hash) { + print $key . " = " . $hash{$key} . "\n"; +} + +# Foreach er dritnyttig! diff --git a/foiler/13_break.pl b/foiler/13_break.pl new file mode 100644 index 0000000..c6448c0 --- /dev/null +++ b/foiler/13_break.pl @@ -0,0 +1,26 @@ +#!/usr/bin/perl +use strict; use warnings; + +## Å bryte ut av looper i Perl +# Når man skal bryte ut av looper er Perl litt rart. Alt heter noe annet enn +# det gjør i andre språk! Dette er jo skikkelig teit, men man venner seg +# til det ganske fort. Jeg tipper grunnen er at perl ble laget for å parse +# tekst, og da virket disse navnene mer logiske. +# +# En liten tabell: +# +------+-------------+---------------------------------------------+ +# | Perl | Andre språk | Betydning | +# +------+-------------+---------------------------------------------+ +# | next | continue | Hopp over det som er nedenfor og kjør neste | +# | | | runde i loopen | +# +------+-------------+---------------------------------------------+ +# | last | break | Avbryt kjøringen av hele loopen | +# +------+-------------+---------------------------------------------+ + +# Eksempel på next: +foreach my $tall (1, 2, 3) { + if ($tall == 2) { + next; + } + print "tallet er $tall!\n"; +} diff --git a/foiler/14_break2.pl b/foiler/14_break2.pl new file mode 100644 index 0000000..236a052 --- /dev/null +++ b/foiler/14_break2.pl @@ -0,0 +1,15 @@ +#!/usr/bin/perl +use strict; +use warnings; + +# Eksempel på "last": Rakettutskyting med forviklinger + +for (my $tall = 10; $tall > 0; $tall--) { + print "$tall...\n"; + + # Oh no! Når vi kommer til 5 eksploderer raketten! + if ($tall == 5) { + print "Boom!\n"; + last; # Her avbryter loopen + } +} diff --git a/foiler/15_shebang.pl b/foiler/15_shebang.pl new file mode 100644 index 0000000..dc47e6b --- /dev/null +++ b/foiler/15_shebang.pl @@ -0,0 +1,23 @@ +#!/usr/bin/perl +use strict; +use warnings; + +### Hva er egentlig det greiene på toppen av alle foilene? + +## Shebangen +# +# #!/usr/bin/perl er en såkalt shebang. Den forteller hva slags språk +# scriptet er skrevet i, og hva slags program som skal brukes til å tolke +# det. +# +# Om ikke shebangen var det ville vi måttet vite hva scriptet var skrevet i, +# og selv kjørt programmet med filen som argument. +# +# Uten shebang: +# perl program.pl +# +# Med shebang: +# ./program.pl +# +# For at programmet skal kunne kjøres direkte må det også være kjørbart. +# "chmod +x program.pl" fikser den biffen. diff --git a/foiler/16_strict.pl b/foiler/16_strict.pl new file mode 100644 index 0000000..a21b7fb --- /dev/null +++ b/foiler/16_strict.pl @@ -0,0 +1,15 @@ +#!/usr/bin/perl +use strict; +use warnings; + +## use strict: +# +# Uten use strict trenger man ikke å deklarere variabler. Variabler blir +# bare opprettet når de trengs av seg selv. Kjekt? Nei. +# +# Alle variabler som er implisitt deklarert blir nemlig globale. +# Globale variabler er ikke bra. +# +# Dessuten blir det plutselig mulig å bruke samme variabel til flere ting +# uten å merke det. Det er heller ikke bra. + diff --git a/foiler/17_nonstrict_eks.pl b/foiler/17_nonstrict_eks.pl new file mode 100644 index 0000000..548bbed --- /dev/null +++ b/foiler/17_nonstrict_eks.pl @@ -0,0 +1,27 @@ +#!/usr/bin/perl +use warnings; + +# Eksempel uten strict. Merk at det ikke er noen "use strict" øverst. +# Vi tenker oss en webtjeneste der brukeren kan logge inn. Brukeren er +# innlogget som "rob-geir". +$user = "rob-geir"; +print "Du er logget inn som: $user\n"; + +# maaaange linjer kode med magi og ting. Vi har helt glemt $user. + +# Hoi, systemet har en funksjon som lister opp alle som er innlogget. +# Akkurat nå er det disse tre: +@users = ('ottar', 'rob-geir', 'dan-børge' ); + +# Vi lister opp alle brukerene. Men hold an! Her brukte vi jo $user på nytt! +print "Brukere innlogget: "; +for ($i = 0; $i < scalar @users; $i++){ + $user = $users[$i]; + print "$user "; +} +print "\n"; + +# Maaange linjer med kode. Nå har vi glemt brukerlisten. + +# Nederst på siden vil vi vise hvem som er logget inn en gang til. +print "Du er logget inn som: $user\n"; diff --git a/foiler/18_warnings.pl b/foiler/18_warnings.pl new file mode 100644 index 0000000..2dcb930 --- /dev/null +++ b/foiler/18_warnings.pl @@ -0,0 +1,15 @@ +#!/usr/bin/perl +use warnings; + +# Warnings betyr akkurat det som står: Advarsler. Det gjør at perl advarer +# når noe ser rart ut. Du vil ha det. Om koden din gir advarsler er det fordi +# du har gjort noe du ikke burde gjøre. +# +# Jeg fjernet use strict denne gangen, så det skulle bli lettere å gjøre +# noe dumt warnings kunne oppdage. + +# Eksempel på hvorfor warnings er bra: + +my $foo = "bar"; + +print "hei, jeg er $bar\n"; # Å nei! Feil variabelnavn! diff --git a/foiler/19_pekere.pl b/foiler/19_pekere.pl new file mode 100644 index 0000000..29a5cff --- /dev/null +++ b/foiler/19_pekere.pl @@ -0,0 +1,25 @@ +#!/usr/bin/perl +use strict; +use warnings; + +## Kompliserte datastrukturer i Perl +# Perl versjon 4 (som ingen bruker lenger) hadde ingen støtte for å nøste +# arrays og lignende. Todimensjonale arrays var ikke mulig. Folk brukte all +# verdens grisete triks for å få til noe tilsvarende. Æsj! +# +# Perl versjon 5 har egentlig heller ikke støtte for flerdimensjonale arrays +# eller sånne ting, men det merker vi ikke stort til. Nå har vi nemlig pekere! +# +# Pekere i perl kan minne om pointere i C eller objektreferanser i Java. + +# Vi har arrayen @array +my @array = ('ottar', 'spiser', 'fisk'); + +# Vi lager en referanse +my $ref = [ @array ]; # Firkantparenteser til array, akkurat som ved henting + # av verdier + +# Vi får tilbake arrayen med @{}: +my @sammearray = @{$ref}; # denne sier: $ref er egentlig en array, altså! + +# Det samme gjelder for hasher, men med { %hash } og %{$ref} diff --git a/foiler/20_pekere2.pl b/foiler/20_pekere2.pl new file mode 100644 index 0000000..e82cd21 --- /dev/null +++ b/foiler/20_pekere2.pl @@ -0,0 +1,25 @@ +#!/usr/bin/perl +use strict; +use warnings; + +# Vi kan også gjøre ting litt mer direkte, uten å lage @array først: +my $arrayref = [ 'geir', 'liker', 'sko' ]; + +# Og så kan vi hente ut verdier direkte på to måter. De er omtrent like bra, +# så det er bare å velge den du liker best. Personlig derefererer jeg gjerne +# referansen og bruker arrayen/hashen direkte etterpå, som på forrige foil. +print @{$arrayref}[0] . "\n"; # Bruker @{} som før +print $arrayref->[0] . "\n"; # Derefererer peker med ->, som i C. + +# Det samme virker for hasher: +my $hashref = { 'name' => 'ottar', 'liker' => 'sko' }; +my %hash = %{$hashref}; + +print %{$hashref}->{'name'} . "\n"; # Perl liker ikke }{, så vi må ha pil. +print $hashref->{'name'} . "\n"; +print $hash{'name'} . "\n"; + +# Legg merke til at den første bare er stygg, og de to siste ligner ganske +# mye på hverandre. Ukritisk bruk av referanser kan være en potensiell +# feilkilde, siden det er lett å blingse. Bare lag en vanlig hash eller +# array, så unngår du problemet. diff --git a/foiler/21_todimensjonalt.pl b/foiler/21_todimensjonalt.pl new file mode 100644 index 0000000..95c2456 --- /dev/null +++ b/foiler/21_todimensjonalt.pl @@ -0,0 +1,26 @@ +#!/usr/bin/perl +use strict; +use warnings; + +## Så, til poenget: Hvordan lage todimensjonale ting? +# Todimensjonale arrays i Perl 5 er en array med arrayreferanser i. +# Hva merker vi til dette? Ingen ting. Perl fikser det for oss automatisk. + +my @array; +$array[0] = [ 'rob-geir' ]; # Vi legger en array-referanse fremst i arrayen. + +# Om vi printer ut $array[0] nå, får vi bare en referanse, omtrent som når vi +# printer et rart objekt i Java. Den ser slik ut: "ARRAY(0x814cd28)" +print $array[0] . "\n"; + +# Dette er altså egentlig en referanse. Men vent nå litt, da kan vi jo bruke +# pil-notasjonen fra forrige foil! +print $array[0]->[0] . "\n"; + +# Men denne pilen er jo kjedelig å skrive. Det fikser Perl! Det virker nemlig +# uten også! +print $array[0][0] . "\n"; + +# Og vips, vi merker ingen ting til dette rare referanse-greiene! +# Men, det er jo kjekt å vite om dem. Vi kan nemlig bruke dem andre steder +# også. diff --git a/foiler/22_todimensjonalt2.pl b/foiler/22_todimensjonalt2.pl new file mode 100644 index 0000000..6bab66f --- /dev/null +++ b/foiler/22_todimensjonalt2.pl @@ -0,0 +1,20 @@ +#!/usr/bin/perl +use strict; +use warnings; + +# Men av og til må vi likevel vite om dette rare med pekerene. Si vi lager en +# todimensjonal array med navn i: +my @array = ( + [ 'gunnar', 'ottar', 'bengt-åke' ], + [ 'kåre', 'ole-rånni', 'per' ], + [ 'kåbbai-laila', 'per-kristian foss' ] + ); + +# Og så vil vi gå gjennom alle verdiene: +foreach my $ref (@array) { + my @navn = @{$ref}; # Foreach gir oss referansen, så vi lager en array + foreach my $navn (@navn) { + print "$navn\n"; + } + print "\n"; # Printer et linjeskift etter hver gruppe +} diff --git a/foiler/23_lesing.pl b/foiler/23_lesing.pl new file mode 100644 index 0000000..00cb5f9 --- /dev/null +++ b/foiler/23_lesing.pl @@ -0,0 +1,21 @@ +#!/usr/bin/perl +use strict; +use warnings; + +## Å lese inn ting med perl +# Noe av det man gjør oftest i perl er å lese inn data. Dette gjør man med +# "<>". Omtrent sånn: + +## Lese fra standard in +# En og en linje: +while (my $linje = ) { + print $linje; +} + +# Alt inn i en stor array (krever mer minne, unngå om du kan): +my @array = ; +foreach my $linje (@array) { + print $linje; +} + + diff --git a/foiler/24_lesing2.pl b/foiler/24_lesing2.pl new file mode 100644 index 0000000..7aeb2ac --- /dev/null +++ b/foiler/24_lesing2.pl @@ -0,0 +1,19 @@ +#!/usr/bin/perl +use strict; +use warnings; + +## Å lese fra en fil: +# Åpne filen, eller dø om det ikke virket. +open(my $FILDESKRIPTOR, "test.txt") or die("Kunne ikke åpne test.txt: $!"); + +# Les, og print ut med "> " foran: +while(my $linje = <$FILDESKRIPTOR>) { + print "> $linje"; +} + +# Lukk. +close($FILDESKRIPTOR); + +# Hett tips: open kan også brukes for å åpne ting for skriving. +# Kjør kommandoen "perldoc -f open" for å få masse info om alt du +# kan gjøre med open. diff --git a/foiler/25_chomp.pl b/foiler/25_chomp.pl new file mode 100644 index 0000000..0c927c5 --- /dev/null +++ b/foiler/25_chomp.pl @@ -0,0 +1,22 @@ +#!/usr/bin/perl +use strict; +use warnings; + +## Fjerne linjeskift fra det du leser +# Til forskjell fra f.eks. sed og grep, fjerner ikke perl linjeskift av seg +# selv. Om du ikke vil ha dem, må du fjerne dem. +# Til dette har vi kommandoen chomp. + +while (my $linje = ) { + chomp($linje); + print "$linje\n"; # ok, litt unyttig å bare sette på igjen linjeskiftet. +} + +# chomp kan også kjøres rett på en hel array. Da fikser den alle verdiene. + +my @array = ; +chomp(@array); + +# NB! Det er veldig vanlig å glemme chomp, og så fortsette i god tro. +# Det kan føre til ekle bugs der linjeskift dukker opp på rare steder. +# Jeg vet dette fordi jeg gjør det hele tiden selv ;-) diff --git a/foiler/26_print.pl b/foiler/26_print.pl new file mode 100644 index 0000000..7b74535 --- /dev/null +++ b/foiler/26_print.pl @@ -0,0 +1,25 @@ +#!/usr/bin/perl +use strict; +use warnings; + +## Printing i Perl +# Hittil har vi bare sett på basic bruk av print. Men print kan brukes til +# mer. For eksempel en fildeskriptor: + +# Dette burde gi morosakene ut på standard error. +# PS: Det er IKKE komma etter fildeskriptoren når du printer! +print STDERR "Aaaah! Venstre motor brenner!\n"; + + +# Om du åpner noe med skrivetilgang med open kan og også bruke print der. +# Dette overskriver test.txt: +open(my $DESKR, ">test.txt") or die ("feil ved åpning av test.txt: $!"); + +print $DESKR "Hei, har du det bra?\n"; + +close($DESKR); + + +# Print på en array printer alle verdiene: +my @linjer = ("hei\n", "ost\n", "banan\n"); +print @linjer; diff --git a/foiler/27_printf.pl b/foiler/27_printf.pl new file mode 100644 index 0000000..461e2cd --- /dev/null +++ b/foiler/27_printf.pl @@ -0,0 +1,27 @@ +#!/usr/bin/perl +use strict; use warnings; + +## Printf: Fancy-schmancy printing +# Der sitter du med et digert desimaltall, og vil printe det ut med to +# desimaler. Printf to the rescue! +my $tall = 3.1415; +printf("pi: %.2f\n", $tall); + +# Eller du har en masse tallverdier med ulik lengde, og vil høyurejustere: +my @tall = (3, 1337, 25, 254); +foreach my $tall (@tall) { + printf("tall: %4d\n", $tall); # juksa litt: hardkodet inn maksbredde fire +} + +# Eller du vil printe ut et tall i hex, oktal og desimal, null-paddet til +# åtte sifre: +printf("hex: %08x %08o %08d\n", 255, 255, 255); + +# Du kan også lagre resultatet i en annen variabel med sprintf: +my $leet = sprintf("%03.2f", 13.37890); +print $leet, "\n"; +# Dette er litt for omfattende til at vi kan herje veldig mye med det. +# "perldoc -f sprintf" har mer info. +# +# Pass på! Det er lurere å bruke print om du ikke trenger ekstra formatering! +# Printf er tregere, og det er lettere å gjøre feil. diff --git a/foiler/28_split.pl b/foiler/28_split.pl new file mode 100644 index 0000000..fd7a7bb --- /dev/null +++ b/foiler/28_split.pl @@ -0,0 +1,26 @@ +#!/usr/bin/perl +use strict; use warnings; + +## Splitting av tekststrenger +# Ofte har man en lang greie man vil splitte inn i en array. No problem! + +my $string = "www.pvv.ntnu.no"; +my @deler = split(".", $string); +# nå inneholder @deler dette: ('www', 'pvv', 'ntnu', 'no'); + +# Man kan også splitte på flere tegn: +my $verdier = "en, to, tre, fire, fem"; +my @verdier = split(", ", $verdier); + +# I stedet for å skrive en string som tegnet man kan splitte på, kan man også +# skrive et regulært uttrykk. Vi tar kanskje noe om regulære uttrykk senere, +# hvis vi rekker det. + +# Å splitte på " " (mellomrom) er litt spesielt. Da oppfører perl seg som awk, +# og gir deg alle ordene, uansett hvor mye whitespace det er mellom. +my $setn = "hei, jeg er ikke så flink med mellomrom"; +my @setn = split(" ", $setn); + +# Om du vil at det skal bli som i cut, med blanke felter mellom spaces som er +# inntil hverandre, bruk regulæruttrykket / /: +@setn = split(/ /, $setn); diff --git a/foiler/29_join.pl b/foiler/29_join.pl new file mode 100644 index 0000000..79a6516 --- /dev/null +++ b/foiler/29_join.pl @@ -0,0 +1,18 @@ +#!/usr/bin/perl +use strict; +use warnings; + +## Join, det motsatte av split +# Hvis du har en array, og skal lage en tekststreng av verdiene, er join +# tingen for deg. Den setter sammen alle feltene, med en tekststreng mellom. + +my @koner = ("magda", "gunhild", "gunda"); +my $penliste = join(", ", @koner); +print "Koner: $penliste\n"; + +# Ut kommer dette: "Koner: magda, gunhild, gunda" + + +# Gammelt jegertriks for å lage en diger variabel av en array du har lest inn: +my @linjer = ; +my $digervariabel = join("", @linjer); # Vi joiner på tom streng diff --git a/foiler/30_magiske_variable.pl b/foiler/30_magiske_variable.pl new file mode 100644 index 0000000..1597173 --- /dev/null +++ b/foiler/30_magiske_variable.pl @@ -0,0 +1,24 @@ +#!/usr/bin/perl +use strict; +use warnings; + +## Magiske variabler i Perl +# De magiske variablene i Perl er beryktet, og flittig kritisert av +# Python-brukere. Og ja, de er litt ekle. Ikke bruk dem mer enn du må, +# og husk å kommentere kode der du eventuelt bruker dem. + +# Disse tre dukker opp relativt ofte, og man forventes vel egentlig å kunne +# dem, så de trenger man ikke forklare i koden. Men husk å forklare eventuelle +# andre utskeielser! + + $_ # Default-variabelen. Om ikke noe er angitt, brukes som regel + # denne. Kan stort sett unngås, men av og til lurer den seg inn. + + @_ # Default-arrayen. Dukker stort sett bare opp som argumentene til + # subrutiner (mer om dem senere, om vi rekker det) + + $! # Feilmelding. Denne variabelen inneholder siste feilmelding. + # Den ble brukt etter open for et par foiler siden. + +# Det er hauger av andre magiske variabler også, men disse tre får holde +# inntil videre. Er du nysgjerrig på mer, kjør kommandoen "perldoc perlvar". diff --git a/foiler/31_subrutiner.pl b/foiler/31_subrutiner.pl new file mode 100644 index 0000000..ce90685 --- /dev/null +++ b/foiler/31_subrutiner.pl @@ -0,0 +1,18 @@ +#!/usr/bin/perl +use strict; +use warnings; + +## Subrutiner (også kjent som funksjoner eller metoder) +# Subrutiner er veldig kjekke for å strukturere scripts. De har litt +# annerledes syntaks enn det vi er vant til, men ikke så veldig. + +# Vi lager en subrutine +sub hei () { + print "hei!\n"; +} + +# ...og vi kjører den. +hei(); + +# ...og en gang til: +hei(); diff --git a/foiler/32_subrutiner2.pl b/foiler/32_subrutiner2.pl new file mode 100644 index 0000000..e2528e0 --- /dev/null +++ b/foiler/32_subrutiner2.pl @@ -0,0 +1,26 @@ +#!/usr/bin/perl +use strict; +use warnings; + +# Men vi vil kanskje gjerne gi subrutinen noen argumenter. For å fortelle +# subrutinen at den skal ta inn to variabler, gir vi den to $-tegn i +# parentesen: + +sub hei($$) { + my ($navn, $adjektiv) = @_; # Oi, hva er dette? + + print "Hei $navn, du er $adjektiv!\n"; +} + +# Og så hilser vi på noen +hei("ottar", "kul"); +hei("pål", "illeluktende"); + +# Nå dukket det opp litt nytt, spesielt den rare greia som heter @_. +# @_ er en magisk array der alle argumentene ligger. Jeg vet at det er to +# argumenter (det står jo "$$" i parentesen), så jeg kan bare hente dem ut +# direkte med to variabler inni en parentes. +# +# Denne parentesen er kanskje litt rar, men det er egentlig bare +# array-snarveien baklengs. Husk at vi kan si +my @array = ('per', 'pål'); diff --git a/foiler/33_subrutiner_return.pl b/foiler/33_subrutiner_return.pl new file mode 100644 index 0000000..db7ef36 --- /dev/null +++ b/foiler/33_subrutiner_return.pl @@ -0,0 +1,22 @@ +#!/usr/bin/perl +use strict; +use warnings; + +# Vi vil jo ofte returnere noe fra subrutinene våre. Det er lett. Bare bruk +# return $variabel: + +# Vi lager subrutinen fjortis, som setter masse utropstegn bakerst på +# tekst: +sub fjortis ($) { + my ( $tekst ) = @_; + return "$tekst!!!11"; +} + +# Hent ut fjortis-tegnsatt variabel +my $fjortis = fjortis("hei"); + +# Print den. +print "$fjortis\n"; + +# Print en dobbeltfjortis variabel +print fjortis(fjortis("hallo")) . "\n"; diff --git a/foiler/34_subrutiner_array.pl b/foiler/34_subrutiner_array.pl new file mode 100644 index 0000000..cc24160 --- /dev/null +++ b/foiler/34_subrutiner_array.pl @@ -0,0 +1,18 @@ +#!/usr/bin/perl +use strict; +use warnings; + +# Å sende inn og ut arrays fra subrutiner er lett: + +# En skikkelig unødvendig og teit subrutine som sorterer mot alfabetet: +sub descsort (@) { + my @array = @_; + my @output = reverse sort @array; + return @output; +} + +my @array = ('hei', 'hå', 'aha'); +foreach my $ord (descsort(@array)) { + print "$ord\n"; +} + diff --git a/foiler/35_subrutiner_hash.pl b/foiler/35_subrutiner_hash.pl new file mode 100644 index 0000000..5612b60 --- /dev/null +++ b/foiler/35_subrutiner_hash.pl @@ -0,0 +1,25 @@ +#!/usr/bin/perl +use strict; +use warnings; + +# Å leke med en hash er også temmelig likt: + +sub print_hash (%) { + my %hash = @_; # Hold an! Hva er dette? Hash = Array? Hæ? + + foreach my $key (keys %hash) { + print "$key = " . $hash{$key} . "\n"; + } +} + +my %hash = ( 'fnavn' => 'herodes', 'enavn' => 'falsk' ); +print_hash(%hash); + +# Dette med "%hash = @_" virker jo litt sært. Men legg merke til at vi bruker +# de samme parentesene for å lage arrays og hasher. Faktisk er det bare piler +# stedet for kommaer på annenhver for at det skal bli lettere å se hva som er +# hva. +# +# Når du legger masse verdier inn i en hash gir du den altså bare en array +# med verdier, og så blir annenhver verdi nøkkel og innhold. +# (dette virker på samme måten i PHP). diff --git a/foiler/36_subrutiner_multivar.pl b/foiler/36_subrutiner_multivar.pl new file mode 100644 index 0000000..347f53b --- /dev/null +++ b/foiler/36_subrutiner_multivar.pl @@ -0,0 +1,26 @@ +#!/usr/bin/perl +use strict; +use warnings; + +# Men hva om vi for eksempel vil gi inn to variabler og en array? + +sub felleseie ($$@) { + my $han = shift; # Hva er denne shift? + my $hun = shift; + my @eiendeler = @_; + print "$han og $hun eier sammen dette:\n"; + foreach my $ting (@eiendeler) { + print "\t$ting\n"; + } +} + +my @eiendeler = ('sofa', 'tv', 'stereo'); +felleseie("per", "kari", @eiendeler); + +# shift(@array) tar første verdi i @array, fjerner den fra arrayen og +# returnerer den. ('en', 'to', 'tre') blir altså ('to', 'tre') etter shift. +# Slik kan vi fjerne de to første variablene, og sitte igjen med resten, som +# er til arrayen. +# +# Grunnen til at det må gjøres slik er at @_ bare inneholder alle verdiene, +# den har ikke system på hva som er hva. diff --git a/foiler/37_subrutiner_dual_arrays.pl b/foiler/37_subrutiner_dual_arrays.pl new file mode 100644 index 0000000..de37030 --- /dev/null +++ b/foiler/37_subrutiner_dual_arrays.pl @@ -0,0 +1,25 @@ +#!/usr/bin/perl +use strict; +use warnings; + +# Men hva med to arrays? @_ vet jo ikke når den ene slutter og den andre +# begynner! Da må vi til med referanser igjen! + +sub tell_penisforlengere (\@\@) { + my @biler = @{ $_[0] }; + my @baater = @{ $_[1] }; + + print "Det er ".scalar @biler." bilær og ".scalar @baater."båtær\n"; +} + +my @biler = ('mercedes', 'porsche', 'austin martin'); +my @baater = ('sjekte', 'campingcruiser', 'yacht', 'pråm'); + +tell_penisforlengere(\@biler, \@baater); + +# Hva er disse backslashene? Bare en annen måte å lage referanser på. +# I C ville de tilsvart '&var'. Hvilken du bruker er hipp som happ. +# Disse gjør det samme: +my $biler; +$biler = [ @biler ]; +$biler = \@biler; diff --git a/foiler/38_prototyping.pl b/foiler/38_prototyping.pl new file mode 100644 index 0000000..2155ac7 --- /dev/null +++ b/foiler/38_prototyping.pl @@ -0,0 +1,20 @@ +#!/usr/bin/perl +use strict; +use warnings; + +# Hittil har vi hatt funksjonen øverst i scriptet. Men da må vi jo scrolle +# forbi masse drit for å se hva selve programmet gjør (man *skal* gi +# subrutinene så logiske navn at man skjønner hva de gjør ut fra navnet. + +# Dette fikser vi med en prototype. De er omtrent som i C: +sub hei ($$); + +# Og så bruker vi den +hei('rob-geir', 'tøff'); +hei('gunnar', 'sexy'); + +# Og her kommer den. +sub hei ($$) { + my ($navn, $adjektiv) = @_; + print "Hei $navn, du er $adjektiv!\n"; +} diff --git a/foiler/39_prototyping2.pl b/foiler/39_prototyping2.pl new file mode 100644 index 0000000..07c3f81 --- /dev/null +++ b/foiler/39_prototyping2.pl @@ -0,0 +1,20 @@ +#!/usr/bin/perl +use strict; +use warnings; + +# Om du skriver rekursive funksjoner må du uansett prototype. +# La oss se på denne greia som teller nedover (på en skikkelig teit måte): + +sub tellned ($); + +sub tellned ($) { + my $tall = shift; + + print "$tall...\n"; + + if ($tall > 0) { + tellned($tall-1); + } +} + +tellned(10); diff --git a/foiler/40_subrutiner_epilog.pl b/foiler/40_subrutiner_epilog.pl new file mode 100644 index 0000000..cf8b6bd --- /dev/null +++ b/foiler/40_subrutiner_epilog.pl @@ -0,0 +1,17 @@ +#!/usr/bin/perl +use strict; +use warnings; + +## Noen siste ord om subrutiner +# +# I en del gammel eller dårlig kode vil du kanskje oppdage at alle +# subrutinekall er med '&' foran, og at ingenting er prototypet. +# +# Dette var slik subrutiner virket før. De sjekket ikke antall argumenter +# eller noe som helst, og man sa fra om at de var subrutiner med &. +# Det er fremdeles mulig å gjøre det slik av hensyn til bakoverkompatibilitet, +# men IKKE GJØR DET! +# +# Om man gjør dette forsvinner nemlig alle former for feilsjekking rett i +# rett i dass, siden &subrutine() slår av sjekking av antall argumenter og +# slikt. Dette er et kjempetriks for å skjule bugs. Just don't do it, okay? diff --git a/plakat.html b/plakat.html new file mode 100644 index 0000000..2849164 --- /dev/null +++ b/plakat.html @@ -0,0 +1,88 @@ + + + + + +
+
+#! /usr/bin/perl

+PVV arrangerer nybegynnerkurs i Perl



+
+

+ + + + +
Tid: Torsdag 28. oktober, fra 18:00 til 20:00
Sted: Auditorium R8, Realfagsbygget
Pris: Kr 50 for ikke-medlemmer, gratis for medlemmer (medlemsskap koster kr 42)
+

+

+PVV arrangerer kurs for nybegynnere i programmerings- språket Perl. Vi fokuserer på hvordan man kan lage enkle script, og på å gi et grunnlag for å lære seg mer selv.

+

Kurset forutsetter litt programmeringserfaring, men halve IT-intro burde holde.

+

Kursholder: Knut Auvor Grythe

+
+
+#!/usr/bin/perl -w                                    
+use strict;
+                                           $_='ev
+                                       al("seek\040D
+           ATA,0,                  0;");foreach(1..2)
+       {<DATA>;}my               @camel1hump;my$camel;
+  my$Camel  ;while(             <DATA>){$_=sprintf("%-6
+9s",$_);my@dromedary           1=split(//);if(defined($
+_=<DATA>)){@camel1hum        p=split(//);}while(@dromeda
+ ry1){my$camel1hump=0      ;my$CAMEL=3;if(defined($_=shif
+        t(@dromedary1    ))&&/\S/){$camel1hump+=1<<$CAMEL;}
+       $CAMEL--;if(d   efined($_=shift(@dromedary1))&&/\S/){
+      $camel1hump+=1  <<$CAMEL;}$CAMEL--;if(defined($_=shift(
+     @camel1hump))&&/\S/){$camel1hump+=1<<$CAMEL;}$CAMEL--;if(
+     defined($_=shift(@camel1hump))&&/\S/){$camel1hump+=1<<$CAME
+     L;;}$camel.=(split(//,"\040..m`{/J\047\134}L^7FX"))[$camel1h
+      ump];}$camel.="\n";}@camel1hump=split(/\n/,$camel);foreach(@
+      camel1hump){chomp;$Camel=$_;tr/LJF7\173\175`\047/\061\062\063
+      45678/;tr/12345678/JL7F\175\173\047`/;$_=reverse;print"$_\040
+       $Camel\n";}foreach(@camel1hump){chomp;$Camel=$_;y/LJF7\173\17
+        5`\047/12345678/;tr/12345678/JL7F\175\173\047`/;$_=reverse;p
+         rint"\040$_$Camel\n";}#japh-Erudil';;s;\s*;;g;;eval;   eval
+           ("seek\040DATA,0,0;");undef$/;$_=<DATA>;s$\s*$$g;(   );;s
+             ;^.*_;;;map{eval"print\"$_\"";}/.{4}/g; __DATA__   \124
+               \1   50\145\040\165\163\145\040\157\1 46\040\1  41\0
+                    40\143\141  \155\145\1 54\040\1   51\155\  141
+                    \147\145\0  40\151\156 \040\141    \163\16 3\
+                     157\143\   151\141\16  4\151\1     57\156
+                     \040\167  \151\164\1   50\040\      120\1
+                     45\162\   154\040\15    1\163\      040\14
+                     1\040\1   64\162\1      41\144       \145\
+                     155\14    1\162\       153\04        0\157
+                      \146\     040\11     7\047\         122\1
+                      45\15      1\154\1  54\171          \040
+                      \046\         012\101\16            3\16
+                      3\15           7\143\15             1\14
+                      1\16            4\145\163           \054
+                     \040            \111\156\14         3\056
+                    \040\         125\163\145\14         4\040\
+                    167\1        51\164\1  50\0         40\160\
+                  145\162                              \155\151
+                \163\163                                \151\1
+              57\156\056
+
+# camel code, copyright 2000 by Stephen B. Jenkins
+# The use of a camel image with the topic of Perl 
+# is a trademark of O'Reilly & Associates, Inc. 
+# Used with permission.
+
+ +
+ + diff --git a/plakat.pdf b/plakat.pdf new file mode 100644 index 0000000000000000000000000000000000000000..7ca1b02848302744c033e975c64851d5e6d53052 GIT binary patch literal 4412 zcmY!laBO|JbD;CTAF}brOsY3F|VN-EMo_&YPYx>mYTc4=8 z7igy0ZX$e8r?`*L`qcM^ZvXtMq7&=u7@oAQyX0#bzjIw$*7@=Y%O_vncWr<7r8(=W zpXdl3+Kmc zMy2O9f=6oJY1tm~_xGwY3CPxY_*(4GvI*f)lRh1trnsfV)2d?8(~P1oH($QjKj+^g zd-=slqX?7cc~`fb@UT^Rd9Zom>wVIbKAZm4SAX;I@thkwGYg)?Haq5VTbG^L>bvD- z_N;A+JoTxo&el)g^C)A@*YB1Wlh$RtGyIr*M)dN|X0sYQhi&V`e}96mzPx) zZs(P+r?yoV|2zNU>HXME9~P>tV{TEiyH?^MSUz`l+Xk)Ff|MKQpPP0+^Yp#? zpABZ8f-GM8&h_Cre?D%~qKS^;uP29eY?*cT#iGkcSKRbDE!W%LlDuo8`MGoM`l{O! z9RDm|*!)rCPgnO8>rL}^ML3Fdgz0(SytF;)r}@{s+eNca#(J$U`Mco6wRb9_-h20E z20uHPp1)USkHG9o0XZwbS3B~4T_~(M{xCf5MS$&t+VsWQxlKRUO@CiFTjKJ1^;D7S zs9Va1;?9>pVQVd(^W|LI>pzR_=2-O!SH8|Rx;~Y$ELQT7-YS_@*PoreP@Z6=dh6ws z6*0?Ze}8lLhX29KAM&DtlR#TckXd zt2$;Z(z6P-IJ5=W%(xGkI~zad{xK$sM)PqYyaw8 zdRWGuT-iFsJHqSQx97#$iJr6W-Qtq6No{(Ue5h;1q;)GkEz(PgykfJd>YI>g;f42K zcfMSGCgk1S9=Xd;Pk(Xz_nm8V%DLYavH7kK^o=i=`Zk}| z-E;a!)yd?FRfi<|!ySEg?~HX&_vZUzHc#h(c16>P&z3d3n^aRQW~shTaC@Bp!gs!l ztiyyyZ+t3>bb+_B4cd%DuI8h;u;{X9pspC@p_GDo4+ z7GIK>^8ddVJ}V(nW_sQv;?XM(w_RCN)TJ_HGheI;VhEi(;n>DikwzI$`elq%mmYjk z;KH1LZ$G;~hyJ&n511akRsFub@XXOHun#|toN^MnCJD+T2WpknU z=;w3nsX}Mu4_-{ji9Dqu`0~zYNBPwg)@*t*soPGcg+1pF$7BU=r!#CdR=+GPU%zO} znl$m`VScV>Z7PY6C$7r$u{=7xOGl7#9*^F!+8qz#c6|8rrReokYdj%c6G`z1* zz0Q=)`Qa*O)738i4@<3|1iE~yeV95!!zAQu(-Q;V(w=o0Pud@8{mhuPZjb4jNhXIg zwHejs?kEstTh{AsV{mLooJqakiRIFFttfF12J1C~YH`cYD^V~q0qeK3SES5@CoTs#g{C zofAtEbMn(+hJh?Ww$uz&J;MF^eu=rM`ax#;Awl|{DXDoSnI)C_PVNd|kLZUw2Pv3> zyo9hB>|coc^@Gf~Kn4dP$%6F3WDU)^48gw94>C03GBg4iq#tBt$Ylg_evp2Up&6GU z*Z}DLDb;Bt`}XEKUMP9n?)uiN&d)1g`Iqnp2iq zl9`;S>y)390#3jBUG& zO~o|R2&b9gbcAkZNM>$oG1x>5ql^r38U;>==tiOX7N-NvaGMHB(&(nbJdM*l+^z)Y z3v}}k9`-Cr%*jl~^tJ(R2O?z#ERl@UiKe(s1Z7fmCk9vMCgtZ~ILr`_!$27v-57{Z zarn~E61SU>vKQQ!&}hJPlnG9Az~u{eM+N2QCgx$7WrREJf(s~gv)~C1!z4osE`8U$ zBH+ooM&sB!TxC0DP?F1C%r<5kA7HPN#_$at%bVl;}%tPJ(c^+CoOSQ=Rv7{+L7+Sx%%--@EtG%f=LBQq`oI8ZP%H8nO> zNK=4{8Csf{D1c=Z@?c`dW+vw7Vulvxrs!fuCI%K5Vn${L=wgPJmPQz2<_4DNVg?4F zS`p+Jgj)>FEHKm=8-h|SsyZVJa}0GxX2zI)Gd0I>pRo}ZF#{6}bw=iv#^`P~GBw2r z7h@ApEYD&=1PbFHr!M=s^nlo_T5c3gG4jsA*SRl2}v%PDRERh9+F9s;>TSTmaDJOWFVc literal 0 HcmV?d00001 diff --git a/plakat.ps b/plakat.ps new file mode 100644 index 0000000..e630b57 --- /dev/null +++ b/plakat.ps @@ -0,0 +1,1787 @@ +%!PS-Adobe-3.0 +%%BoundingBox: 0 0 595.25 841.9 +%%Creator: Mozilla PostScript module (rv:1.7/2004092801) +%%DocumentData: Clean8Bit +%%DocumentPaperSizes: A4 +%%Orientation: Landscape +%%Pages: (atend) +%%PageOrder: Ascend +%%EndComments +% MozillaCharsetName: iso-8859-1 + +%%BeginProlog +/setpagedevice where +{ pop 1 dict + dup /PageSize [ 595.25 841.9 ] put + setpagedevice +} if +[ /.notdef /.notdef /.notdef /.notdef /.notdef /.notdef + /.notdef /.notdef /.notdef /.notdef /.notdef /.notdef + /.notdef /.notdef /.notdef /.notdef /.notdef /.notdef + /.notdef /.notdef /.notdef /.notdef /.notdef /.notdef + /.notdef /.notdef /.notdef /.notdef /.notdef /.notdef + /.notdef /.notdef /space /exclam /quotedbl /numbersign + /dollar /percent /ampersand /quoteright /parenleft /parenright + /asterisk /plus /comma /hyphen /period /slash + /zero /one /two /three /four /five + /six /seven /eight /nine /colon /semicolon + /less /equal /greater /question /at /A + /B /C /D /E /F /G + /H /I /J /K /L /M + /N /O /P /Q /R /S + /T /U /V /W /X /Y + /Z /bracketleft /backslash /bracketright /asciicircum /underscore + /quoteleft /a /b /c /d /e + /f /g /h /i /j /k + /l /m /n /o /p /q + /r /s /t /u /v /w + /x /y /z /braceleft /bar /braceright + /asciitilde /.notdef /.notdef /.notdef /.notdef /.notdef + /.notdef /.notdef /.notdef /.notdef /.notdef /.notdef + /.notdef /.notdef /.notdef /.notdef /.notdef /.notdef + /.notdef /.notdef /.notdef /.notdef /.notdef /.notdef + /.notdef /.notdef /.notdef /.notdef /.notdef /.notdef + /.notdef /.notdef /.notdef /.notdef /space /exclamdown + /cent /sterling /currency /yen /brokenbar /section + /dieresis /copyright /ordfeminine /guillemotleft /logicalnot /hyphen + /registered /macron /degree /plusminus /twosuperior /threesuperior + /acute /mu /paragraph /periodcentered /cedilla /onesuperior + /ordmasculine /guillemotright /onequarter /onehalf /threequarters /questiondown + /Agrave /Aacute /Acircumflex /Atilde /Adieresis /Aring + /AE /Ccedilla /Egrave /Eacute /Ecircumflex /Edieresis + /Igrave /Iacute /Icircumflex /Idieresis /Eth /Ntilde + /Ograve /Oacute /Ocircumflex /Otilde /Odieresis /multiply + /Oslash /Ugrave /Uacute /Ucircumflex /Udieresis /Yacute + /Thorn /germandbls /agrave /aacute /acircumflex /atilde + /adieresis /aring /ae /ccedilla /egrave /eacute + /ecircumflex /edieresis /igrave /iacute /icircumflex /idieresis + /eth /ntilde /ograve /oacute /ocircumflex /otilde + /odieresis /divide /oslash /ugrave /uacute /ucircumflex + /udieresis /yacute /thorn /ydieresis] /isolatin1encoding exch def +/Mfr { + findfont dup length dict + begin + {1 index /FID ne {def} {pop pop} ifelse} forall + /Encoding isolatin1encoding def + currentdict + end + definefont pop +} bind def +/Msf /selectfont where + { pop { exch selectfont } } + { { findfont exch scalefont setfont } } + ifelse + bind def +/F0 /Times-Roman Mfr +/f0 { dup /csize exch def /F0 Msf } bind def +/F1 /Times-Bold Mfr +/f1 { dup /csize exch def /F1 Msf } bind def +/F2 /Times-BoldItalic Mfr +/f2 { dup /csize exch def /F2 Msf } bind def +/F3 /Times-Italic Mfr +/f3 { dup /csize exch def /F3 Msf } bind def +/F4 /Helvetica Mfr +/f4 { dup /csize exch def /F4 Msf } bind def +/F5 /Helvetica-Bold Mfr +/f5 { dup /csize exch def /F5 Msf } bind def +/F6 /Helvetica-BoldOblique Mfr +/f6 { dup /csize exch def /F6 Msf } bind def +/F7 /Helvetica-Oblique Mfr +/f7 { dup /csize exch def /F7 Msf } bind def +/F8 /Courier Mfr +/f8 { dup /csize exch def /F8 Msf } bind def +/F9 /Courier-Bold Mfr +/f9 { dup /csize exch def /F9 Msf } bind def +/F10 /Courier-BoldOblique Mfr +/f10 { dup /csize exch def /F10 Msf } bind def +/F11 /Courier-Oblique Mfr +/f11 { dup /csize exch def /F11 Msf } bind def +/F12 /Symbol Mfr +/f12 { dup /csize exch def /F12 Msf } bind def +/UniDict +1051 dict dup begin +16#0020 /space def +16#0021 /exclam def +16#0022 /quotedbl def +16#0023 /numbersign def +16#0024 /dollar def +16#0025 /percent def +16#0026 /ampersand def +16#0027 /quotesingle def +16#0028 /parenleft def +16#0029 /parenright def +16#002A /asterisk def +16#002B /plus def +16#002C /comma def +16#002D /hyphen def +16#002E /period def +16#002F /slash def +16#0030 /zero def +16#0031 /one def +16#0032 /two def +16#0033 /three def +16#0034 /four def +16#0035 /five def +16#0036 /six def +16#0037 /seven def +16#0038 /eight def +16#0039 /nine def +16#003A /colon def +16#003B /semicolon def +16#003C /less def +16#003D /equal def +16#003E /greater def +16#003F /question def +16#0040 /at def +16#0041 /A def +16#0042 /B def +16#0043 /C def +16#0044 /D def +16#0045 /E def +16#0046 /F def +16#0047 /G def +16#0048 /H def +16#0049 /I def +16#004A /J def +16#004B /K def +16#004C /L def +16#004D /M def +16#004E /N def +16#004F /O def +16#0050 /P def +16#0051 /Q def +16#0052 /R def +16#0053 /S def +16#0054 /T def +16#0055 /U def +16#0056 /V def +16#0057 /W def +16#0058 /X def +16#0059 /Y def +16#005A /Z def +16#005B /bracketleft def +16#005C /backslash def +16#005D /bracketright def +16#005E /asciicircum def +16#005F /underscore def +16#0060 /grave def +16#0061 /a def +16#0062 /b def +16#0063 /c def +16#0064 /d def +16#0065 /e def +16#0066 /f def +16#0067 /g def +16#0068 /h def +16#0069 /i def +16#006A /j def +16#006B /k def +16#006C /l def +16#006D /m def +16#006E /n def +16#006F /o def +16#0070 /p def +16#0071 /q def +16#0072 /r def +16#0073 /s def +16#0074 /t def +16#0075 /u def +16#0076 /v def +16#0077 /w def +16#0078 /x def +16#0079 /y def +16#007A /z def +16#007B /braceleft def +16#007C /bar def +16#007D /braceright def +16#007E /asciitilde def +16#00A0 /space def +16#00A1 /exclamdown def +16#00A2 /cent def +16#00A3 /sterling def +16#00A4 /currency def +16#00A5 /yen def +16#00A6 /brokenbar def +16#00A7 /section def +16#00A8 /dieresis def +16#00A9 /copyright def +16#00AA /ordfeminine def +16#00AB /guillemotleft def +16#00AC /logicalnot def +16#00AD /hyphen def +16#00AE /registered def +16#00AF /macron def +16#00B0 /degree def +16#00B1 /plusminus def +16#00B2 /twosuperior def +16#00B3 /threesuperior def +16#00B4 /acute def +16#00B5 /mu def +16#00B6 /paragraph def +16#00B7 /periodcentered def +16#00B8 /cedilla def +16#00B9 /onesuperior def +16#00BA /ordmasculine def +16#00BB /guillemotright def +16#00BC /onequarter def +16#00BD /onehalf def +16#00BE /threequarters def +16#00BF /questiondown def +16#00C0 /Agrave def +16#00C1 /Aacute def +16#00C2 /Acircumflex def +16#00C3 /Atilde def +16#00C4 /Adieresis def +16#00C5 /Aring def +16#00C6 /AE def +16#00C7 /Ccedilla def +16#00C8 /Egrave def +16#00C9 /Eacute def +16#00CA /Ecircumflex def +16#00CB /Edieresis def +16#00CC /Igrave def +16#00CD /Iacute def +16#00CE /Icircumflex def +16#00CF /Idieresis def +16#00D0 /Eth def +16#00D1 /Ntilde def +16#00D2 /Ograve def +16#00D3 /Oacute def +16#00D4 /Ocircumflex def +16#00D5 /Otilde def +16#00D6 /Odieresis def +16#00D7 /multiply def +16#00D8 /Oslash def +16#00D9 /Ugrave def +16#00DA /Uacute def +16#00DB /Ucircumflex def +16#00DC /Udieresis def +16#00DD /Yacute def +16#00DE /Thorn def +16#00DF /germandbls def +16#00E0 /agrave def +16#00E1 /aacute def +16#00E2 /acircumflex def +16#00E3 /atilde def +16#00E4 /adieresis def +16#00E5 /aring def +16#00E6 /ae def +16#00E7 /ccedilla def +16#00E8 /egrave def +16#00E9 /eacute def +16#00EA /ecircumflex def +16#00EB /edieresis def +16#00EC /igrave def +16#00ED /iacute def +16#00EE /icircumflex def +16#00EF /idieresis def +16#00F0 /eth def +16#00F1 /ntilde def +16#00F2 /ograve def +16#00F3 /oacute def +16#00F4 /ocircumflex def +16#00F5 /otilde def +16#00F6 /odieresis def +16#00F7 /divide def +16#00F8 /oslash def +16#00F9 /ugrave def +16#00FA /uacute def +16#00FB /ucircumflex def +16#00FC /udieresis def +16#00FD /yacute def +16#00FE /thorn def +16#00FF /ydieresis def +16#0100 /Amacron def +16#0101 /amacron def +16#0102 /Abreve def +16#0103 /abreve def +16#0104 /Aogonek def +16#0105 /aogonek def +16#0106 /Cacute def +16#0107 /cacute def +16#0108 /Ccircumflex def +16#0109 /ccircumflex def +16#010A /Cdotaccent def +16#010B /cdotaccent def +16#010C /Ccaron def +16#010D /ccaron def +16#010E /Dcaron def +16#010F /dcaron def +16#0110 /Dcroat def +16#0111 /dcroat def +16#0112 /Emacron def +16#0113 /emacron def +16#0114 /Ebreve def +16#0115 /ebreve def +16#0116 /Edotaccent def +16#0117 /edotaccent def +16#0118 /Eogonek def +16#0119 /eogonek def +16#011A /Ecaron def +16#011B /ecaron def +16#011C /Gcircumflex def +16#011D /gcircumflex def +16#011E /Gbreve def +16#011F /gbreve def +16#0120 /Gdotaccent def +16#0121 /gdotaccent def +16#0122 /Gcommaaccent def +16#0123 /gcommaaccent def +16#0124 /Hcircumflex def +16#0125 /hcircumflex def +16#0126 /Hbar def +16#0127 /hbar def +16#0128 /Itilde def +16#0129 /itilde def +16#012A /Imacron def +16#012B /imacron def +16#012C /Ibreve def +16#012D /ibreve def +16#012E /Iogonek def +16#012F /iogonek def +16#0130 /Idotaccent def +16#0131 /dotlessi def +16#0132 /IJ def +16#0133 /ij def +16#0134 /Jcircumflex def +16#0135 /jcircumflex def +16#0136 /Kcommaaccent def +16#0137 /kcommaaccent def +16#0138 /kgreenlandic def +16#0139 /Lacute def +16#013A /lacute def +16#013B /Lcommaaccent def +16#013C /lcommaaccent def +16#013D /Lcaron def +16#013E /lcaron def +16#013F /Ldot def +16#0140 /ldot def +16#0141 /Lslash def +16#0142 /lslash def +16#0143 /Nacute def +16#0144 /nacute def +16#0145 /Ncommaaccent def +16#0146 /ncommaaccent def +16#0147 /Ncaron def +16#0148 /ncaron def +16#0149 /napostrophe def +16#014A /Eng def +16#014B /eng def +16#014C /Omacron def +16#014D /omacron def +16#014E /Obreve def +16#014F /obreve def +16#0150 /Ohungarumlaut def +16#0151 /ohungarumlaut def +16#0152 /OE def +16#0153 /oe def +16#0154 /Racute def +16#0155 /racute def +16#0156 /Rcommaaccent def +16#0157 /rcommaaccent def +16#0158 /Rcaron def +16#0159 /rcaron def +16#015A /Sacute def +16#015B /sacute def +16#015C /Scircumflex def +16#015D /scircumflex def +16#015E /Scedilla def +16#015F /scedilla def +16#0160 /Scaron def +16#0161 /scaron def +16#0162 /Tcommaaccent def +16#0163 /tcommaaccent def +16#0164 /Tcaron def +16#0165 /tcaron def +16#0166 /Tbar def +16#0167 /tbar def +16#0168 /Utilde def +16#0169 /utilde def +16#016A /Umacron def +16#016B /umacron def +16#016C /Ubreve def +16#016D /ubreve def +16#016E /Uring def +16#016F /uring def +16#0170 /Uhungarumlaut def +16#0171 /uhungarumlaut def +16#0172 /Uogonek def +16#0173 /uogonek def +16#0174 /Wcircumflex def +16#0175 /wcircumflex def +16#0176 /Ycircumflex def +16#0177 /ycircumflex def +16#0178 /Ydieresis def +16#0179 /Zacute def +16#017A /zacute def +16#017B /Zdotaccent def +16#017C /zdotaccent def +16#017D /Zcaron def +16#017E /zcaron def +16#017F /longs def +16#0192 /florin def +16#01A0 /Ohorn def +16#01A1 /ohorn def +16#01AF /Uhorn def +16#01B0 /uhorn def +16#01E6 /Gcaron def +16#01E7 /gcaron def +16#01FA /Aringacute def +16#01FB /aringacute def +16#01FC /AEacute def +16#01FD /aeacute def +16#01FE /Oslashacute def +16#01FF /oslashacute def +16#0218 /Scommaaccent def +16#0219 /scommaaccent def +16#021A /Tcommaaccent def +16#021B /tcommaaccent def +16#02BC /afii57929 def +16#02BD /afii64937 def +16#02C6 /circumflex def +16#02C7 /caron def +16#02C9 /macron def +16#02D8 /breve def +16#02D9 /dotaccent def +16#02DA /ring def +16#02DB /ogonek def +16#02DC /tilde def +16#02DD /hungarumlaut def +16#0300 /gravecomb def +16#0301 /acutecomb def +16#0303 /tildecomb def +16#0309 /hookabovecomb def +16#0323 /dotbelowcomb def +16#0384 /tonos def +16#0385 /dieresistonos def +16#0386 /Alphatonos def +16#0387 /anoteleia def +16#0388 /Epsilontonos def +16#0389 /Etatonos def +16#038A /Iotatonos def +16#038C /Omicrontonos def +16#038E /Upsilontonos def +16#038F /Omegatonos def +16#0390 /iotadieresistonos def +16#0391 /Alpha def +16#0392 /Beta def +16#0393 /Gamma def +16#0394 /Delta def +16#0395 /Epsilon def +16#0396 /Zeta def +16#0397 /Eta def +16#0398 /Theta def +16#0399 /Iota def +16#039A /Kappa def +16#039B /Lambda def +16#039C /Mu def +16#039D /Nu def +16#039E /Xi def +16#039F /Omicron def +16#03A0 /Pi def +16#03A1 /Rho def +16#03A3 /Sigma def +16#03A4 /Tau def +16#03A5 /Upsilon def +16#03A6 /Phi def +16#03A7 /Chi def +16#03A8 /Psi def +16#03A9 /Omega def +16#03AA /Iotadieresis def +16#03AB /Upsilondieresis def +16#03AC /alphatonos def +16#03AD /epsilontonos def +16#03AE /etatonos def +16#03AF /iotatonos def +16#03B0 /upsilondieresistonos def +16#03B1 /alpha def +16#03B2 /beta def +16#03B3 /gamma def +16#03B4 /delta def +16#03B5 /epsilon def +16#03B6 /zeta def +16#03B7 /eta def +16#03B8 /theta def +16#03B9 /iota def +16#03BA /kappa def +16#03BB /lambda def +16#03BC /mu def +16#03BD /nu def +16#03BE /xi def +16#03BF /omicron def +16#03C0 /pi def +16#03C1 /rho def +16#03C2 /sigma1 def +16#03C3 /sigma def +16#03C4 /tau def +16#03C5 /upsilon def +16#03C6 /phi def +16#03C7 /chi def +16#03C8 /psi def +16#03C9 /omega def +16#03CA /iotadieresis def +16#03CB /upsilondieresis def +16#03CC /omicrontonos def +16#03CD /upsilontonos def +16#03CE /omegatonos def +16#03D1 /theta1 def +16#03D2 /Upsilon1 def +16#03D5 /phi1 def +16#03D6 /omega1 def +16#0401 /afii10023 def +16#0402 /afii10051 def +16#0403 /afii10052 def +16#0404 /afii10053 def +16#0405 /afii10054 def +16#0406 /afii10055 def +16#0407 /afii10056 def +16#0408 /afii10057 def +16#0409 /afii10058 def +16#040A /afii10059 def +16#040B /afii10060 def +16#040C /afii10061 def +16#040E /afii10062 def +16#040F /afii10145 def +16#0410 /afii10017 def +16#0411 /afii10018 def +16#0412 /afii10019 def +16#0413 /afii10020 def +16#0414 /afii10021 def +16#0415 /afii10022 def +16#0416 /afii10024 def +16#0417 /afii10025 def +16#0418 /afii10026 def +16#0419 /afii10027 def +16#041A /afii10028 def +16#041B /afii10029 def +16#041C /afii10030 def +16#041D /afii10031 def +16#041E /afii10032 def +16#041F /afii10033 def +16#0420 /afii10034 def +16#0421 /afii10035 def +16#0422 /afii10036 def +16#0423 /afii10037 def +16#0424 /afii10038 def +16#0425 /afii10039 def +16#0426 /afii10040 def +16#0427 /afii10041 def +16#0428 /afii10042 def +16#0429 /afii10043 def +16#042A /afii10044 def +16#042B /afii10045 def +16#042C /afii10046 def +16#042D /afii10047 def +16#042E /afii10048 def +16#042F /afii10049 def +16#0430 /afii10065 def +16#0431 /afii10066 def +16#0432 /afii10067 def +16#0433 /afii10068 def +16#0434 /afii10069 def +16#0435 /afii10070 def +16#0436 /afii10072 def +16#0437 /afii10073 def +16#0438 /afii10074 def +16#0439 /afii10075 def +16#043A /afii10076 def +16#043B /afii10077 def +16#043C /afii10078 def +16#043D /afii10079 def +16#043E /afii10080 def +16#043F /afii10081 def +16#0440 /afii10082 def +16#0441 /afii10083 def +16#0442 /afii10084 def +16#0443 /afii10085 def +16#0444 /afii10086 def +16#0445 /afii10087 def +16#0446 /afii10088 def +16#0447 /afii10089 def +16#0448 /afii10090 def +16#0449 /afii10091 def +16#044A /afii10092 def +16#044B /afii10093 def +16#044C /afii10094 def +16#044D /afii10095 def +16#044E /afii10096 def +16#044F /afii10097 def +16#0451 /afii10071 def +16#0452 /afii10099 def +16#0453 /afii10100 def +16#0454 /afii10101 def +16#0455 /afii10102 def +16#0456 /afii10103 def +16#0457 /afii10104 def +16#0458 /afii10105 def +16#0459 /afii10106 def +16#045A /afii10107 def +16#045B /afii10108 def +16#045C /afii10109 def +16#045E /afii10110 def +16#045F /afii10193 def +16#0462 /afii10146 def +16#0463 /afii10194 def +16#0472 /afii10147 def +16#0473 /afii10195 def +16#0474 /afii10148 def +16#0475 /afii10196 def +16#0490 /afii10050 def +16#0491 /afii10098 def +16#04D9 /afii10846 def +16#05B0 /afii57799 def +16#05B1 /afii57801 def +16#05B2 /afii57800 def +16#05B3 /afii57802 def +16#05B4 /afii57793 def +16#05B5 /afii57794 def +16#05B6 /afii57795 def +16#05B7 /afii57798 def +16#05B8 /afii57797 def +16#05B9 /afii57806 def +16#05BB /afii57796 def +16#05BC /afii57807 def +16#05BD /afii57839 def +16#05BE /afii57645 def +16#05BF /afii57841 def +16#05C0 /afii57842 def +16#05C1 /afii57804 def +16#05C2 /afii57803 def +16#05C3 /afii57658 def +16#05D0 /afii57664 def +16#05D1 /afii57665 def +16#05D2 /afii57666 def +16#05D3 /afii57667 def +16#05D4 /afii57668 def +16#05D5 /afii57669 def +16#05D6 /afii57670 def +16#05D7 /afii57671 def +16#05D8 /afii57672 def +16#05D9 /afii57673 def +16#05DA /afii57674 def +16#05DB /afii57675 def +16#05DC /afii57676 def +16#05DD /afii57677 def +16#05DE /afii57678 def +16#05DF /afii57679 def +16#05E0 /afii57680 def +16#05E1 /afii57681 def +16#05E2 /afii57682 def +16#05E3 /afii57683 def +16#05E4 /afii57684 def +16#05E5 /afii57685 def +16#05E6 /afii57686 def +16#05E7 /afii57687 def +16#05E8 /afii57688 def +16#05E9 /afii57689 def +16#05EA /afii57690 def +16#05F0 /afii57716 def +16#05F1 /afii57717 def +16#05F2 /afii57718 def +16#060C /afii57388 def +16#061B /afii57403 def +16#061F /afii57407 def +16#0621 /afii57409 def +16#0622 /afii57410 def +16#0623 /afii57411 def +16#0624 /afii57412 def +16#0625 /afii57413 def +16#0626 /afii57414 def +16#0627 /afii57415 def +16#0628 /afii57416 def +16#0629 /afii57417 def +16#062A /afii57418 def +16#062B /afii57419 def +16#062C /afii57420 def +16#062D /afii57421 def +16#062E /afii57422 def +16#062F /afii57423 def +16#0630 /afii57424 def +16#0631 /afii57425 def +16#0632 /afii57426 def +16#0633 /afii57427 def +16#0634 /afii57428 def +16#0635 /afii57429 def +16#0636 /afii57430 def +16#0637 /afii57431 def +16#0638 /afii57432 def +16#0639 /afii57433 def +16#063A /afii57434 def +16#0640 /afii57440 def +16#0641 /afii57441 def +16#0642 /afii57442 def +16#0643 /afii57443 def +16#0644 /afii57444 def +16#0645 /afii57445 def +16#0646 /afii57446 def +16#0647 /afii57470 def +16#0648 /afii57448 def +16#0649 /afii57449 def +16#064A /afii57450 def +16#064B /afii57451 def +16#064C /afii57452 def +16#064D /afii57453 def +16#064E /afii57454 def +16#064F /afii57455 def +16#0650 /afii57456 def +16#0651 /afii57457 def +16#0652 /afii57458 def +16#0660 /afii57392 def +16#0661 /afii57393 def +16#0662 /afii57394 def +16#0663 /afii57395 def +16#0664 /afii57396 def +16#0665 /afii57397 def +16#0666 /afii57398 def +16#0667 /afii57399 def +16#0668 /afii57400 def +16#0669 /afii57401 def +16#066A /afii57381 def +16#066D /afii63167 def +16#0679 /afii57511 def +16#067E /afii57506 def +16#0686 /afii57507 def +16#0688 /afii57512 def +16#0691 /afii57513 def +16#0698 /afii57508 def +16#06A4 /afii57505 def +16#06AF /afii57509 def +16#06BA /afii57514 def +16#06D2 /afii57519 def +16#06D5 /afii57534 def +16#1E80 /Wgrave def +16#1E81 /wgrave def +16#1E82 /Wacute def +16#1E83 /wacute def +16#1E84 /Wdieresis def +16#1E85 /wdieresis def +16#1EF2 /Ygrave def +16#1EF3 /ygrave def +16#200C /afii61664 def +16#200D /afii301 def +16#200E /afii299 def +16#200F /afii300 def +16#2012 /figuredash def +16#2013 /endash def +16#2014 /emdash def +16#2015 /afii00208 def +16#2017 /underscoredbl def +16#2018 /quoteleft def +16#2019 /quoteright def +16#201A /quotesinglbase def +16#201B /quotereversed def +16#201C /quotedblleft def +16#201D /quotedblright def +16#201E /quotedblbase def +16#2020 /dagger def +16#2021 /daggerdbl def +16#2022 /bullet def +16#2024 /onedotenleader def +16#2025 /twodotenleader def +16#2026 /ellipsis def +16#202C /afii61573 def +16#202D /afii61574 def +16#202E /afii61575 def +16#2030 /perthousand def +16#2032 /minute def +16#2033 /second def +16#2039 /guilsinglleft def +16#203A /guilsinglright def +16#203C /exclamdbl def +16#2044 /fraction def +16#2070 /zerosuperior def +16#2074 /foursuperior def +16#2075 /fivesuperior def +16#2076 /sixsuperior def +16#2077 /sevensuperior def +16#2078 /eightsuperior def +16#2079 /ninesuperior def +16#207D /parenleftsuperior def +16#207E /parenrightsuperior def +16#207F /nsuperior def +16#2080 /zeroinferior def +16#2081 /oneinferior def +16#2082 /twoinferior def +16#2083 /threeinferior def +16#2084 /fourinferior def +16#2085 /fiveinferior def +16#2086 /sixinferior def +16#2087 /seveninferior def +16#2088 /eightinferior def +16#2089 /nineinferior def +16#208D /parenleftinferior def +16#208E /parenrightinferior def +16#20A1 /colonmonetary def +16#20A3 /franc def +16#20A4 /lira def +16#20A7 /peseta def +16#20AA /afii57636 def +16#20AB /dong def +16#20AC /Euro def +16#2105 /afii61248 def +16#2111 /Ifraktur def +16#2113 /afii61289 def +16#2116 /afii61352 def +16#2118 /weierstrass def +16#211C /Rfraktur def +16#211E /prescription def +16#2122 /trademark def +16#2126 /Omega def +16#212E /estimated def +16#2135 /aleph def +16#2153 /onethird def +16#2154 /twothirds def +16#215B /oneeighth def +16#215C /threeeighths def +16#215D /fiveeighths def +16#215E /seveneighths def +16#2190 /arrowleft def +16#2191 /arrowup def +16#2192 /arrowright def +16#2193 /arrowdown def +16#2194 /arrowboth def +16#2195 /arrowupdn def +16#21A8 /arrowupdnbse def +16#21B5 /carriagereturn def +16#21D0 /arrowdblleft def +16#21D1 /arrowdblup def +16#21D2 /arrowdblright def +16#21D3 /arrowdbldown def +16#21D4 /arrowdblboth def +16#2200 /universal def +16#2202 /partialdiff def +16#2203 /existential def +16#2205 /emptyset def +16#2206 /Delta def +16#2207 /gradient def +16#2208 /element def +16#2209 /notelement def +16#220B /suchthat def +16#220F /product def +16#2211 /summation def +16#2212 /minus def +16#2215 /fraction def +16#2217 /asteriskmath def +16#2219 /periodcentered def +16#221A /radical def +16#221D /proportional def +16#221E /infinity def +16#221F /orthogonal def +16#2220 /angle def +16#2227 /logicaland def +16#2228 /logicalor def +16#2229 /intersection def +16#222A /union def +16#222B /integral def +16#2234 /therefore def +16#223C /similar def +16#2245 /congruent def +16#2248 /approxequal def +16#2260 /notequal def +16#2261 /equivalence def +16#2264 /lessequal def +16#2265 /greaterequal def +16#2282 /propersubset def +16#2283 /propersuperset def +16#2284 /notsubset def +16#2286 /reflexsubset def +16#2287 /reflexsuperset def +16#2295 /circleplus def +16#2297 /circlemultiply def +16#22A5 /perpendicular def +16#22C5 /dotmath def +16#2302 /house def +16#2310 /revlogicalnot def +16#2320 /integraltp def +16#2321 /integralbt def +16#2329 /angleleft def +16#232A /angleright def +16#2500 /SF100000 def +16#2502 /SF110000 def +16#250C /SF010000 def +16#2510 /SF030000 def +16#2514 /SF020000 def +16#2518 /SF040000 def +16#251C /SF080000 def +16#2524 /SF090000 def +16#252C /SF060000 def +16#2534 /SF070000 def +16#253C /SF050000 def +16#2550 /SF430000 def +16#2551 /SF240000 def +16#2552 /SF510000 def +16#2553 /SF520000 def +16#2554 /SF390000 def +16#2555 /SF220000 def +16#2556 /SF210000 def +16#2557 /SF250000 def +16#2558 /SF500000 def +16#2559 /SF490000 def +16#255A /SF380000 def +16#255B /SF280000 def +16#255C /SF270000 def +16#255D /SF260000 def +16#255E /SF360000 def +16#255F /SF370000 def +16#2560 /SF420000 def +16#2561 /SF190000 def +16#2562 /SF200000 def +16#2563 /SF230000 def +16#2564 /SF470000 def +16#2565 /SF480000 def +16#2566 /SF410000 def +16#2567 /SF450000 def +16#2568 /SF460000 def +16#2569 /SF400000 def +16#256A /SF540000 def +16#256B /SF530000 def +16#256C /SF440000 def +16#2580 /upblock def +16#2584 /dnblock def +16#2588 /block def +16#258C /lfblock def +16#2590 /rtblock def +16#2591 /ltshade def +16#2592 /shade def +16#2593 /dkshade def +16#25A0 /filledbox def +16#25A1 /H22073 def +16#25AA /H18543 def +16#25AB /H18551 def +16#25AC /filledrect def +16#25B2 /triagup def +16#25BA /triagrt def +16#25BC /triagdn def +16#25C4 /triaglf def +16#25CA /lozenge def +16#25CB /circle def +16#25CF /H18533 def +16#25D8 /invbullet def +16#25D9 /invcircle def +16#25E6 /openbullet def +16#263A /smileface def +16#263B /invsmileface def +16#263C /sun def +16#2640 /female def +16#2642 /male def +16#2660 /spade def +16#2663 /club def +16#2665 /heart def +16#2666 /diamond def +16#266A /musicalnote def +16#266B /musicalnotedbl def +16#F6BE /dotlessj def +16#F6BF /LL def +16#F6C0 /ll def +16#F6C1 /Scedilla def +16#F6C2 /scedilla def +16#F6C3 /commaaccent def +16#F6C4 /afii10063 def +16#F6C5 /afii10064 def +16#F6C6 /afii10192 def +16#F6C7 /afii10831 def +16#F6C8 /afii10832 def +16#F6C9 /Acute def +16#F6CA /Caron def +16#F6CB /Dieresis def +16#F6CC /DieresisAcute def +16#F6CD /DieresisGrave def +16#F6CE /Grave def +16#F6CF /Hungarumlaut def +16#F6D0 /Macron def +16#F6D1 /cyrBreve def +16#F6D2 /cyrFlex def +16#F6D3 /dblGrave def +16#F6D4 /cyrbreve def +16#F6D5 /cyrflex def +16#F6D6 /dblgrave def +16#F6D7 /dieresisacute def +16#F6D8 /dieresisgrave def +16#F6D9 /copyrightserif def +16#F6DA /registerserif def +16#F6DB /trademarkserif def +16#F6DC /onefitted def +16#F6DD /rupiah def +16#F6DE /threequartersemdash def +16#F6DF /centinferior def +16#F6E0 /centsuperior def +16#F6E1 /commainferior def +16#F6E2 /commasuperior def +16#F6E3 /dollarinferior def +16#F6E4 /dollarsuperior def +16#F6E5 /hypheninferior def +16#F6E6 /hyphensuperior def +16#F6E7 /periodinferior def +16#F6E8 /periodsuperior def +16#F6E9 /asuperior def +16#F6EA /bsuperior def +16#F6EB /dsuperior def +16#F6EC /esuperior def +16#F6ED /isuperior def +16#F6EE /lsuperior def +16#F6EF /msuperior def +16#F6F0 /osuperior def +16#F6F1 /rsuperior def +16#F6F2 /ssuperior def +16#F6F3 /tsuperior def +16#F6F4 /Brevesmall def +16#F6F5 /Caronsmall def +16#F6F6 /Circumflexsmall def +16#F6F7 /Dotaccentsmall def +16#F6F8 /Hungarumlautsmall def +16#F6F9 /Lslashsmall def +16#F6FA /OEsmall def +16#F6FB /Ogoneksmall def +16#F6FC /Ringsmall def +16#F6FD /Scaronsmall def +16#F6FE /Tildesmall def +16#F6FF /Zcaronsmall def +16#F721 /exclamsmall def +16#F724 /dollaroldstyle def +16#F726 /ampersandsmall def +16#F730 /zerooldstyle def +16#F731 /oneoldstyle def +16#F732 /twooldstyle def +16#F733 /threeoldstyle def +16#F734 /fouroldstyle def +16#F735 /fiveoldstyle def +16#F736 /sixoldstyle def +16#F737 /sevenoldstyle def +16#F738 /eightoldstyle def +16#F739 /nineoldstyle def +16#F73F /questionsmall def +16#F760 /Gravesmall def +16#F761 /Asmall def +16#F762 /Bsmall def +16#F763 /Csmall def +16#F764 /Dsmall def +16#F765 /Esmall def +16#F766 /Fsmall def +16#F767 /Gsmall def +16#F768 /Hsmall def +16#F769 /Ismall def +16#F76A /Jsmall def +16#F76B /Ksmall def +16#F76C /Lsmall def +16#F76D /Msmall def +16#F76E /Nsmall def +16#F76F /Osmall def +16#F770 /Psmall def +16#F771 /Qsmall def +16#F772 /Rsmall def +16#F773 /Ssmall def +16#F774 /Tsmall def +16#F775 /Usmall def +16#F776 /Vsmall def +16#F777 /Wsmall def +16#F778 /Xsmall def +16#F779 /Ysmall def +16#F77A /Zsmall def +16#F7A1 /exclamdownsmall def +16#F7A2 /centoldstyle def +16#F7A8 /Dieresissmall def +16#F7AF /Macronsmall def +16#F7B4 /Acutesmall def +16#F7B8 /Cedillasmall def +16#F7BF /questiondownsmall def +16#F7E0 /Agravesmall def +16#F7E1 /Aacutesmall def +16#F7E2 /Acircumflexsmall def +16#F7E3 /Atildesmall def +16#F7E4 /Adieresissmall def +16#F7E5 /Aringsmall def +16#F7E6 /AEsmall def +16#F7E7 /Ccedillasmall def +16#F7E8 /Egravesmall def +16#F7E9 /Eacutesmall def +16#F7EA /Ecircumflexsmall def +16#F7EB /Edieresissmall def +16#F7EC /Igravesmall def +16#F7ED /Iacutesmall def +16#F7EE /Icircumflexsmall def +16#F7EF /Idieresissmall def +16#F7F0 /Ethsmall def +16#F7F1 /Ntildesmall def +16#F7F2 /Ogravesmall def +16#F7F3 /Oacutesmall def +16#F7F4 /Ocircumflexsmall def +16#F7F5 /Otildesmall def +16#F7F6 /Odieresissmall def +16#F7F8 /Oslashsmall def +16#F7F9 /Ugravesmall def +16#F7FA /Uacutesmall def +16#F7FB /Ucircumflexsmall def +16#F7FC /Udieresissmall def +16#F7FD /Yacutesmall def +16#F7FE /Thornsmall def +16#F7FF /Ydieresissmall def +16#F8E5 /radicalex def +16#F8E6 /arrowvertex def +16#F8E7 /arrowhorizex def +16#F8E8 /registersans def +16#F8E9 /copyrightsans def +16#F8EA /trademarksans def +16#F8EB /parenlefttp def +16#F8EC /parenleftex def +16#F8ED /parenleftbt def +16#F8EE /bracketlefttp def +16#F8EF /bracketleftex def +16#F8F0 /bracketleftbt def +16#F8F1 /bracelefttp def +16#F8F2 /braceleftmid def +16#F8F3 /braceleftbt def +16#F8F4 /braceex def +16#F8F5 /integralex def +16#F8F6 /parenrighttp def +16#F8F7 /parenrightex def +16#F8F8 /parenrightbt def +16#F8F9 /bracketrighttp def +16#F8FA /bracketrightex def +16#F8FB /bracketrightbt def +16#F8FC /bracerighttp def +16#F8FD /bracerightmid def +16#F8FE /bracerightbt def +16#FB00 /ff def +16#FB01 /fi def +16#FB02 /fl def +16#FB03 /ffi def +16#FB04 /ffl def +16#FB1F /afii57705 def +16#FB2A /afii57694 def +16#FB2B /afii57695 def +16#FB35 /afii57723 def +16#FB4B /afii57700 def +end +def +10 dict dup begin + /FontType 3 def + /FontMatrix [.001 0 0 .001 0 0 ] def + /FontBBox [0 0 100 100] def + /Encoding 256 array def + 0 1 255 {Encoding exch /.notdef put} for + Encoding 97 /openbox put + /CharProcs 2 dict def + CharProcs begin + /.notdef { } def + /openbox + { newpath + 90 30 moveto 90 670 lineto + 730 670 lineto 730 30 lineto + closepath + 60 setlinewidth + stroke } def + end + /BuildChar + { 1000 0 0 + 0 750 750 + setcachedevice + exch begin + Encoding exch get + CharProcs exch get + end + exec + } def +end +/NoglyphFont exch definefont pop + +/mbshow { % num + 8 array % num array + -1 % num array counter + { + dup 7 ge { exit } if + 1 add % num array counter + 2 index 16#100 mod % num array counter mod + 3 copy put pop % num array counter + 2 index 16#100 idiv % num array counter num + dup 0 le + { + pop exit + } if + 4 -1 roll pop + 3 1 roll + } loop % num array counter + 3 -1 roll pop % array counter + dup 1 add string % array counter string + 0 1 3 index + { % array counter string index + 2 index 1 index sub % array counter string index sid + 4 index 3 2 roll get % array counter string sid byte + 2 index 3 1 roll put % array counter string + } for + show pop pop +} def +/draw_undefined_char +{ + csize /NoglyphFont Msf (a) show +} bind def + +/real_unicodeshow +{ + /ccode exch def + /Unicodedict where { + pop + Unicodedict ccode known { + /cwidth {currentfont /ScaleMatrix get 0 get} def + /cheight cwidth def + gsave + currentpoint translate + cwidth 1056 div cheight 1056 div scale + 2 -2 translate + ccode Unicodedict exch get + cvx exec + grestore + currentpoint exch cwidth add exch moveto + true + } { + false + } ifelse + } { + false + } ifelse +} bind def + +/real_unicodeshow_native +{ + /ccode exch def + /NativeFont where { + pop + NativeFont findfont /FontName get /Courier eq { + false + } { + csize NativeFont Msf + /Unicode2NativeDict where { + pop + Unicode2NativeDict ccode known { + Unicode2NativeDict ccode get show + true + } { + false + } ifelse + } { + false + } ifelse + } ifelse + } { + false + } ifelse +} bind def + +/real_glyph_unicodeshow +{ + /ccode exch def + /UniDict where { + pop + UniDict ccode known { + UniDict ccode get glyphshow + true + } { + false + } ifelse + } { + false + } ifelse +} bind def +/real_unicodeshow_cid +{ + /ccode exch def + /UCS2Font where { + pop + UCS2Font findfont /FontName get /Courier eq { + false + } { + csize UCS2Font Msf + ccode mbshow + true + } ifelse + } { + false + } ifelse +} bind def + +/unicodeshow +{ + /cfont currentfont def + /str exch def + /i 0 def + str length /ls exch def + { + i 1 add ls ge {exit} if + str i get /c1 exch def + str i 1 add get /c2 exch def + /c c2 256 mul c1 add def + c2 1 ge + { + c unicodeshow1 + { + % do nothing + } { + c real_unicodeshow_cid % try CID + { + % do nothing + } { + c unicodeshow2 + { + % do nothing + } { + draw_undefined_char + } ifelse + } ifelse + } ifelse + } { + % ascii + cfont setfont + str i 1 getinterval show + } ifelse + /i i 2 add def + } loop +} bind def + +/u2nadd {Unicode2NativeDict 3 1 roll put} bind def + +/Unicode2NativeDictdef 0 dict def +/default_ls { + /Unicode2NativeDict Unicode2NativeDictdef def + /UCS2Font /Courier def + /NativeFont /Courier def + /unicodeshow1 { real_glyph_unicodeshow } bind def + /unicodeshow2 { real_unicodeshow_native } bind def +} bind def +/Mrect { % x y w h Mrect - + 2 index add + 4 1 roll + 2 index add + 4 1 roll + transform round .1 add exch round .1 add exch itransform + 4 -2 roll + transform round .1 sub exch round .1 sub exch itransform + 2 index sub + 4 1 roll + 2 index sub + 4 1 roll + moveto + dup 0 exch rlineto + exch 0 rlineto + neg 0 exch rlineto + closepath +} bind def +/Msetstrokeadjust /setstrokeadjust where + { pop /setstrokeadjust } { /pop } ifelse + load def + +/Unicode2NativeDictja 0 dict def +/ja_ls { + /NativeFont /Ryumin-Light-EUC-H def + /UCS2Font /Courier def + /Unicode2NativeDict Unicode2NativeDictja def + /unicodeshow1 { real_unicodeshow } bind def + /unicodeshow2 { real_unicodeshow_native } bind def +} bind def +%%EndProlog +%%Page: 1 1 +%%BeginPageSetup +/pagelevel save def +0.05 0.05 scale +90 rotate 0 -11905 translate +true Msetstrokeadjust +%%EndPageSetup + initclip + newpath +0 11905 16838 -11905 Mrect clip + newpath + gsave + gsave +1 1 1 setrgbcolor + grestore + gsave +1 1 1 setrgbcolor + grestore + gsave +1 1 1 setrgbcolor +0 0 0 setrgbcolor + grestore + grestore + gsave + gsave + initclip + newpath +720 11185 15398 -10465 Mrect clip + newpath + gsave + grestore + gsave + gsave + grestore + gsave + grestore + gsave + grestore + grestore + grestore + gsave + initclip + newpath +720 11185 15398 -10465 Mrect clip + newpath + gsave + grestore + gsave + gsave + grestore + gsave + grestore + gsave + grestore +0 0 0 setrgbcolor +default_ls +120 f8 +10495 6988 moveto +(#!/usr/bin/perl -w ) show +0 0 0 setrgbcolor +default_ls +120 f8 +10495 6868 moveto +(use strict;) show +0 0 0 setrgbcolor +default_ls +120 f8 +10495 6748 moveto +( $_='ev) show +0 0 0 setrgbcolor +default_ls +120 f8 +10495 6628 moveto +( al\("seek\\040D) show +0 0 0 setrgbcolor +default_ls +120 f8 +10495 6508 moveto +( ATA,0, 0;"\);foreach\(1..2\)) show +0 0 0 setrgbcolor +default_ls +120 f8 +10495 6388 moveto +( {;}my @camel1hump;my$camel;) show +0 0 0 setrgbcolor +default_ls +120 f8 +10495 6268 moveto +( my$Camel ;while\( \){$_=sprintf\("%-6) show +0 0 0 setrgbcolor +default_ls +120 f8 +10495 6148 moveto +(9s",$_\);my@dromedary 1=split\(//\);if\(defined\($) show +0 0 0 setrgbcolor +default_ls +120 f8 +10495 6028 moveto +(_=\)\){@camel1hum p=split\(//\);}while\(@dromeda) show +0 0 0 setrgbcolor +default_ls +120 f8 +10495 5908 moveto +( ry1\){my$camel1hump=0 ;my$CAMEL=3;if\(defined\($_=shif) show +0 0 0 setrgbcolor +default_ls +120 f8 +10495 5788 moveto +( t\(@dromedary1 \)\)&&/\\S/\){$camel1hump+=1<<$CAMEL;}) show +0 0 0 setrgbcolor +default_ls +120 f8 +10495 5668 moveto +( $CAMEL--;if\(d efined\($_=shift\(@dromedary1\)\)&&/\\S/\){) show +0 0 0 setrgbcolor +default_ls +120 f8 +10495 5548 moveto +( $camel1hump+=1 <<$CAMEL;}$CAMEL--;if\(defined\($_=shift\() show +0 0 0 setrgbcolor +default_ls +120 f8 +10495 5428 moveto +( @camel1hump\)\)&&/\\S/\){$camel1hump+=1<<$CAMEL;}$CAMEL--;if\() show +0 0 0 setrgbcolor +default_ls +120 f8 +10495 5308 moveto +( defined\($_=shift\(@camel1hump\)\)&&/\\S/\){$camel1hump+=1<<$CAME) show +0 0 0 setrgbcolor +default_ls +120 f8 +10495 5188 moveto +( L;;}$camel.=\(split\(//,"\\040..m`{/J\\047\\134}L^7FX"\)\)[$camel1h) show +0 0 0 setrgbcolor +default_ls +120 f8 +10495 5068 moveto +( ump];}$camel.="\\n";}@camel1hump=split\(/\\n/,$camel\);foreach\(@) show +0 0 0 setrgbcolor +default_ls +120 f8 +10495 4948 moveto +( camel1hump\){chomp;$Camel=$_;tr/LJF7\\173\\175`\\047/\\061\\062\\063) show +0 0 0 setrgbcolor +default_ls +120 f8 +10495 4828 moveto +( 45678/;tr/12345678/JL7F\\175\\173\\047`/;$_=reverse;print"$_\\040) show +0 0 0 setrgbcolor +default_ls +120 f8 +10495 4708 moveto +( $Camel\\n";}foreach\(@camel1hump\){chomp;$Camel=$_;y/LJF7\\173\\17) show +0 0 0 setrgbcolor +default_ls +120 f8 +10495 4588 moveto +( 5`\\047/12345678/;tr/12345678/JL7F\\175\\173\\047`/;$_=reverse;p) show +0 0 0 setrgbcolor +default_ls +120 f8 +10495 4468 moveto +( rint"\\040$_$Camel\\n";}#japh-Erudil';;s;\\s*;;g;;eval; eval) show +0 0 0 setrgbcolor +default_ls +120 f8 +10495 4348 moveto +( \("seek\\040DATA,0,0;"\);undef$/;$_=;s$\\s*$$g;\( \);;s) show +0 0 0 setrgbcolor +default_ls +120 f8 +10495 4228 moveto +( ;^.*_;;;map{eval"print\\"$_\\"";}/.{4}/g; __DATA__ \\124) show +0 0 0 setrgbcolor +default_ls +120 f8 +10495 4108 moveto +( \\1 50\\145\\040\\165\\163\\145\\040\\157\\1 46\\040\\1 41\\0) show +0 0 0 setrgbcolor +default_ls +120 f8 +10495 3988 moveto +( 40\\143\\141 \\155\\145\\1 54\\040\\1 51\\155\\ 141) show +0 0 0 setrgbcolor +default_ls +120 f8 +10495 3868 moveto +( \\147\\145\\0 40\\151\\156 \\040\\141 \\163\\16 3\\) show +0 0 0 setrgbcolor +default_ls +120 f8 +10495 3748 moveto +( 157\\143\\ 151\\141\\16 4\\151\\1 57\\156) show +0 0 0 setrgbcolor +default_ls +120 f8 +10495 3628 moveto +( \\040\\167 \\151\\164\\1 50\\040\\ 120\\1) show +0 0 0 setrgbcolor +default_ls +120 f8 +10495 3508 moveto +( 45\\162\\ 154\\040\\15 1\\163\\ 040\\14) show +0 0 0 setrgbcolor +default_ls +120 f8 +10495 3388 moveto +( 1\\040\\1 64\\162\\1 41\\144 \\145\\) show +0 0 0 setrgbcolor +default_ls +120 f8 +10495 3268 moveto +( 155\\14 1\\162\\ 153\\04 0\\157) show +0 0 0 setrgbcolor +default_ls +120 f8 +10495 3148 moveto +( \\146\\ 040\\11 7\\047\\ 122\\1) show +0 0 0 setrgbcolor +default_ls +120 f8 +10495 3028 moveto +( 45\\15 1\\154\\1 54\\171 \\040) show +0 0 0 setrgbcolor +default_ls +120 f8 +10495 2908 moveto +( \\046\\ 012\\101\\16 3\\16) show +0 0 0 setrgbcolor +default_ls +120 f8 +10495 2788 moveto +( 3\\15 7\\143\\15 1\\14) show +0 0 0 setrgbcolor +default_ls +120 f8 +10495 2668 moveto +( 1\\16 4\\145\\163 \\054) show +0 0 0 setrgbcolor +default_ls +120 f8 +10495 2548 moveto +( \\040 \\111\\156\\14 3\\056) show +0 0 0 setrgbcolor +default_ls +120 f8 +10495 2428 moveto +( \\040\\ 125\\163\\145\\14 4\\040\\) show +0 0 0 setrgbcolor +default_ls +120 f8 +10495 2308 moveto +( 167\\1 51\\164\\1 50\\0 40\\160\\) show +0 0 0 setrgbcolor +default_ls +120 f8 +10495 2188 moveto +( 145\\162 \\155\\151) show +0 0 0 setrgbcolor +default_ls +120 f8 +10495 2068 moveto +( \\163\\163 \\151\\1) show +0 0 0 setrgbcolor +default_ls +120 f8 +10495 1948 moveto +( 57\\156\\056) show +0 0 0 setrgbcolor +default_ls +120 f8 +10495 1708 moveto +(# camel code, copyright 2000 by Stephen B. Jenkins) show +0 0 0 setrgbcolor +default_ls +120 f8 +10495 1588 moveto +(# The use of a camel image with the topic of Perl ) show +0 0 0 setrgbcolor +default_ls +120 f8 +10495 1468 moveto +(# is a trademark of O'Reilly & Associates, Inc. ) show +0 0 0 setrgbcolor +default_ls +120 f8 +10495 1348 moveto +(# Used with permission.) show + grestore + grestore + gsave + initclip + newpath +720 11185 15398 -10465 Mrect clip + newpath + gsave +0 0 0 setrgbcolor +default_ls +2200 f4 +1447 9451 moveto +(\043\000\041\000\040\000\057\000\165\000\163\000\162\000\057\000\142\000\151\000\156\000\057\000\160\000\145\000\162\000\154\000) unicodeshow +0 0 0 setrgbcolor +default_ls +224 f4 +1447 8670 moveto +(\040\000) unicodeshow +0 0 0 setrgbcolor +default_ls +800 f4 +1447 8033 moveto +(PVV arrangerer nybegynnerkurs i Perl) show +0 0 0 setrgbcolor +default_ls +224 f4 +1447 7646 moveto +(\040\000) unicodeshow +0 0 0 setrgbcolor +default_ls +224 f4 +1447 7422 moveto +(\040\000) unicodeshow +0 0 0 setrgbcolor +default_ls +224 f4 +1447 7198 moveto +(\040\000) unicodeshow + grestore + gsave + gsave +0 0 0 setrgbcolor +default_ls +320 f4 +1489 6751 moveto +(Tid: ) show +0 0 0 setrgbcolor +default_ls +320 f4 +2385 6751 moveto +(Torsdag 28. oktober, fra 18:00 til 20:00) show + grestore + gsave +0 0 0 setrgbcolor +default_ls +320 f4 +1489 6283 moveto +(\123\000\164\000\145\000\144\000\072\000\040\000) unicodeshow +0 0 0 setrgbcolor +default_ls +320 f4 +2385 6283 moveto +(Auditorium R8, Realfagsbygget) show + grestore + gsave +0 0 0 setrgbcolor +default_ls +320 f4 +1489 5815 moveto +(Pris: ) show +0 0 0 setrgbcolor +default_ls +320 f4 +2385 5815 moveto +(Kr 50 for ikke-medlemmer, gratis for medlemmer ) show +0 0 0 setrgbcolor +default_ls +320 f4 +2385 5415 moveto +(\(medlemsskap koster kr 42\)) show + grestore +0 0 0 setrgbcolor +default_ls +320 f4 +1447 4641 moveto +(\120\000\126\000\126\000\040\000\141\000\162\000\162\000\141\000\156\000\147\000\145\000\162\000\145\000\162\000\040\000\153\000\165\000\162\000\163\000\040\000\146\000\157\000\162\000\040\000\156\000\171\000\142\000\145\000\147\000\171\000\156\000\156\000\145\000\162\000\145\000\040\000\151\000\040\000\160\000\162\000\157\000\147\000\162\000\141\000\155\000\155\000\145\000\162\000\151\000\156\000\147\000\163\000\055\000) unicodeshow +0 0 0 setrgbcolor +default_ls +320 f4 +1447 4241 moveto +(\163\000\160\000\162\000\345\000\153\000\145\000\164\000\040\000\120\000\145\000\162\000\154\000\056\000\040\000\126\000\151\000\040\000\146\000\157\000\153\000\165\000\163\000\145\000\162\000\145\000\162\000\040\000\160\000\345\000\040\000\150\000\166\000\157\000\162\000\144\000\141\000\156\000\040\000\155\000\141\000\156\000\040\000\153\000\141\000\156\000\040\000\154\000\141\000\147\000\145\000\040\000\145\000\156\000\153\000\154\000\145\000) unicodeshow +0 0 0 setrgbcolor +default_ls +320 f4 +1447 3841 moveto +(\163\000\143\000\162\000\151\000\160\000\164\000\054\000\040\000\157\000\147\000\040\000\160\000\345\000\040\000\345\000\040\000\147\000\151\000\040\000\145\000\164\000\040\000\147\000\162\000\165\000\156\000\156\000\154\000\141\000\147\000\040\000\146\000\157\000\162\000\040\000\345\000\040\000\154\000\346\000\162\000\145\000\040\000\163\000\145\000\147\000\040\000\155\000\145\000\162\000\040\000\163\000\145\000\154\000\166\000\056\000) unicodeshow +0 0 0 setrgbcolor +default_ls +320 f4 +1447 3121 moveto +(Kurset forutsetter litt programmeringserfaring, men halve ) show +0 0 0 setrgbcolor +default_ls +320 f4 +1447 2721 moveto +(IT-intro burde holde.) show +0 0 0 setrgbcolor +default_ls +320 f4 +1447 2001 moveto +(Kursholder: Knut Auvor Grythe) show + grestore + grestore + grestore +pagelevel restore +showpage +%%Trailer +%%Pages: 1 +%%EOF