Start to program – De anatomie van een computerprogramma

print

Inhoud


Wat vooraf ging

Via computationeel denken hebt u inzicht in het te programmeren probleem en hebt u reeds oplossingen (algoritmen) uitgewerkt.

U bent ook op de hoogte dat er ontwerptechnieken en programmeerprincipes zijn.

Maar u kunt nog geen bit programmeren, tijd dat we daaraan beginnen.


Hoe gaan we te werk?

We gaan leren programmeren en ik voorzie hiervoor 3 posts.

  1. In deze post ga ik het hebben over de basisonderdelen van een programmeertaal.
  2. Het verloop van een computerprogramma (de control flow) is voor de volgende post.
  3. In een derde en laatste post ga ik het hebben over meer complexe structuren zoals lijsten, objecten en databanken.

Het is niet de bedoeling om een specifieke programmeertaal aan te leren. Er zijn immers honderden programmeertalen met elk hun eigen specifieke syntax. Al deze programmeertalen hebben echter een aantal zaken gemeenschappelijk. Ze gebruiken allemaal variabelen, kennen functies (ook al noemen ze het misschien anders (procedures, subroutines, modules,…), gebruiken lijsten (ook al noemen ze het misschien geen lijst maar een array),…

Het is de bedoeling een inzicht te krijgen in de, algemeen voorkomende, onderdelen waaruit een programmeertaal is opgebouwd.

Het mag echter geen theoretische benadering worden. programmeercode moet immers kunnen getypt worden, uitgetest. Dus moest ik op zoek naar een omgeving, die eenvoudig is, toegankelijk en ideaal om een programmeertaal aan te leren. Ik heb geopteerd voor code.org. Code.org is een professioneel Amerikaans initiatief om jongeren (van 7 tot 77 zoals dat heet) aan het programmeren te helpen.

Code.org biedt een aantal eenvoudige programmeeromgevingen, ideaal om te testen.

  • Een App lab, voor het programmeren van mobiele apps.
  • Een Game lab, voor het programmeren van eenvoudige spelletjes (nog in beta op het ogenblik van dit typen).

Werken met App lab heeft een aantal voordelen:

  • Snel resultaat. App lab is heel visueel en u ziet snel het resultaat van uw code op het scherm.
  • Code blocks. U kunt leren programmeren met zogenaamde code blocks, een visuele manier van programmeren waarbij u geen code typt. Verkiest u echter meteen “echte” programmeercode dan kan dit ook. De keuze is aan u.
  • Javascript. De gebruikte programmeertaal is, een afgeleide van, Javascript. Een heel populaire programmeertaal.
  • Visueel interactief ontwerpen. Het ontwerpen van uw app kan eenvoudig, op een visuele interactieve manier door objecten te slepen op het scherm.
  • Een databank ter beschikking. App lab ondersteunt een achterliggende (back end) databank. U kunt er dus volwaardige apps mee ontwerpen die tevens gegevens opslaan.
  • Delen. U kunt uw app meteen, en eenvoudig, delen via sociale media.

De aanvullende programmeercode ga ik eveneens aanbieden in Javascript. Javascript lijkt qua syntax goed op Java en C#, dus eigenlijk maakt u ook al meteen kennis met deze programmeertalen.

Zo, log u in op App lab (eventueel Game lab) en we kunnen beginnen met te leren programmeren.

Code.org biedt een heel visuele benadering, met heel veel goede filmpjes, om te leren programmeren. Ik ga dan ook intens gebruik maken van deze filmpjes.


Statements

  • Een computerprogramma is een lijst van instructies die moeten worden uitgevoerd door een computer.
  • In een programmeertaal spreken we niet van een instructie maar van een statement.
  • Statements worden meestal gescheiden door een scheidingsteken. Vaak een puntkomma. Javascript gebruikt ook een puntkomma als scheidingsteken (maar verplicht het niet indien de statements op verschillende lijnen staan).
  • Sommige programmeertalen zijn hoofdlettergevoelig, anderen niet. Javascript is hoofdlettergevoelig.

Een voorbeeld van een statement in Javascript is:

window.alert("Hello, world!");

dit statement zal een boodschappenvenster weergeven met de tekst “Hello, world”.

Laten we dit statement eens wat verder ontleden. Het statement bestaat op zich uit volgende delen:

Object.Functie(parameters);

  • window is het object. Het is het object window dat de statement alert() bevat dat kan gebruikt worden om een boodschappenvenster met een bijhorende boodschap weer te geven. Javascript is dan ook object georiënteerd.
  • alert() is een functie (of een methode om de correcte objectgeoriënteerde benaming te gebruiken). Een methode is iets dat het object kan doen, of dat kan gedaan worden op/met het object. In dit geval zal het object window met de methode alert() een boodschappenvenster weergeven.
  • Een functie heeft vaak waarden nodig waarmee de functie zijn ding doet. In dit geval zal de functie alert() een boodschappenvenster weergeven. De boodschap die moet worden weergegeven wordt als parameter/argument meegegeven aan de functie. In dit geval wordt de tekstwaarde “Hello, world!” als parameter/argument meegegeven aan de functie alert().
  • Merk op dat tekst wordt weergegeven tussen “” (quotes). Javascript kent zowel het gebruik van dubbele quotes “” als van enkel quotes ” om tekst te markeren, ze mogen evenwel niet door mekaar gebruikt worden (C# kent enkel de dubbele quotes).
  • Het statement wordt beëindigd met een puntkomma.

Opmerking

Het weergeven van boodschappenvenster is niet aan te raden in een browseromgeving en het wordt ook niet ondersteunt in App lab. We gaan deze slechte gewoonte dus vanaf nu achterwege laten. App lab gebruikt het statement:

write()

Dit is geen officieel javascript-statement, het is een eigen functie binnen App lab. Omdat we met App lab werken en het een eenvoudige functie is gaan we er wel gebruik van maken. De code voor App lab wordt dus:

write("Hello, world!");

Block statements

Een Block statement wordt gebruikt om statements te groeperen. De statements worden gegroepeerd binnen {}.

{
  statement_1;
  statement_2;
  .
  .
  .
  statement_n;
}

Commentaar

Niet iedere regel die u intypt hoeft een statement te zijn.

Meer zelfs, het is belangrijk dat u uw programmeercode documenteert met uitgebreide commentaar, zowel voor uzelf als voor anderen die uw programmeercode eventueel dienen te onderhouden.

Deze commentaar wordt door de compiler/interpreter genegeerd en niet omgezet in machinetaal. Commentaar vormt dus geen extra belasting (vertraging) voor het uiteindelijke programma, het helpt u gewoon uw programmeercode overzichtelijker te houden.

Commentaar op 1 regel

Typ // en al wat volgt tot het einde van de regel wordt als commentaar beschouwd. U kunt // aan het begin van een regel of achter een statement plaatsen.

//Dit is commentaar
write("Hello, world!"); //Deze commentaar staat achter een statement

Commentaar op meerdere regels

U kunt ook commentaar spreiden over meerdere regels. U begint de commentaar op meerdere regels met /* en beëindigt de commentaar met */.

/*
Deze commentaar
Staat
Op meerdere
regels.
*/

Over bits en bytes

Elektronica is in zijn essentie een verhaal van: er is stroom of er is geen stroom. Er zijn maar 2 mogelijkheden. We spreken van een binair (of tweetallig/tweeledig) stelsel.

De computer kent in zijn essentie dus ook enkel de binaire waarden 0 en 1 (aan of uit, stroom of geen stroom, een puntje gebrand op de CD of niet, …). Alle data die opgeslagen is, alle informatie die doorgestuurd wordt, is dus in zijn essentie een stroom van 0-en en 1-en.

Een 0 of een 1 wordt een bit genoemd. Een verzameling van 8 bits wordt een byte genoemd.

Waarden worden gecombineerd in een veelvoud van 8 bits m.a.w. in een veelvoud van bytes.

Bijvoorbeeld, het getal 13 wordt als volgt opgeslagen: 00001101

Hoe komen we nu aan die 00001101?

Wel, bekijk onderstaande tabel van rechts naar links. Op de tweede rij ziet u machten van 2. Waarom 2? Wel, omdat, zoals we net gezien hebben, de computer maar 2 waarden kent 0 en 1.

De machten van 2 zijn:

2^0 = 1
2^1 = 2
2^2 = 2 x 2 = 4
2^3 = 2 x 2 x 2 = 8
2^4 = 2 x 2 x 2x 2 = 16
2^5 = 2 x 2 x 2 x 2 x 2 = 32
2^6 = 2 x 2 x 2 x 2 x 2 x 2 = 64
2^7 = 2 x 2 x 2 x 2 x 2 x 2 x 2 = 128

0 0 0 0 1 1 0 1
128 64 32 16 8 4 2 1

Om nu aan de waarde 13 te komen moeten we (1 x 8) + (1 x 4) + (1 x 1) optellen. Dit is de enige combinatie die 13 als resultaat levert. We zetten dus een 1 bij de overeenkomende waarden van 8, 4 en 1 en laten op de andere posities de waarde 0 staan. Dit levert dus 00001101 op als binaire waarde voor het getal 13.

Als we getallen opslaan in een combinatie van maximaal 8 bits zullen we enkel de getallen van 0 (00000000) tot en met 255 (11111111) kunnen opslaan, of een totaal van 256 waarden.

Getallen hoger dan 255

Willen we grotere getallen dan 255 opslaan dan zullen we een veelvoud van 8 bits (een byte) moeten gebruiken. Door bv. 16 bits (2 bytes) te voorzien kunnen we getallen tussen 0 en 65535 (2^16) opslaan.

Negatieve getallen

Willen we negatieve getallen opslaan dan wordt de meest linkse bit gebruikt om het teken (0 voor – en 1 voor +) op te slaan. Mits we dus 1 bit “kwijt” zijn voor het teken betekent dit dat we 1 bit minder hebben voor het eigenlijke getal. We behouden wel de 256 combinaties.

Voorzien we 8 bits en gebruiken we de meest linkse bit om het teken bij te houden dan zullen de getallen die we kunnen opslaan liggen tussen -128 tot 127.

Decimale getallen

Om decimale getallen op te slaan moet ook de positie van de komma opgeslagen worden in de beschikbare bits.

Tekens

Tekens worden ook opgeslagen als een combinatie van bits. Welk teken met welke combinatie overeenkomt is vastgelegd in tabellen, bv. de ASCII tabel.

Bv. A = 65 = 1000001

Een A wordt dus opgeslagen als 1000001.

Omdat de ASCII-tabel slechts 7 bits gebruikt om tekens op te slaan zijn er maar 128 (27) combinaties mogelijk.

Er zijn dus andere karaktersets nodig die meer dan 128 tekens kunnen opnemen. HTML, JavaScript, PHP, ASP,… maken gebruik van Unicode. De eerste 128 tekens uit de Unicode-karakterset zijn dezelfde als de 128 tekens uit de ANSI-tabel.

Afbeeldingen, muziek,…

Ook afbeeldingen, muziek,… worden elk op hun eigen specifieke manier opgeslagen als een combinatie van 0-en en 1-en.

Zo worden afbeeldingen bv. opgeslagen als een combinatie van punten, waarbij ieder punt uit 32bits bestaat. 8 bits voor Rood, 8 bits voor Groen, 8 bits voor Blauw en 8 bits voor andere informatie als bv. de transparantie.

In onderstaande video legt de oprichter van Instagram uit hoe afbeeldingen opgeslagen worden als bits en hoe filters worden toegepast op afbeeldingen door een berekening uit te voeren op deze bits.


Datatypes

Het datatype is het specifieke type van de data/waarde. Het datatype bepaalt ook hoeveel bytes een waarde van dat type inneemt in het geheugen.

JavaScript kent slechts 3 elementaire datatypen:

  • Number: getallen zoals 65 of 65.0
  • String: tekst weergegeven tussen quotes zoals “Dit is tekst” of ‘Dit is tekst’.
  • Boolean: true of false.

JavaScript kent zo’n beperkt aantal elementaire datatypen omdat het geen onderscheid maakt tussen getallen. Alle getallen, zowel integers als decimale getallen worden als 64-bits (8 bytes) floating point getallen opgeslagen.

Bij wijze van uitzondering geef ik hieronder ook de tabel met de datatypes die kunnen gebruikt worden in C#. U zal opmerken dat deze veel uitgebreider is.

C#Bytes in het geheugenWaardenSuffix
BooleanAfhankelijk van het gebruikte platformTrue of False.
Byte1 byte0 tot 255 (unsigned)
Char2 bytes0 tot 65535 (unsigned)
Int16 (short)2 bytes-32.768 tot 32.767
Int32 (int)4 bytes-2.147.483.648 tot 2.147.483.647
Int64 (long)8 bytes -9.223.372.036,854.775,808 tot 9.223.372.036.854.775.807L of l
Single (float)4 bytes-3,4028235E+38 tot -1,401298E-45 voor negatieve waarden
1,401298E-45 tot 3,4028235E+38 voor positieve waarden
F of f
Double8 bytes-1,79769313486231570E+308 tot
-4,94065645841246544E-324 voor negatieve waarden
4,94065645841246544E-324 tot 1,79769313486231570E+308 voor positieve waarden
D of d
Decimal16 bytes 0 tot +/-79.228.162.514.264.337.593.543.950.335 zonder decimaal teken.
0 tot +/-7,9228162514264337593543950335 met 28 cijfers na het decimaal teken.
M of m
StringAfhankelijk van het gebruikte platform 0 tot ongeveer 2 miljard tekens.
Object4 bytesKan elke willekeurige waarde bevatten
UInt16 (ushort)2 bytes0 tot 65.535
UInt32 (uint)4 bytes0 tot 4.294.967.295U of u
UInt64 (ulong)8 bytes0 tot 18.446.744.073.709.551.615UL of ul

Programmeertalen waar het exacte datatype moet worden geduid worden strongly typed programmeertalen genoemd. Programmeertalen waar deze duiding niet verplicht is maar optioneel worden weakly/loosly typed genoemd.

  • Strongly typed programmeertalen zijn exacter, vragen meer werk/aandacht (bv. door de noodzaak om zelf de conversie van het ene type naar het andere te programmeren) tijdens het typen maar zullen ook rapper fouten ontdekken en weergeven.
  • Weakly/loosly typed programmeertalen zijn losser, minder streng, bij het typen van de programmeertaal. De programmeertaal neemt zelf de conversie voor zijn rekening. Deze lossere aanpak is gemakkelijker voor de beginnende programmeur maar kan ook potentiële fouten langer verbergen.

Javascrypt is weakly/loosly typed (in C# kunt u strongly typed als weakly typed werken).


Variabelen

In voorgaande post heb ik onderstaande “definitie” gebruikt voor het begrip variabele.

Een variabele is een voorbehouden locatie in het computergeheugen waar u een waarde kunt bijhouden/stokkeren voor later hergebruik. De variabele heeft een naam en is vaak van een specifiek type. Het type bepaalt het aantal bytes dat gereserveerd wordt in het computergeheugen voor deze variabele en de naam van de variabele wordt gebruikt om toegang te krijgen tot deze locatie in het computergeheugen. De waarde die wordt bijhouden in die locatie, en waar de variabele naar verwijst, kan in de loop van het programma variëren/wijzigen.

Laten we dit nu even meer in detail bekijken en wat uitbreiden en duiden:

  • Een variabele is een voorbehouden locatie in het computergeheugen waar u een waarde kunt bijhouden/stokkeren voor later hergebruik.
  • Zoals u wellicht weet is het computergeheugen vluchtig. Dit wil zeggen dat het wordt leeggemaakt als u uw computer uitschakelt. Dit betekent dat de variabelen, die zich in het computergeheugen, en niet op een schijf, bevinden, eveneens hun gewijzigde waarde zullen verliezen. De wijzigingen zijn dus niet blijvend.
  • De variabele heeft een naam (identifier). De naam van de variabele wordt gebruikt om toegang te krijgen tot deze locatie in het computergeheugen.
  • De variabele is vaak van een specifiek datatype. Het datatype bepaalt het aantal bytes dat gereserveerd wordt in het computergeheugen voor deze variabele en bepaalt ook welk soort/type data de variabele kan bevatten (int16, string, decimal,…).
  • De waarden die opgeslagen worden in variabelen kunnen in de loop van het programma variëren, ze zijn dus variabel.
  • Het bereik van een variabele wordt bepaald (en beperkt door) de {…} waarbinnen de variabele is gedeclareerd. Buiten de {…} waarbinnen de variabele is gedeclareerd is deze variabele niet gekend en dus ook niet toegankelijk.
  • Een variabele moet binnen hetzelfde bereik uniek zijn. Dezelfde naam mag dus binnen hetzelfde bereik geen tweede keer hergebruikt worden voor een tweede variabele.

Declaratie van variabelen

Voor u een variabele kunt gebruiken moet u een variabele declareren, als het ware een plek reserveren voor de variabele in het geheugen van de computer.

Dit gebeurt door het datatype te bepalen en een naam te kiezen voor de variabele. De naam wordt ook wel Identifier genoemd. De declaratie wordt afgesloten met het scheidingsteken puntkomma.

Bij een Strongly typed programmeertaal zal dit datatype moeten gespecifieerd zijn.

Datatype Identifier;

Bij een weakly/loosly typed programmeertaal (zoals Javascript) hoeft het type niet gespecifieerd te worden en kunt u een variabele duiden met het woordje var.

var Identifier;

Bijvoorbeeld, onderstaande code toont hoe u een variabele met de naam mijnNaam declareert.

var mijnNaam;

Merk op dat er op dit ogenblik nog geen waarde is toegekend, dit betekent dat in JavaScript op dit ogenblik het datatype van het type Undefined is (een speciaal datatype in Javascript).

Waarde toekennen

Nadat een variabele gedeclareerd is kan een waarde toegekend worden. Dit gebeurt door het toekenningsteken (meestal =-teken) gevolgd door de waarde die toegekend wordt en het scheidingsteken puntkomma.

Variabele = Waarde;

Belangrijk, ook al staat er een =-teken, dit is geen wiskundige gelijkheid. U moet dit lezen als de variabele krijgt de waarde “waarde” toegewezen.

var mijnNaam;
mijnNaam = "Geert";

JavaScript herkent dat er een string (tekst) is toegekend en geeft de variabele mijnNaam het datatype String. De waarde die u toekent bepaalt dus, in Javascript, het datatype van de variabele.

Bijvoorbeeld, onderstaande code declareert 2 variabelen, aan de ene mijnNaam wordt een tekst/string toegewezen en aan de tweede variabele schoenmaat een getal.

var mijnNaam;
var schoenmaat;

mijnNaam = "Geert";
schoenmaat = 42;
  • De variabele mijnNaam zal het datatype String hebben.
  • De variabele schoenmaat zal het datatype Number hebben.

Initialisatie

Vaak wordt de declaratie en de toekenning van de waarde in één stap uitgevoerd. Dit wordt initialisatie genoemd.

var Identifier = Waarde;

var mijnNaam = "Geert";

De variabele gebruiken

Eens de variabele een waarde gekregen heeft kan ze nadien gebruikt worden om bv. de waarde van variabele weer te geven op het scherm.

var mijnNaam = "Geert";
write(mijnNaam);

Merk op dat de variabele niet tussen “” (quotes) staat!

Constanten

De meeste programmeertalen, en ook JavaScript, kennen het begrip constante. Een constante is als een variabele maar met dit belangrijke verschil dat de waarde na de declaratie niet meer kan worden gewijzigd.

Het declareren, in JavaScript, van een constante is identiek aan het declareren van een variabele, vervang gewoon het woordje var door const.

const Identifier = Waarde;

Constanten worden praktisch gebruikt om vaste waarden toe te kennen die niet mogen gewijzigd worden. Bijvoorbeeld de waarde van het getal PI of het aantal maanden in een jaar.

const PI = 3.14159;

Identifiers

Alle variabelen moeten een unieke naam (binnen hetzelfde bereik) hebben.

Zo’n unieke naam wordt een Identifier genoemd. Het identificeert de variabele op een unieke manier.

Identifiers, of namen, moeten zich houden aan bepaalde regels. Voor JavaScript (net als bij C#) zijn deze:

  • De identifier mag letters, cijfers, de underscore (_-teken) of dollarteken ($-teken) bevatten.
  • De identifier mag dus geen spaties bevatten.
  • Identifiers mogen niet beginnen met een cijfer.
  • Identifiers zijn hoofdlettergevoelig (dus de naam Getal is niet gelijk aan de naam getal).
  • De identifier mag geen gereserveerd woord zijn gebruikt door de programmeertaal.

Kies steeds namen die duidelijk de waarde omschrijven. Zo is de naam BTW duidelijker dan Getal7.

Vaak wilt u dat de identifier bestaat uit meerdere woorden. Door de tijd hebben programmeurs hiervoor een drietal methoden gebruikt:

Gebruik underscores

bedrag_zonder_BTW, mijn_naam

Camel Case (beginhoofdletters)

BedragZonderBTW, MijnNaam

of, zoals vaak in JavaScript, startend met een kleine letter en vervolgens beginhoofdletters

bedragZonderBTW, mijnNaam

De gekozen methode is niet bindend, u mag dus verschillende methoden door mekaar gebruiken al raad ik dit af om vanzelfsprekende redenen.


Berekeningen

Operatoren

Om berekeningen uit te voeren maakt u gebruik van operatoren. Er zijn wiskundige operatoren, stringoperatoren en toekenningsoperatoren.

Wiskundige operatoren

Onderstaande tabel toont de wiskundige operatoren die gebruikt worden in Javascript (en C#).

BetekenisOperator
Machtsverheffing Math.Pow(x,y)
Positief of negatief+ en -
Vermenigvuldigen en delen * en /
Gehele deling (deling zonder gedeelte na de komma)/
Modulus (rest bij een gehele deling) %
Optellen en aftrekken + en -

Bijvoorbeeld, tel 2 getallen op.

var x = 5; // Ken de waarde 5 toe aan de variabele x
var y = 2; // Ken de waarde 2 toe aan de variabele y
var z = x + y; // Ken de som van de waarden van de variabelen x en y toe aan de variabele z

Merk op dat, ook al kan u rechtstreeks de getallen zelf optellen, het is een goede gewoonte de getallen eerst aan een variabele toe te kennen en vervolgens de variabelen te gebruiken voor de optelling.

Voorrangregels

De bovenstaande tabel toont de berekeningen met de operatoren in de juiste volgorde van uitvoeren (voorrangregels).
zo is:

1 + 2 * 3 = 7

De bovenstaande tabel toont dat * (vermenigvuldigen) voorrang heeft op + (optellen). Dus eerst wordt 2 * 3 uitgevoerd, dit is 6, en daar wordt dan 1 bij opgeteld. Dit levert 7 op als resultaat.

Om de voorrangregels te wijzigen worden haakjes gebruikt.

(1 + 2) * 3 = 9

De haakjes zorgen ervoor dat eerst 1 + 2 wordt uitgevoerd (dit levert 3 op). Deze uitkomst, 3 dus, wordt nadien vermenigvuldigd met 3 en levert zo het resultaat 9 op.

Stringoperatoren

Strings, tekst, kunnen eveneens “berekend”, aan mekaar verbonden, worden.

BetekenisOperator
Strings samenvoegen+

Bijvoorbeeld, voeg 2 strings/teksten samen.

var voornaam = "Geert";
var familienaam = "Linthoudt";
var naam = voornaam + " " + familienaam;

Merk het tussenvoegen van een spatie op. Doet u dit niet dan zouden de voornaam en familienaam direct aan mekaar “gekleefd” worden. Het resultaat zou dan zijn, zonder die extra spatie, “GeertLinthoudt”. Dit wilt u uiteraard niet, vandaar het tussenvoegen van de spatie.

Toekenningoperatoren

Toekenningoperatoren zijn operatoren die gebruikt kunnen worden om waarden toe te kennen aan variabelen. Tot nu toe hebben we dit steeds gedaan met het =-teken. Dit is inderdaad de meest gebruikte toekenningoperator maar er zijn er nog anderen.

De toekenning, het =-teken, moet u lezen als krijgt als waarde.

De toekenningoperatoren kunnen ook gebruikt worden als een verkorte vorm van een berekening.

ToekenningOperator
Getal krijgt de waardeGetal = Waarde
Getal = Getal + Waarde Getal += Waarde
Getal = Getal - Waarde Getal -= Waarde
Getal = Getal * WaardeGetal *= Waarde
Getal = Getal / Waarde Getal /= Waarde
Getal = Getal % Waarde Getal %= Waarde
Getal = Getal + 1 Getal++
Getal = Getal - 1 Getal--
Tekst = Tekst + Tekst2 Tekst += Tekst2

Bijvoorbeeld:

var x = 5; // Ken de waarde 5 toe aan de variabele x
x += 5; // Tel bij de waarde van x 5 op. x heeft na de optelling de waarde 10

Wanneer telt het +-teken getallen op, wanneer voegt het tekst samen?

  • 5 + 5 geeft als resultaat 10.
  • “Klas” + 5 geeft als resultaat “Klas5”.

Met andere woorden:

  • Het +-teken telt op indien de beide waarden numeriek zijn.
  • Het +-teken voegt samen indien minstens één van de beide waarden een string/tekst is.

Willekeurige getallen

Om een willekeurige waarde te genereren kent JavaScript (en ook C#) de functie wiskundige functie random(). Deze functie bevindt zich in de klasse Math. De functie wordt dus:

Math.random()

De gegenereerde waarde wordt toegekend aan een variabele.

var Getal1 = Math.random();

De waarde die gegenereerd wordt ligt tussen 0 (inbegrepen) en 1 (niet inbegrepen) of:

0 <= Math.random() < 1

We wensen echter de waarde tussen 1 en 6.

Daartoe dient de gegenereerde waarde vermenigvuldigd te worden met 6. Dit levert een waarde op tussen 0 * 6 = 0 (inbegrepen) en 1 * 6 = 6 (niet inbegrepen).

0 <= Math.random() * 6 < 6

We hebben dus nog steeds een probleem want de waarde die nu gegenereerd wordt ligt tussen 0 en 5.9999 en dus niet tussen 1 en 6. De oplossing bestaat eruit 1 bij te tellen. De formule wordt dan:

1 <= Math.random() * 6 + 1< 7

We zijn er nog steeds niet want de willekeurig berekende waarde ligt nu tussen 1 en 6,9999 en we wensen enkel gehele waarden als uitvoer (dus geen decimale getallen). Om dit te bekomen moeten we een tweede functie toepassen op de berekende waarde met name de functie Math.floor().

De functie Math.floor() rondt de berekende waarde af naar de juist onderliggende gehele waarde dus 6.999 wordt afgerond naar 6. De formule wordt dan:

1 <= Math.floor(Math.random() * 6) + 1 <= 6

De code:

var Getal1 = Math.floor(Math.random() * 6) + 1;

Overzicht genereren van willekeurige getallen

Een willekeurig getal tussen 0 (inbegrepen) en 1 (niet inbegrepen):

Math.random()

Een willekeurig getal tussen een minimum (inbegrepen) en een maximum (niet inbegrepen):

Math.random() * (max – min) + min

Een willekeurig geheel getal tussen een minimum (inbegrepen) en een maximum (niet inbegrepen):

Math.floor(Math.random() * (max – min)) + min

Een willekeurig geheel getal tussen een minimum (inbegrepen) en een maximum (inbegrepen):

Math.floor(Math.random() * (max – min + 1)) + min

Opmerking: App lab heeft ook een eigen functie om een willekeurig getal te berekenen:

randomNumber(min, max);


Functies

Een basisprincipe van het programmeren is het DRY-principe (Don’t Repeat Yourself).

Het DRY-principe stelt dat u eenzelfde code nooit twee keer mag intypen.

Dus, wanneer bepaalde code, bv. de code om iets te berekenen, herhaaldelijk kan voorkomen in uw programma(‘s) dan kunt u dit het best afzonderen in een functie (subroutine, module, procedure,…).

Functies zorgen er dus voor dat u bepaalde code slechts eenmaal moet programmeren. Eventuele wijzigingen moeten dan ook maar op deze ene plek uitgevoerd worden. Hebt u deze functie nodig dan moet u deze aanroepen.

  1. Een functie moet dus eerst gedefinieerd worden, door het een naam/identifier te geven.
  2. Nadien kunt u deze functie aanroepen door deze naam te gebruiken.
  3. Uw functies kunt u in principe gelijk waar definiëren, het best is ze echter te verzamelen op eenzelfde plek, desnoods een afzonderlijk bestand dat u kunt linken, integreren. Zoiets wordt een bibliotheek genoemd. Deze bibliotheken worden vaak toegankelijk gemaakt via API’s (Aplication Programming Interface). Maar dit is specifiek voor een programmeertaal en wordt hier niet verder uitgewerkt.

Een functie definiëren

Het definiëren van een functie in Javascript gebeurt als volgt:

function functienaam(parameter1, parameter2, ...) {
statements
}

  • Een functie begint met het woordje function.
  • Nadien volgt de functienaam, die een identifiër is en dus moet voldoen aan de regels van een identifiër.
  • nadien komen de ().
  • Een functie kan parameters/argumenten ontvangen. Deze parameters zijn waarden waarmee de functie iets kan/moet doen, parameters zijn de invoer (input) voor de functie. Parameters maken functies dynamischer doordat u steeds andere waarden kunt toekennen aan de parameters waardoor de functie een ander resultaat kan “berekenen”.
  • Zijn er meerdere parameters dan worden deze gescheiden door een komma.
  • Het begin en einde van de functie wordt afgebakend door de {}.
  • De functie zelf bevat een (aantal) statement(s).

U hebt reeds functies gebruikt, denk aan:

window.alert("Hello, world!");
Math.random()

Dit is een standaard functie uit Javascript.

Of denk aan:

write("Hello, world!");
randomNumber(min, max);

Dit zijn eigen functie van App lab geprogrammeerd in Javascript.

Er zijn 2 soorten functies.

  • Functies die geen waarde teruggeven maar een aantal statements groeperen onder een specifiek naam om deze gezamenlijk uit te voeren. Deze functies kunnen, maar moeten geen, parameters hebben. Deze functies kunnen gewoon worden aangeroepen als een statement. De bovenstaande functies window.alert("Hello, world!"); en write("Hello, world!"); zijn hier een voorbeeld van.
  • Functies die een “berekende” waarde teruggeven. Deze functies kunnen (zullen vaak) parameters hebben die de waarden meegeven waarmee de “berekening” moet worden uitgevoerd. Mits deze functies een “berekende” waarde teruggeven moet deze teruggeven waarde ook ergens in bewaard worden. Deze functies worden dan ook meestal aangeroepen rechts van een =-teken (Links staat dan bv. een variabele waar de teruggegeven, berekende, waarde in bewaard wordt) of als parameter van een statement. Ik plaats “berekenen” tussen “” omdat het niet echt om wiskundige berekening moet gaan.

Functies die geen waarde teruggeven

Bijvoorbeeld, een eigen functie mijnBoodschap().

function mijnBoodschap(boodschap)
{
     write(boodschap);
}

Om deze functie aan te roepen gebruikt de naam mijnBoodschap en geeft u tussen () de gewenste waarde (boodschap) mee.

mijnBoodschap("Hello, world!");

Functies die een waarde teruggeven

Bijvoorbeeld een functie die de BTW berekent.

function BTW(bedrag, perc)
{
     var resultaat = bedrag * perc / 100;
     return resultaat ;
}

Deze functie kan bijvoorbeeld aangeroepen via onderstaande code:

var bedrag;
var percentage;
var BTWbedrag;

bedrag = 100;
percentage = 21;

BTWbedrag = BTW(bedrag, percentage);
write(BTWbedrag);

Bij de aanroep van de functie BTW wordt de waarde van de variabele bedrag toegekend aan de parameter bedrag van de functie en wordt de waarde van de parameter percentage toegekend aan de parameter perc.

BTW(bedrag, percentage)

De functie gebruikt de parameters bedrag en perc (en de hun toegekende waarden) om de gewenste berekening te maken en kent het resultaat toe aan een variabele resultaat.

var resultaat = bedrag * perc / 100;

De variabele resultaat wordt nadien teruggegeven.

return resultaat ;

De teruggegeven waarde wordt geplaatst in de variabele BTWbedrag.

BTWbedrag = BTW(bedrag, percentage);

De waarde van BTWbedrag wordt vervolgens getoond.

write(BTWbedrag);

Merk op dat de namen van de parameters van de functie BTW(Bedrag, Perc) en van de aanroep BTW(bedrag, percentage) dezelfde mogen, maar niet moeten zijn.

Uiteraard wordt de waarde van de eerste parameter van de aanroep aan de eerste parameter van de functie toegekend. De waarde van de tweede parameter van de aanroep wordt aan de tweede parameter van de functie toegekend, enz.

Opmerking, bij een strongly typed programmeertaal zullen de datatypes van de meegegeven waarde bij de aanroep en van de ontvangen parameter in de functie moeten bepaald en van hetzelfde datatype zijn.


Event-drive ontwerpen

Vele moderne programma’s, zoals vele mobile apps, werken event-driven. Bij event-dreven programmeren wordt de control flow in eerste instantie bepaald door de events/gebeurtenissen veroorzaakt (getriggerd) door het programma zelf of door de gebruiker.

Ik herneem hier even het stukje rond event-driven dat ik al eens eerder geschreven heb.

Events/gebeurtenissen zijn acties die kunnen gebeuren of uitgevoerd worden tijdens het werken met het programma. Voorbeelden van events zijn:

  • de pagina wordt geladen
  • de pagina is geladen
  • de gebruiker klikt op een knop
  • de gebruiker beweegt de muis over een object
  • de gebruiker typt een toets in

Bij event-driven programmeren wordt de control flow, de opeenvolging van de uit te voeren instructies, van het programma bepaald door de volgorde waarin de events/gebeurtenissen plaatsvinden. De instructies die horen bij het klikken op een specifieke knop worden pas uitgevoerd indien er daadwerkelijk op die specifieke knop gedrukt wordt.

Programma’s die veel interactie vragen van de gebruiker zoals interactieve websites, mobiele apps, eenvoudige spelletjes zijn vaak event-driven. Deze programma’s beschikken dan ook vaak over een geschikte gebruikersvriendelijke GUI (Grafische User Interface).

Bij event-driven ontwerpen bouwt u (vaak) eerst de GUI en bedenkt u welke events er kunnen plaatsvinden of nodig zijn (let op, de GUI wordt gebouwd met de nodige events in gedachte, zo zal u een knop toevoegen aan de GUI juist me de bedoeling om er op te kunnen klikken en niet andersom. U gaat geen knop plaatsen omdat die er mooi staat en u vervolgens de vraag stellen wat er zou kunnen gebeuren als u op deze knop zou drukken). Vervolgens programmeert u elk van deze events.

Een event toevoegen in App lab

Voeg een Button (knop) toe aan het ontwerpscherm. Geef de Button de tekst “OK”. Merk op dat u nog andere eigenschappen (properties) kunt wijzigen. Een belangrijke is de id, die u voorlopig op button1 mag laten staan. De id wordt gebruikt om het object te identificeren, een naam te geven. Deze id wordt in de programmeercode gebruikt telkens u verwijst naar het specifieke object. Omdat er maar 1 Button is, is de id “Button1” aanvaardbaar.

Met de knop geselecteerd klikt u op het tabblad Events. U kunt maar één event toevoegen, namelijk een Click-event, deze wordt uitgevoerd (getriggerd) als de gebruiker op de knop klikt.

De aangemaakte code ziet er als volgt uit (in blokjes).


De aangemaakte programmeercode is de volgende:

onEvent("button1", "click", function(event) {
  console.log("button1 clicked!");
});
  • Er wordt een functie aangeroepen onEvent() (dit is een functie van App lac).
  • Deze functie heeft 3 parameters:
  1. De naam van het object die de event triggert: hier “button1”.
  2. De event die wordt getriggerd: hier click.
  3. De derde parameter is opnieuw een functie, de eigenlijke event: function(event){}. Deze functie wordt een callback function genoemd, een functie die aangeroepen wordt door de vorige functie en waarbij het resultaat van de vorige functie als parameter wordt meegegeven aan de callback function (meer hierover als we het hebben over functies).
  • De voorlopige uitvoer van de event is het schrijven van de tekst “button1 clicked!” op de console.

Zo, nu u weet hoe een event toe te voegen kunnen we code toevoegen binnen deze event.


Invoeren, verwerken en uitvoeren

De control flow is in essentie vaak te herleiden tot volgende 3 stappen:

  1. Gegevens invoeren.
  2. De ingevoerde gegevens verwerken tot informatie.
  3. Informatie uitvoeren.

Als flow chart (zie algoritmes) zie dit er als volgt uit.

Wat is informatie?

Informatie kan gezien worden als het resultaat van verwerkte gegevens.

Bijvoorbeeld:

45 is een gegeven (of data). Maar waar staat die 45 nu eigenlijk voor?

Na verwerking van het gegeven 45 kan bv. blijken dat de 45 staat voor behaalde punten en dat dit onvoldoende is om geslaagd te zijn.

Onvoldoende om geslaagd te zijn is dan de informatie die gehaald is uit het gegeven 45.

Invoer

Invoer is afhankelijk van de ontwikkelomgeving maar veel voorkomende invoerobjecten zijn:

  • Tekstvakken
  • Keuzelijsten
  • Keuzerondjes
  • Keuzevakjes
  • Datepickers
  • Sliders

Naargelang de ontwikkelomgeving kunnen deze ook anders genoemd worden.

In App lab kunt u ingevoerde tekst opvragen met de functie:

getText(id)

Hierbij is id de waarde van de eigenschap id van het object (tussen “”) dat de tekst bevat .

Indien u specifiek een getal wilt invoeren kunt u dit doen met de functie:

getNumber(id)

Uitvoer

Uitvoer is afhankelijk van de ontwikkelomgeving maar veel voorkomende uitvoerobjecten zijn:

  • Labels
  • Canvas

Naargelang de ontwikkelomgeving kunnen deze ook anders genoemd worden.

In App lab kunt u tekst uitvoeren met de functie:

setText(id, text)

Hierbij is id de id de waarde van de eigenschap id van het object (tussen “”) waar u de tekst wilt plaatsen, de parameter text bevat dan de eigenlijke tekst, of de variabele die de tekst bevat.

Meestal zal u als tekst uitvoeren, maar u kunt eventueel ook als een getal uitvoeren met:

setNumber(id, number)

Uw eerste app: BTW berekenen

  • De gebruiker moet een getal invoeren.
  • Uit een keuzelijst het gewenste BTW-percentage selecteren.
  • Na het klikken op een knop/button moet de berekende BTW getoond worden.

Ik herneem een voorbeeld uit een vorige post waarin we reeds de BTW berekend hebben via aan functie.

De functie BTW():

function BTW(bedrag, perc)
{
     var resultaat = bedrag * perc / 100;
     return resultaat ;
}

Dit was de code voor het aanroepen van de functie BTW() zonder specifieke invoer (maar via variabelen) hier uitgebreid met commentaar die duidt wat de invoer, berekening en uitvoer is:

var bedrag;
var percentage;
var BTWbedrag;

//Invoer
bedrag = 100;
percentage = 21;

//Berekening
BTWbedrag = BTW(bedrag, percentage);

//Uitvoer
write(BTWbedrag);

Laten we dit nu omzetten naar een bruikbare app.

Maak eerst het onderstaande scherm aan. Gebruik hiervoor het ontwerpscherm van App lab. Het hoeft niet perfect te kloppen maar een paar tips.

  • De titel, een label, heeft een font size van 20 px.
  • Het tekstvak (Text input) naast het label “Bedrag zonder BTW” heeft de id “invoerBedrag”.
  • De keuzelijst (Dropdown) naast het label “Percentage” heeft de id “invoerPercentage”. De keuzelijst heeft 4 opties: 0, 6, 12, 21.
  • De eigenschappen van de label waar de uitvoer moet komen heeft de id “uitvoer”. De andere eigenschappen van dit object ziet u in het afdrukvoorbeeld.

  • Voeg vervolgens een Click-event toe aan de Button (zoals hierboven beschreven).
  • Kopieer de functie BTW() (zie hierboven) onder de code van het Click-event.
  • Voeg de code met de aanroep van de BTW() (zie ook hierboven) toe binnen het Click-event ter vervanging van de code console.log("button1 clicked!");.

De programmeercode moet er nu als volgt uitzien.

onEvent("button1", "click", function(event) {
    var bedrag;
    var percentage;
    var BTWbedrag;

    //Invoer
    bedrag = 100;
    percentage = 21;

    //Berekening
    BTWbedrag = BTW(bedrag, percentage);

    //Uitvoer
    write(BTWbedrag);
});

function BTW(bedrag, perc)
{
     var resultaat = bedrag * perc / 100;
     return resultaat ;
}

Nu moet de specifieke invoer nog worden toegevoegd.

Voor de invoer.

In plaats van vaste waarden aan variabelen toe te kennen zoals:

bedrag = 100;

vraagt u het specifieke bedrag op dat staat in het tekstvak “invoerBedrag”. U doet dit met de functie getText(id):

bedrag = getText("invoerBedrag");

In plaats van:

percentage = 21;

vraagt u het specifieke percentage op dat u selecteert in de keuzelijst “invoerPercentage”. U doet dit eveneens met de functie getText(id):

percentage = getText("invoerPercentage");

Voor de uitvoer.

In plaats van het BTWbedrag gewoon op het scherm te schrijven met:

write(BTWbedrag);

wordt het BTWbedrag nu weggeschreven in het label met de id “uitvoer”. U doet dit met de functie setText(id, Text):

setText("uitvoer", BTWbedrag);

De code wordt nu:

onEvent("button1", "click", function(event) {
    var bedrag;
    var percentage;
    var BTWbedrag;

    //Invoer
    bedrag = getText("invoerBedrag");
    percentage = getText("invoerPercentage");

    //Berekening
    BTWbedrag = BTW(bedrag, percentage);

    //Uitvoer
    setText("uitvoer", BTWbedrag);
});

function BTW(bedrag, perc)
{
     var resultaat = bedrag * perc / 100;
     return resultaat ;
}

Zo, u hebt uw eerste, heel eenvoudig, maar toch, programmaatje geschreven.

getText() versus getNumber()

Let op, in bovenstaande code gebruik ik voor de invoer het standaard, eenvoudige getText("invoerBedrag"), maar aangezien we getallen inlezen was getNumber("invoerBedrag") misschien we de betere optie.

Stel, onderstaande code.

Ik heb 2 tekstvakken/text_input (txtA en txtB), een knop/button (Bereken) en een label (lblResultaat).

Ik heb onderstaande code:

onEvent("Bereken", "click", function( ) {
	 var a;
	 var b;
	 var c;
	 
	 a = getText("txtA");
	 b = getText("txtB");
	 
	 c = a + b;
	 
	 setText("lblResultaat", c)
});

Stel, u geeft 1 en 2 in in de tekstvakken en u klikt op de knop Bereken.

U krijgt niet het gewenste resultaat, u verwachtte wellicht 3, maar krijgt 12 als resultaat.

Hoe komt dit?

Wel de invoer wordt als tekst ingelezen a = getText("txtA"); en b = getText("txtB");, u leest dus de tekst “1” en de tekst “2” in. Vervolgens worden deze tekens samengevoegd (niet opgeteld) met de code c = a + b;. Het resultaat is dus de tekst “12”.

Om als resultaat het getal 3 te krijgen moet u inlezen als een getal a = getNumber("txtA"); en b = getNumber("txtB");.

onEvent("Bereken", "click", function( ) {
	 var a;
	 var b;
	 var c;
	 
	 a = getNumber("txtA");
	 b = getNumber("txtB");
	 
	 c = a + b;
	 
	 setText("lblResultaat", c)
});

U krijgt nu wel de verwachtte 3 als resultaat.


Behandelde Basiscompetenties uit de module ICT Programmeren – Start to program

  • IC BC228 – kent de verschillende principes en onderdelen op basis waarvan een programma kan opgebouwd worden
  • IC BC229 – begrijpt de basisprincipes van programmeren
  • IC BC237 – kan een eenvoudig programma wijzigen
  • IC BC240 – kan een eenvoudig programma maken
  • IC BC242 – kan een programma uittesten
  • IC BC243 – kan een programma documenteren
  • IC BC352 – begrijpt het systeem en de functies die achter een programma zitten

Hide and seek champion…
;
since 1958.

Geef een reactie

Deze website gebruikt Akismet om spam te verminderen. Bekijk hoe je reactie-gegevens worden verwerkt.

  • Abonneer je op deze website d.m.v. e-mail

    Voer je e-mailadres in om je in te schrijven op deze website en e-mailmeldingen te ontvangen van nieuwe berichten.