PERL
planning 1 week is 3 lesuren
week 1 installatie PERL
week 2 PERL- robotprog
week 3 Variabelen, Constanten, datatypes een inleiding, scalairen en tekst, tekstfuncties
week 4 operatoren logische expressies
week 5 arrays en arraylussen (foreach) arrayfuncties
week 6 hash en hashlussen (each) hashfuncties
week 7 scope van variabelen, datum en tijdfuncties
week 8 uitvoer van HTML (CGI)
week 9 Eindopdacht HTML formulier afhandelen dat cijfers onder de 100 omzet in letters
31 wordt een en dertig enz.
een week (3 lesuren bestaat uit een inleiding en een workshop)
Het portfolio heet PERL_klas_Achternaam_Voornaam voorvoegsels en wordt op de bekende manier in googledocs gedeeld en bijgehouden. (klas is bv 41b)
in het portfolio komen elke week
de aantekeningen, (samenvatting van de les / reader in eigen woorden) (bron reader / les)
de probeersels en hun uitvoer.
een toelichting op problemen die je bent tegengekomen (evaluatie, bv haakjes vergeten)
de nieuwe begrippen / functies beschreven in eigen woorden (bron reader, http://perldoc.PERL.org/)
de syntaxis van die functies (bron http://perldoc.PERL.org/)
een of meerdere programmavoorbeelden van nieuwe begrippen / functies (uit de editor / uitvoer in cmd)
het is raadzaam hiervoor een vaste structuur (template) te kiezen. (bijlage)
op enig moment zal bij wijze van toets een programma moeten worden gemaakt waarbij alleen het eigen portfolio als referentie mag dienen, niemand verwacht dat je alles uit je hoofd weet. Statements en functies die je vaak gebruikt leer je vanzelf.
Kijk eerst eens even op wikipedia: http://nl.wikipedia.org/wiki/Perl_(programmeertaal)
In periode 1 hebben we kennis gemaakt met programmeren in het programma robotprog
Zoals elke programmeertaal kent PERL de 3 basis bestanddelen; statement, lus en beslissing.
vergelijken we PERL met de robotprog-taal dan herkennen we de volgende dingen
het statement
(turn left, turn right, move forward, mark, erase, reload in robotprog) maar dat zijn er natuurlijk oneindig veel meer in PERL
de beslissingsstructuur
if ($var<=10){doe dit}else{doe dat}
de lus
while($var<=10){doe dit }
for ($var=1;$var<6;$var++){doe dit}
zaken als subroutines, toekenningsstatements, operatoren
het weergeven en inlezen van tekst.
Maar PERL kan meer, afgezien van veel (heel veel) statements, hebben we nog een heel scala van lussen, functies en beslissingsstructuren extra.
Maar dat zal in het begin niet het meeste opvallen.
Zoals al vaker opgemerkt is programmeren een proces dat zich in het hoofd en "op papier" afspeelt.
In het eerste komt geen verschil (nooit meer), maar op het gebied van coderen is veel te verbeteren ten opzichte van robotprog.
PERL-code schrijf je in een editor, als je een goede uitkiest dan heb je gelijk de beschikking over hulpmiddelen als higlighting van commando's en het paren van brackets en quotes.
verder kun je code opslaan in stukjes, onbeperkt kopiëren en plakken.
In robotprog hebben we kennis gemaakt met variabelen, dat is een onderwerp dat we nog veel uitgebreider gaan behandelen.
Maar eerst moeten we PERL aan het lopen hebben
PERL is een programma, een compiler
draai je linux dan hoef je niets te doen, PERL draait al mee, maar voor windhoos moet je even downloaden
http://www.activestate.com/activeperl/
(je kunt gelijk even komodo ophalen dat ie een prima editor, maar notepad++ doet het ook wel)
om te testen draaien we vanaf de commandprompt (cmd) prompt>PERL-e "print 27.35 * 0.825;"
de -e parameter zorgt voor een execute
krijg je de foutmelding:
PERL wordt niet herkend als een interne
of externe opdracht, programma of batchbestand.
dan moet je even het pad aanwijzen: path = C:\PERL\bin of zoiets
in dat geval krijg je 2.256375 en een nieuwe prompt
nb. zorg dat je handig wordt in het kopieren en plakken van en naar de command-shell
eigenschappen>Opties>Modus Snel Bewerken aanvinken,
dan kun je stukken afblokken en met <enter> op het clipboard zetten
de inhoud van het clipboard wordt geplakt in de shell als je op rechts klikt
met het pijltje omhoog kun je bladeren in eerdere commando's
we bekijken het commando:
PERL-e "print 27.35 * 0.825;"
het PERL statement staat tussen de " " en eindigt per definitie met een ;
hoera, we hebben een commandline rekenmachine uitgevonden!
Je zou een programma kunnen maken dat dit zelfde statement bevat, alleen het statement dus geen "" en geen PERL-e!
print 27.35 * 0.825;
Sla dat op als test.pl
Om dit programma te testen draaien we vanaf de commandprompt (cmd) prompt>PERL test.pl
en ziedaar
2.256375 en een nieuwe prompt.
We gaan dit programma uitbreiden met nog wat statements:
bijvoorbeeld
print "\n";
print "hoera\n";
$hoera = 5;
print $hoera."\n";
met als uitvoer:
22.56375
hoera
5
en een nieuwe prompt.
wat is hier gebeurd?
het bijzondere karakter \n betekent newline dat kun je gewoon printen
de regel $hoera = 5; betekent dat een variabele ($hoera) de waarde 5 krijgt
als je die variabele print krijg je de waarde te zien.
je kunt ook rekenen met variabelen
$eerste = 27.35;
$tweede = 0.825;
print $eerste * $tweede;
het resultaat is: 2.256375 en een nieuwe prompt.
opdrachten:
maak een programma dat de volgende uitvoer heeft:
$eerste = 27.35;
$tweede = 0.825;
het product van $eerste en $tweede is 2.256375
de som van $eerste en $tweede is
het verschil van $eerste en $tweede is
het quotiënt van $eerste en $tweede is
problemen die je kunt tegenkomen zijn:
het verschil tussen de variabele-naam en de variabele-waarde weergeven.
probeer het verschil tussen "" en ''
de \ voor de $ zorgt ervoor dat de $ als een letter wordt behandeld en niet als een variabele. (dit heet een literal (= niet variabele) en kan met alle bijzondere karakters (karakters met een betekenis in de taal) gebruikt worden {}!@#$%&*()[] enzovoort)
De shebang bovenin een PERL script wijst de weg naar de compiler.
#!c:\PERL\bin\PERL-w
de -w parameter zorgt ervoor dat het programma wordt gecontroleerd op fouten en je daar ook een melding van krijgt.
Het is dus verstandig om deze regel in elk PERL-programma te zetten hoewel het in windows niet nodig is, het pad en de bestands-associatie staan in het register.
Pragma's
Je kunt ervoor zorgen dat PERL meer of minder vergevingsgezind is ten opzichte van foutjes met pragma's
use strict; de code moet perfect zijn voordat die wordt uitgevoerd, dit lever je af
use warnings; de code wordt uitgevoerd, maar mogelijke fouten worden gemeld, tijdens het ontwikkelen (doet hetzelfde als de -w optie)
Lussen:
we kennen de volgende lussen al for en while, in PERL zien die er als volgt uit:
while($var<=10){doe dit }
$var<=10 betekent kleiner of gelijk aan 10
tussen de {} staan de statements
een van de statements verandert de waarde van $var, bijvoorbeeld door er 1 bij op te tellen ($var = $var + 1, afgekort tot ++ , want we zijn lui) dat betekent dat $var moet worden leeggemaakt voordat de lus begint:
$var = 0;
while($var<=10){
print "hallo \$var = $var\n";
print 'hallo $var = ' . $var . "\n"; # doet hetzelfde, let op de quotes
$var++;
}
met de for lus kunnen we iets soortgelijks doen:
for ($var=1;$var<6;$var++){doe dit}
for ($var=0;$var<11;$var++){
print "hallo \$var = $var\n";
}
wat is dan het verschil?
in een for lus wordt de waarde altijd aan het einde van de lus verhoogd
in een while lus kan dat overal gebeuren en hoeft het niet over getallen te gaan
ook hoeft in een while lus geen regelmaat te zitten
probeer:
$var = 0;
while($var<=10){
$var = int(rand(12));
print "hallo \$var = $var\n";
}
de functies int() en rand() zorgen ervoor dat een willekeurig geheel getal wordt gemaakt,
int(rnd(12)) maakt een geheel getal tussen 0 en 11
de lus eindigt altijd met een 11 (11 > 10) maar is elke keer dat je het programma uitvoer anders.
Je springt doorlopend heen en weer tussen de commandshell, de editor en de reader en
eventueel google die meestal uitkomt bij http://perldoc.PERL.org maar dat went snel.
een op hol geslagen lus:
probeer:
$var = 0;
while($var<10){
$var = int(rand(10));
print "hallo \$var = $var\n";
}
kun je pauzeren met <ctrl>-s, hervatten met <any key> (als je die niet hebt kun je die kopen op http://www.bestel.nl/catalog/any-key-p-878.html)
en aborten met <crtl>-c
Maak een programma dat de volgende uitvoer heeft:
dit is couplet 1
dit is couplet 2
...
dit is couplet 99
begin en end komen natuurlijk ook voor in de vorm van { en } brackets om het hoofdprogramma zijn ze mandatory (vrijwillig) maar rond lussen, subroutines en beslissingen moet het.
subroutines:
een subroutine kan overal in het programma worden gedeclareerd met het keyword (sleutelwoord) sub
voorbeeld:
for($var=1;$var<=10;$var++){
&pruts;
}
sub pruts
{
print "Zomaar wat tekst\n";
}
een subroutine wordt aangeroepen met &naam_van_de-subroutine(parameters);
beslissingsstructuren:
net als in robotprog kun je een keuze maken
dat doe je met het if-statement
for($var=1;$var<=10;$var++){
if($var > 5){ print "\$var is groter dan vijf\n";}
}
of
for($var=1;$var<=10;$var++){
if($var > 5){ print "\$var is groter dan vijf\n";}
else { print "\$var is niet groter dan vijf\n";}
}
Let even op het verschil.
Zo, nu weten we evenveel van PERL als van robotprog.
een speciale variabele is $ARGV[0] de waarde hiervan is een parameter die is meegegeven op de commandline
probeer het programma:
print $ARGV[0];
en voer dat uit met PERL test.pl welkom
kennelijk is $ARG[0] de parameter
maar wat als er meer parameters zijn?
dan blijkt dat die in $ARGV[1] , $ARGV[2] zijn opgeslagen
$ARG[ ] is een voorbeeld van een array, hierover later meer.
$argv[ ] werkt niet hoofd en kleine letters zijn echt iets anders in variabelenamen!
comments en debuggen (outcommenten)
door een # voor een regel te zetten wordt dit een comment, als je grote stukken wilt uitschakelen
kan dat als volgt:
=naam
stuff to be commented out
=cut
Comments zijn een belangrijk onderdeel van een programma.
Programma's worden vaker gelezen door programmeurs dan door compilers!
Programmeurs gebruiken 90% van de tijd 10% van de talen die ze beheersen.
Er zijn altijd meerdere oplossingen mogelijk.
Programmeurs zijn lui en overmoedig, ze denken dat alles makkelijker kan worden opgelost.
Variabelen, Constanten, datatypes een inleiding, scalairen en tekst, tekstfuncties
Enkelvoudige datatypen: en hun ruimtegebruik
Name |
Description |
Size* |
Range* |
---|---|---|---|
char |
ASCII |
1byte |
unsigned: 0 to 255 |
char |
Unicode |
4 bytes |
unsigned: 0 to 4294967295 |
int / byte |
Tiny integer |
1 byte |
signed:
-128 to 128 |
int |
Short Integer. |
2bytes |
signed:
-32768 to 32767 |
int |
Long integer. |
4bytes |
signed:
-2147483648 to 2147483647 |
bool |
Boolean value. It can take one of two values: true or false. |
1byte |
true or false |
float |
Floating point number. |
4bytes |
+/- 3.4e +/- 38 (~7 digits) |
double |
Double precision floating point number. |
8bytes |
+/- 1.7e +/- 308 (~15 digits) |
Tekst types (ascii, unicode) (letters, woorden, tekstblokken, documenten)
Getal types (real, int, byte (unsigned))
Getallen zijn er in soorten en maten, we onderscheiden bijvoorbeeld scalairen(1), vectoren (2), coördinaten(2 of meer) en matrices(2), afhankelijk van het aantal dimensies waarin een waarde zich afspeelt. Referenties of pointers zijn ook scalairen.
Logisch type (true, false)
Datum en tijd types (dd-mm-jjjj hh:mm:ss) zijn text, int of real
Een greep uit mogelijkheden
C
onstanten
zijn 'variabelen' met een vaste waarde, kosten minder geheugen dan de
waarde zelf, omdat ze worden hergebruikt, bovendien zijn ze sneller
toegankelijk omdat ze al in het geheugen aanwezig zijn.
verhogen ook de leesbaarheid van programma's
pi() en exp() zijn voorbeelden
Complexe data types: array, hash, record, file, set, enum.
Arrays kun je je voorstellen als horizontale rijen de elementen worden benaderd door hun nummer:
$array[1] heeft de waarde: Waarde 2 (een array begint bij 0 te tellen en is een scalair)
Om het aantal elementen te tellen kun je een array in scalaire context aanroepen
$elementen = @array
$elementen = scalar(@array)
Hashes lijken meer op kolommen, elementen van een hash hebben een naam en een waarde, die waarde kan ook een referentie of zelfs een heel programma(blok) of subroutine / functie zijn
$hash{Sleutel4} heeft de waarde: Waarde4 (en is een scalair, referentie of programma(blok))
Om het aantal elementen te tellen kun je een hash in scalaire context aanroepen
$aantal = (keys %hash)
$aantal = (values %hash)
een hash kun je afdrukken door: (door het kolomidee kan dat alleen in een lus)
while ( ($key,$value) = each %hash ) {print "$key => $value\n";}
Hashes zijn buitengewoon efficiënt in hun ruimtegebruik, leesbaarheid en snelheid.
Ook het zogenaamde verhashen van variabelen maakt ze geschikt voor het versleutelen van wachtwoorden en dus beveiliging.
Hashes en arrays kunnen ook weer hashes of arrays bevatten en zodoende als meer-dimensionale structuren worden benut.
Een set is een deelverzameling
set (Maandag,Dinsdag,Woensdag,Donderdag,Vrijdag,Zaterdag,Zondag)
set (A,Bb,B,C,C#,D,Eb,E,F,F#,G,G#)
in bijvoorbeeld C++ en MySQL heet dit een ENUM
ENUM('small', 'medium', 'large')
Het zijn eigenlijk arrays, die weinig ruimte innemen. (lagere kardinaliteit)
record
Te vergelijken met een kaartsysteem, in een record zitten variabelen van verschillende types
file
Te vergelijken met een buffer, heeft dezelfde structuur als een file op schijf, maar dan in het geheugen.
Niet alle talen eisen dat je variabelen van tevoren declareert, toch zou je dat altijd moeten doen, het voorkomt veel problemen achteraf.
Niet toegestane variabele-namen : spaties, verboden tekens, cijfers als eerste, taalelementen. In de meeste serieuze talen wordt onderscheid gemaakt tussen hoofd en kleine letters!
Referenties / pointers zijn verwijzingen naar variabelen (of zelfs functies etc)
Je kent referenties al vanuit Excel. Kosten vaak minder ruimte dan de variabele herhalen, en zijn bovenal razendsnel toegankelijk.
samenvatting
In cursus PERL 1 gebruiken we literals, constanten, scalaire variabelen (waaronder booleans), lijstvariabelen (array en hash)
referenties, buffers etc komen later aan bod
Opdrachten:
Maak een programma dat met twee parameters een aantal bewerkingen uitvoert
+-*/
zorg dat het een beetje netjes op het scherm verschijnt.
voeg ruimschoots commentaar toe.
Maak een programma dat de temperatuur in C (als parameter) omrekent in F
(zoek op google hoe dat moet)
Tekstfuncties
Opdracht: Onderzoek van elk van de volgende functies de syntaxis en maak een of meer voorbeelden van de toepassing.
bijzondere karakters:
\a = bell
\n = newline
\t = tab
functies:
concateren . <= hier staat een punt
split()
chop()
chomp()
uc()
lc()
length()
substr()
literals = niet variabelen
'' ,"", q//, qq// en het gebruik van \
probeer de bovenstaande functies uit.
probeer strings op te tellen (+ en . ) en te vermenigvuldigen (x)
$a = "aaaa";
$b = "bbbb";
print $a . $b; resultaat:
print $a + $b; resultaat:
print $a x 3; resultaat:
print $a - $b; resultaat:
print $a / $b; resultaat:
print $a * $b; resultaat:
Formatstrings; definieren hoe een variabele moet worden afgedrukt (een paar voorbeelden)
sprintf
%d geheel getal met teken, in decimaal bv print sprint("%d",$var) rondt $var af op een geheel getal %e wetenschappelijke notatie bv print sprintf("%.2e", $var) geeft $var weer in wetenschappelijke notatie met 2 decimalen %f een kommagetal met een vast aantal decimalen bv print sprint("%.2f",$var) rondt $var af op 2 decimalen
Vlaggen:
spatie rechts aanlijnen + niet negatieve getallen met een + afdrukken - links aanlijnen 0 voorloop nullen gebruiken bij rechts aanlijen
Unicode en UTF-8 of UTF-16
probeer:
$var = -123,456789;
print "geheel = ";
print sprintf("%d", $var);
print "\n";
print "fixed(2) = ";
print sprintf("%.2f", $var);
print "\n";
print "wetenschappelijk = ";
print sprintf("%.2e", $var);
print "\n";
print "8 voorloop nullen= ";
print sprintf("%08d", $var);
print "\n";
Opdracht:
gegeven de volgende string:
nul,een,twee,drie,vier,vijf,zes,zeven,acht,negen,tien,elf, twaalf,dertien,veertien,vijftien
plaats deze string in een variabele met de naam $tellen
splits de string op de komma's en stop die in de array @string
zet de string om naar hoofdletters
bepaal de lengte
druk zeven,acht af als deelstring
voeg de string zestien,zeventien,achttien,negentien,twintig toe.
operatoren logische expressies
(+, -, *, /, div, mod, ^ of **,++, --, x)
Operatoren zijn gekoppeld aan datatypes, bijvoorbeeld bij teksten betekent + dat de strings aan elkaar geregen worden (concateren), bij integers en reals is het een optelling.
Bij booleans leiden deze operatoren tot een foutmelding.
Intergers delen kan met div en mod het resultaat is dan ook een integer.
Reals delen doe je met / als je intergers deelt met een / dan is het resultaat een real.
Dat lijkt raar, maar stel je maar eens voor dat je datums van elkaar aftrekt, het resultaat is dan een aantal dagen en niet een nieuwe datum
binaire getallen kun je ook nog shiften naar links shiften komt overeen met 2*
strings vermenigvuldigen is de string herhalen ("_" x 3 = ____)
Vergelijking, toekenning, verwerkingsvolgorde
= toekenning (wordt of moet worden) of == vergelijking (is gelijk aan ?)
Andere toekenningsoperatoren kunnen zijn => en -> voor hash en array waarden.
string vergelijkingsoperatoren zijn: eq, lt, gt , le, ge, cmp
numerieke vergelijkingsoperatoren zijn: ==, <, >, <=, >=, <=>
booleaanse vergelijkingsongsoperatoren zijn: AND, OR, NOT, &&, ||, !=
Niet elke compiler / interpreter past automatisch meneer van Dalen toe. Bovendien gelden bij logische operatoren zelfs nog verschillende regels voor && en AND. Werk veel met haakjes om de juiste volgorde af te dwingen, dat geeft ook structuur aan je algoritmen. Er zit wel een beetje meneer van Dalen in, maar er wordt van links naar rechts gewerkt (/ en * zijn gelijkwaardig)
Bv: 16/2x4 = 16/8 = 2 (want eerst vermenigvuldigen en dan pas delen)
Wordt op de computer: 16/2*4 = 8*4 = 32 (van links naar rechts afwerken)
Wil je dat goed doen dan moet de formule als volgt:
16/(2*4) = 16/8 = 2
probeer dat
Opdracht: Onderzoek van elk van de volgende functies de syntaxis en maak een of meer voorbeelden van de toepassing.
if
else
elsif
unless
while
until
for
Opdrachten:
Maak een programma dat van twee numerieke parameters bepaald wat de grootste is
als er geen of verkeerde parameters worden ingevoerd moet de fout gemeld worden
als de paramater een ? is dan moet het programma uitleggen hoe het werkt
Idem, maar nu met twee woorden en bepalen welke het langste is
Maak een programma dat van twee numerieke parameters met div en mod een deling maakt
arrays en arraylussen (foreach) arrayfuncties
arrays zijn lijsten, het zal even wennen zijn maar net als in het echte leven maakt Perl onderscheid tussen de lijst en de inhoud.
Stel je een boodschappenlijst voor. (iedereen heeft nu een verschillend lijstje in zijn hoofd.)
een slordig papiertje met daarop shag, toetjes en knabbels.
of een gedetailleerd lijstje met daarop 3 drum halfzwaar met vloei, mona bulgaarse yoghurt, en lays naturel chips 450 gram.
er kan zelfs een leeg papiertje bijzitten.
een lijst ziet er in Perl als volgt uit.
@boodschappen = ("shag","toetje","knabbels");
De @ geeft aan dat het om een array gaat
maar de elementen van de array zijn scalairen, in dit geval tekst.
$boodschappen[0] is shag
$boodschappen[1] is toetje
$boodschappen[2] is knabbels
merk op dat de teller bij 0 begint
Opdracht: Onderzoek van elk van de volgende functies de syntaxis en maak een of meer voorbeelden van de toepassing.
scalar() geeft het aantal elementen van een array weer syntaxis scalar(@array)
foreach loopt alle elementen van een array door. syntaxis foreach $scalair(@array){ doe iets }
push() voegt een element aan een array toe(achteraan). syntaxis push(@array,"nieuw element")
pop() knipt het laatste element van een array. syntaxis pop(@array) het geknipte element kan worden bewaard in een scalair: $laatste = pop(@boodschappen);
shift() knipt het eerste element van een array. syntaxis shift(@array)
unshift() voegt een element aan de array toe (vooraan)
splice() kan elementen toevoegen en verwijderen op elke plaats in een array
met splice kan je dus ook push, pop, shift en unshift uitvoeren
push(@array,"nieuw element") splice(@array,@a,0,"nieuw element") pop(@array) splice(@array,-1) shift(@array) splice(@array,0,1) unshift(@array,"nieuw element") splice(@array,0,0,"nieuw element") syntaxis unshift(@array,plaats,aantal, toevoegingen) aantal kan negatief zijn dan wordt van achteraf geteld split() splitst een string op de aangegeven delimiters en slaat die op in een array syntaxis @array = split("delimiter",$string)
probeer:
@boodschappen = ("shag","toetje","knabbels");
print @boodschappen;
print "\n";
print $boodschappen[1];
print "\n";
foreach $boodschap (@boodschappen) {
print $boodschap;
print "\n";
}
print $#boodschappen;
print "\n";
print scalar(@boodschappen);
print "\n";
push(@boodschappen, "melk");
print @boodschappen;
print "\n";
print scalar(@boodschappen);
print "\n";
$laatste = pop(@boodschappen);
print @boodschappen;
print "\n";
print $laatste;
print "\n";
print scalar(@boodschappen);
print "\n";
Maak een programma dat
met de array @boodschappen = ("shag","toetje","knabbels");
telt hoeveel elementen en nu zijn, de lijst afdrukt
melk toevoegt aan het eind, telt hoeveel elementen en nu zijn, de lijst afdrukt
shag verwijdert, telt hoeveel elementen en nu zijn, de lijst afdrukt
toetje vervangt door vla, telt hoeveel elementen en nu zijn, de lijst afdrukt
qq/bier cola brood/; toevoegt, telt hoeveel elementen en nu zijn, de lijst afdrukt
maak een programma dat de volgende tabel maakt
0 1 2 3 4 5 6 7 8 9 10
10 11 12 13 14 15 16 17 18 19 20
20 21 22 23 24 25 26 27 28 29 30
30 31 32 33 34 35 36 37 38 39 40
40 41 42 43 44 45 46 47 48 49 50
50 51 52 53 54 55 56 57 58 59 60
60 61 62 63 64 65 66 67 68 69 70
70 71 72 73 74 75 76 77 78 79 80
80 81 82 83 84 85 86 87 88 89 90
90 91 92 93 94 95 96 97 98 99 100
gebruik geneste lussen en een formatstring
lussen inlezen kan op heel veel manieren, gelukkig, want gegevens komen in alle soorten en maten binnen
tekstbestanden in TXT, CSV, met verschillende lijstscheidingstekens zijn dagelijkse praktijk
stop de volgende reeksen in een array (zorg dat je de opdrachten goed begrijpt)
a) maandag dinsdag woensdag donderdag vrijdag zaterdag zondag
b) januari,februari,maart, april,mei,juni,juli,augustus,september,oktober,november,december
c) herfst
lente
zomer
winter
d) morgen middag avond nacht
e) PERL;C++;Pascal;Delphi;Java
f) "Printer","Scanner","Toetsenbord","Monitor","Muis","USB-stick"
g) 000102030405060708091011121314151617181920
hash en hashlussen (each) hashfuncties
Opdracht: Onderzoek van elk van de volgende functies de syntaxis en maak een of meer voorbeelden van de toepassing.
each
grep
keys
values
sort
probeer:
%munten = ("cent",1,"stuiver",5,"dubbeltje",10, "kwartje",25,"piek",100,"riks",250);
print "Bijvoorbeeld een stuiver is $munten{'stuiver'} cent waard\n";
while (($sleutel, $waarde) = each(%munten)){
print $sleutel.", ".$waarde."\n";
}
heeft als uitvoer:
Bijvoorbeeld een stuiver is 5 cent waard
stuiver, 5
riks, 250
piek, 100
kwartje, 25
cent, 1
dubbeltje, 10
merk op dat de volgorde anders is dan de declaratie, het is mogelijk dat een volgende keer weer een andere volgorde verschijnt! Hashes worden bewaard op de voor de computer meest gunstige manier.
daarom is sorteren ook bij hashes toegevoegd
voeg toe:
print "\n";
print "alfabetisch:\n";
foreach $sleutel (sort keys %munten) {
print "$sleutel: $munten{$sleutel}\n";
}
nu is de boel alfabetisch gerangschikt.
voeg toe:
print "\n";
print "op waarde:\n";
foreach $sleutel (sort {$munten{$a} <=> $munten{$b};} (keys(%munten))) {
print "$munten{$sleutel} : $sleutel\n";
}
of op waarde
Omdat de volgorde waarin een hash wordt opgeslagen aan de computer is heeft de hash dus geen voor en achterkant, array-functies zijn dus zinloos.
Daar staat tegenover dat er die razendsnelle sort en grep functies zijn.
elementen toevoegen, hashes samenvoegen etc. zijn vrij eenvoudig.
%nieuwe_hash (%hash1,%hash2)
$munten{"joet"} = 10000;
scope van variabelen
variabelen hoeven niet altijd in het hele programma beschikbaar te zijn, sterker nog het kan problemen opleveren.
Als je met meer mensen aan een programma werkt kan het voorkomen dat iemand anders een variabele met dezelfde naam verzint.
Ook als je bibliotheken gebruikt kan dit zich voordoen.
Zorg er dus voor dat variabelen alleen geldig zijn waar ze door jou gebruikt worden.
dit kun je doen door my te gebruiken.
als je in een subroutine een variabele nodig hebt geef die dan mee in de aanroep van de subroutine, dan kun je de variabele binnen de subroutine met een eigen "lokale" naam gebruiken.
het doorgeven van variabelen naar een subroutine is net zoiets als commandline parameters, ze worden in een array gestopt die @_ heet het eerste argument is $_[0]
my $klooivariabele = 20;
$globalevariabele = "shit";
&mijnsubje("hallo", "hoera");
sub mijnsubje{
print $_[0]." ".$_[1].">>>>>".$klooivariabele."<<<<<".$globalevariabele;
}
Perl kan veel beter ongebruikte variabelen opruimen (garbage collection) en dus geheugen vrijmaken als je niet onnodig globale variabelen gebruikt.
datum en tijd functies
Datum en tijd zijn op computers een bron van ellende, dat komt door een aantal dingen
datum en tijd zijn niet tientallig
datum en tijd zijn mengsels van tekst en getallen
datum en tijd worden internationaal niet gelijk weergegeven
datum en tijd worden door verschillende besturingssystemen verschillend behandeld
Opdracht: zoek en beschrijf van alle 4 voorbeelden en geef aan wat het probleem is.
print time(); #het aantal seconden sinds tijdstip 0 verschilt per besturingssysteem
(linux en windhoos 1-1-1970 0:00, apple 1-1-1904 0:00, maar 1-1-1900 0:0 komt ook voor)
print "\n";
print localtime(time); # een array met informatie, hier gmt+1
print "\n";
print gmtime(time); # GMT greenwich mean time
Echt mooi werken met datums en tijden vereist PERL modules (dat zijn bibliotheken met functies en routines)
een paar eenvoudige bewerkingen kunnen wel:
($sec,$min,$uur,$maanddag,$maand,$jaar,$weekdag,$jaardag,$zomertijd) = localtime(time);
# prutst de array localtime in losse variabelen, heel handig dat de telling verkeerd loopt (maand 1 is 0) dan kun je een array zonder problemen gebruiken
@maandnaam = qw( Jan Feb Mrt Apr Mei Jun Jul Aug Sep Okt Nov Dec );
print "$maandnaam[$maand]";
Opdracht:
zoek uit:
wat er met $jaar aan de hand is maak daar een oplossing voor.
wat doet $weekdag, maak daar een toepassing voor.
wat doet $jaardag, maak een toepassing die weeknummers uitrekent
wat doet $zomertijd?
maak een programma dat uitrekent hoeveel dagen, uren, minuten je geleefd hebt
maak een programma dat uitrekent hoe lang het duurt tot je verjaardag (in nachtjes slapen)
Eindopdracht
geef een .pl script eventueel de extensie .cgi en je kunt het door apache laten uitvoeren net als PHP
als apache dat toestaat, anders moet je dat even aapassen, het is niet nodig altijd de cgi-bin te gebruiken, elke directory kan worden ingesteld om cgi of pl uit te voeren
http.conf aanpassen in wamp zie: (in xampp zal het ook wel zo gaan)
http://www.chromicdesign.com/2009/05/setting-up-PERL-for-wampp.html
er moet een header aanzitten voor het http-protocol die ziet er altijd zo uit:
print "content-type: text/html\n\n";
de formuliervariabelen komen binnen als een hash, dat stukje code krijg je cadeau (pas de shebang aan) :
#!i:\wamp\PERL\bin\perl-w
use strict;
# splits de input hash in de naam en de waarde
($getal, $value) = split (/=/, $ENV{'QUERY_STRING'});
print "content-type: text/html\n\n";
print "
<!DOCTYPE HTML PUBLIC '-//W3C//DTD HTML 4.01 Transitional//EN'>
<html>
<head>
<title></title>
</head>
<body>";
print "$value wordt: ";
# hier komt het programma en de uitvoer
print "
</body>
</html>";
nu kun je net als php werken, maar PERL is veel krachtiger
$value is de waarde die in de $getal (naam van de inputvariabele in de html getal dus) zit
<html>
<body>
<form action = 'tekst.cgi' method = 'GET'>
<input text name = 'getal' width = '6'>
<input type = 'submit' value = 'text'>
</form>
</body>
</html>
het cgi bestand heet tekst.cgi en moet in dezelfde dir staan als de html
als voorbeeld kun je ook de volgende code gebruiken, hier zit een werkend script achter, maar je ziet alleen de uitvoer.....
<html>
<body>
<form action = 'http://www.goudappel.org/tekst.cgi' method = 'GET'>
<input text name = 'getal' width = '6'>
<input type = 'submit' value = 'text'>
</form>
</body>
</html>
als een cgi-script faalt dan krijg je een melding in de browser, als je wilt weten wat er is misgegaan kijk dan in de apache-error.log daar staan de foutmeldingen van PERL die zijn meestal duidelijker.
In de volgende periode gaan we werken met
bestanden,
pragma's,
PERL-modules (.pm, CPAN)
liberary's
functies maken
reguliere expressies
Bijlage template functies, één functie per blad.
Naam: join
Syntaxis: join uitdrukking, lijst;
Uitleg:
Join voegt de losse elementen van een lijst samen met tussen de elementen het scheidingsteken (de string) dat in uitdrukking is aangegeven en stopt die in een nieuwe scalaire variabele.
lijst kan bestaan uit literals, $scalairen of een @array.
Join doet vrijwel het tegenovergestelde van split.
Voorbeelden:
$tel = join ";", eerste,tweede,derde,vierde,vijfde;
print $tel;
Output:
eerste;tweede;derde;vierde;vijfde
$een = "januari";
$twee = "februari";
$drie = "maart";
$vier = "april";
$maand = join "\t\t", $een,$twee,$drie,$vier;
print $maand;
Output:
januari februari maart april
@test = ("bier","wijn","jenever","melk","sinas");
$drank = join " en ", @test;
print $drank;
Output:
bier en wijn en jenever en melk en sinas
Bronnen:
http://perldoc.perl.org/functions/join.html