Programmering01 [prrprr01]

Moment03 - Kontrollstrukturer

Introduktion

Vi fortsätter med grundläggande programmering men nu skall vi titta på olika saker som är grundläggande krav för att kunna skapa till och med det enklaste programmet. Detta moment innehåller selektioner och iterationer.

Momentets mål

I varje moment så jobbar vi mot ett eller flera mål som skolverket har satt upp i varje kurs.

Centralt innehåll

  • Grundläggande programmering i ett eller flera programspråk varav minst ett av språken är textbaserat.
  • Strukturerat arbetssätt för problemlösning och programmering.
  • Grundläggande kontrollstrukturer, konstruktioner och datatyper.
  • Arbetsmetoder för förebyggande av programmeringsfel, testning, felsökning och rättning av kod.
  • Grundläggande datastrukturer och algoritmer.

Selektion

I alla programmeringsspråk så är selektioner ett centralt begrepp. Selektioner eller villkorssatser brukar vi kalla det på svenska, Control Structures heter det på engelska.
Oavsett vad det kallas så handlar det om val och att tala om för programmet att göra olika saker beroende på ett specifikt villkor. Vi kommer gå igenom två olika strukturer som i grunden fungerar på samma sätt, fastän de skrivs olika.

if-satsen

Den absolut vanligaste selektionen är att bara använda en if-sats. Genom att skriva en if-sats och i parentesen ha ett uttryck så får du din kod att utföra en operation. Vi gör ett enkelt exempel;

<?php
$age = 17;

// Kollar om variabeln $age är mindre än 18
if($age < 18){
	echo "Du är inte myndig!";
}
?>

Läs ut koden som OM $age är mindre än 18, då kommer koden mellan måsvingarna att köras.

Resurser & länkar

Uppgift: if-satsen

  1. I php finns det mängder av inbyggda funktioner, en som kan användas skrivs date("H") och då får du fram webbserverns klockslag i timmar. Lagra detta värde i variabeln $timme och skriv sedan en if-sats som kollar om värdet är större än 16, om det är fallet så skriver du ut att skoldagen är slut.
<?php
	$t = date("H");
	echo $t;
?>

Ger utskriften

20

Uttryck och operatorer

I parentesen ovan så skapar vi ett uttryck. Alla uttryck som vi skapar måste ge svaret SANT eller FALSKT. Inga andra svar kommer fungera.

För att kunna skapa dessa uttryck behöver vi kunna använda oss av ett gäng operatorer inom två olika grupper, jämförelseoperatorer och logiska operatorer.

Jämförelseoperatorer

Dessa operatorer gör precis vad de säger, de används för att jämföra olika värden.

Operator Namn Exempel Resultat av uttrycket
== Lika med $a==12 Sant om $a är lika med 12, annars falskt.
!= Inte lika med, skiljt ifrån $a!=12 Sant om $a inte är lika med 12, annars falskt.
< Mindre än $a<12 Sant om $a är mindre än 12.
> Större än $a>12 Sant om $a är större än 12.
<= Mindre än eller lika med $a<=12 Sant om $a är mindre än eller lika med 12.
>= Större än eller lika med $a>=12 Sant om $a är större än eller lika med 12.
=== Identiska $a===12 Sant om $a har värdet 12 och är ett heltal, 12 är inte lika med "12"!
!== Icke identiska $a!==12 Sant om $a inte har värdet 12 eller inte är ett heltal.

Logiska operatorer

Logiska operatorer används för att kunna skapa sammansatta uttryck

Operator Namn Exempel Resultat av uttrycket
and och $a and $b Sant om $a och $b båda är sanna, annars falskt.
or eller $a or $b Sant om $a eller $b är sanna, är $a sant kollas inte $b.
xor exklusivt eller $a xor $b Sant om $a eller $b är sanna, men inte sant om bägge är sanna.
! icke !$a Sant om $a inte är sant. (Kallas att negera)

Sammansatta exempel

Att lära sig bygga sammansatta uttryck är viktigt för att skriva bra kod. I många fall så går det att komma runt med flera mindre uttryck men vi vill ju skriva effektiv kod och då är detta bra att kunna.
Här kommer några exempel;

Exempel Betydelse
$age < 18 or $age > 65 Sant om $age är mindre än 18 eller större än 65. Alltså koll om personen är ungdom eller pensionär.
$age >= 18 and $haveJob != true Sant om $age större än eller lika med 18 och $haveJob är falsk. Personen är myndig och arbetslös.

Resurser & länkar

Uppgift: Sammansatta uttryck

  1. Skriv på minst ett sätt ett uttryck som gör att det där klockslaget som vi hämtade i förra övningen ger svaret att "Det är skoldag" om värdet är mellan 8 och 16. Hur många sätt kan du lösa uppgiften på?

if else-satsen

Nu när vi kan skriva uttryck så ser vi att det oftast blir två olika alternativ, antingen blir resultatet av uttrycket sant eller så blir det falskt. Vi vet hur vi tar hand om det sanna resultatet, nu är det dags att ta hand om det falska också.
Läs ut koden som Om - annars.

<?php
$age = 17;

// Kollar om variabeln $age är mindre än 18
if($age < 18){
	echo "Du är inte myndig!";
} else {
	echo "Du är myndig!";
}
?>

Om $age är mindre än 18 körs koden mellan de första måsvingarna, annars körs koden mellan de andra måsvingarna.
Det här kommer vi ganska så långt med. Har vi två val är det alltid if och else som vi skall jobba med.

Uppgift: if-else

  1. Skriv nu ut om det är skoldag eller inte, allt mellan 8 och 16 anser vi vara skoldag. Om klockslaget visar utanför den tiden så skriver du ut att det inte är skoldag.

if else if-satsen

Ibland så räcker det inte endast med två alternativ då får vi lägga till med if - else if - else för att kunna göra rätt val.

<?php
$age = 17;

// Kollar om variabeln $age är mindre än 18
if($age < 18){
	echo "Du är inte myndig!";
} else if ($age >= 65) {		// Kolla om $age är större än eller lika med 65
	echo "Du är troligtvis pensionär!";
} else {
	echo "Du är myndig";
}
?>

OM $age är under 18 ..... annars om $age är större än eller lika med 65 ...... annars ....... Avsluta alltid ett flerval med en else-sats.

Det finns ingen anledning att göra följande kontroll;

<?php
$age = 17;

// Kollar om variabeln $age är mindre än 18
if($age < 18){
	echo "Du är inte myndig!";
} else if ($age >= 18) {
	echo "Du är myndig";
}
?>

Risken är större att du skriver fel och tex missar att ta hand om 18-åringen då du av misstag skriver ($age >18).

På samma sätt kan vi skriva många olika uttryck, det finns ingen begränsning om hur många du kan skriva. Det enda du behöver tänka på är att så fort ett uttryck passar så kommer koden att utföra de instruktioner som finns mellan de måsvingar i direkt anslutning till det korrekta uttrycket.

<?php
$age = 72;

if($age < 2){
	echo "Du är nog hemma med dina föräldrar!";
} else if ($age < 6 ) {
	echo "Förskolebarn";
} else if ($age < 12 ){
	echo "Hoppas du får många läxor...";
} else if ($age < 20){
	echo "Tonåring, högstadie, gymnasie eller börjat högskolan?";
} else if ($age > 64){
	echo "Pensionär?";
} else {
	echo "Jobba, jobba, jobba!";
}
?>

Uppgift: if - else if - else

  1. Ok. Vi överraskar lite, nu skall du skriva ut att "skoldagen inte har börjat" om klockan är före 8, att "skoldagen är slut" om klockan är efter 16 annars skriver du att "skoldagen pågår".

Utan måsvingar

Om du tittar på kod som finns på nätet kommer du rätt var det är upptäcka att det här med måsvingar ägnar sig inte alla av. Det beror på att du kan skippa måsvingen om det bara är en instruktion som skall utföras inne i en selektion. Jag rekommenderar dig dock att skriva ut dem då det är vanligt att det blir fel innan du är helt på det klara med hur det fungerar. Lär dig grunderna först och välj sedan de lite enklare lösningarna.

Resurser & länkar

Frivillig uppgift: utan måsvingar

  • Jag gillar egentligen inte att visa på saker som kan gå fel, men om du känner dig redo så lös uppgift 4 utan att använda måsvingar.

switch-satsen

Switch-satsen är väldigt användbar när det är många olika alternativ. Även om man kan lösa i stort sett alla selektioner med både if-satser och switch-satser så är de naturligtvis extra bra på olika saker. När vi jobbar med if-satser så jobbar vi med tydligare uttryck, i switch-satsen så är vi mer ute efter att alternativet vi söker efter är ett heltal, ett tecken eller en sträng. Att köra switch med en sträng fungerar inte i alla programmeringsspråk, men det fungerar utmärkt med php.

Om vi tittar på strukturen så har vi en variabel som vi sätter in i parentesen och sedan jämför vi det värdet med olika "case" som vi sätter upp. Varje case är ett värde som variabeln kan anta. Efter alla case är uppräknade så avslutar vi med ett default-case som tar hand om alla andra alternativ. Detta går att jämställa med else-satsen tidigare.

Nästa grej att hålla koll på är "break;" som kommer efter alla satser som hör ihop med ett speciellt "case". Denna "break" avslutar switch-satsen och gör att programmet fortsätter efter den stängande måsvingen. Om vi struntar i break-satsen på rad 7 och rad 10 så kommer svaret alltid bli "Jag känner inte igen sporten" följt av det som du angivit. Detta kan vara användbart om vi vill göra beräkningar men oftast blir det bara svårt att kontrollera.
Enda chansen att upptäcka detta är att testa våra applikationer.

<?php
$favSport = "fotboll";

switch ($favSport) {
    case "fotboll": 						// Valet: fotboll
        echo "Det gröna fältets schack är sporten framför andra.";
        break;
    case "innebandy": 					// Valet: innebandy
        echo "Den finaste vinteridrotten!";
        break;
    default:  									// Alla andra val
        echo "Jag känner inte igen sporten $favSport.";
}
?>

Om vi testar att köra vår kod så blir utskriften;

Det gröna fältets schack är sporten framför andra.

Om vi har flera "case" som ger samma resultat eller som skall utföra samma sats så kan vi ställa upp koden på följande sätt.

<?php
// Ange i vilken månad du är född.
$monthOfBirth = 11;

switch($monthOfBirth){
	case 12: 								// december
	case 1: 								// januari
	case 2: 								// osv.....
		$season = "vintern";
		break; 								// break, annars går vi automatiskt...
	case 3:
	case 4:
	case 5:
		$season = "våren";
		break; 								// ...vidare till nästa case...
	case 6:
	case 7:
	case 8:
		$season = "sommaren";
		break; 								// ...vilket slutar med att...
	default: 								// ... alla skulle vara födda på hösten.
		$season = "hösten";
}
echo "Du fyller år på $season";
?>

Och utskriften i vårt exempel blir.

Du fyller år på hösten

Resurser & länkar

Uppgift: switch

  1. Vi testar att lösa uppgift 4 med switch-satsen istället. Denna lösning är inte den snyggaste som går att göra men den visar tydligt på skillnaden mellan if och switch.

Iteration

Iteration är ett annat ord för upprepning. Inom matematiken och i programmering handlar detta om att en funktion eller process åstadkommer något genom att upprepa beräkningar eller andra operationer tills ett önskat resultat uppnåtts.
https://sv.wikipedia.org/wiki/Iteration

Det finns flera olika strukturer när vi skapar iterationer inom programmeringen, de är bra på olika saker så för att få den mest effektiva koden behöver du kunna använda flera olika typer.

For-loopen

For-loopen är den mest styrda loopen, här ligger fokus på att en operation genomförs x antal gånger.

<?php
for($i=0; $i<5; $i++){
	echo "$i<br>";
}
?>

Inom loophuvudet, rad 2, så ser du att det finns tre argument;

  1. Variabeln $i får ett värde, i detta fall 0.
  2. Loopen skall köras så länge som villkoret är uppfyllt, i detta fall så länge som $i<5.
  3. Efter att de instruktioner som skall köras, koderna mellan måsvingarna, så händer något med variabeln, i detta fall så ökar värdet med 1, sedan körs hela loopen igen.

Utskriften blir då

0
1
2
3
4

Resurser & länkar

Uppgift: for-loopen

  1. Ulf har satt in 10 000kr på ett konto med 3 % årlig ränta, hur mycket pengar finns på kontot efter 15 år? Inga fler insättningar görs.
    Välj själv hur du vill skriva ut svaret, med en enda rad eller en rad för varje år.

While-loopen

While-loopen är den loopen där uttrycket ligger i fokus, här vet vi inte hur många gånger som en operation skall utföras men vi vet när vi skall avsluta den.

<?php
$i = 0;

while ($i < 5){
	echo "$i<br>";
	$i++;
}
?>

While-loopen ser lite annorlunda ut mot for-loopen. De tre argument som var så tydliga i for-loopen finner vi även här;

  1. På rad 2 får variabeln $i ett värde, i detta fall 0.
  2. På rad 4 sätter vi villkoret för loopen. De skall köras så länge som villkoret är uppfyllt, i detta fall så länge som $i<5.
  3. På rad 6 så ger vi varabeln $i ett nytt värde, vi ökar dess värde med 1. Hade vi inte gjort detta så hade vi fått en oändlig loop.

När alla instruktionerna inom måsvingarna har genomförts så kollar loopen om den kan köras igen genom att uttrycket testas.

Utskriften av exemplet blir då

0
1
2
3
4

Resurser & länkar

Uppgift: while-loopen

  1. Antalet råttor i en stad är 100 stycken, varje månad dubblas populationen av råttor, hur många månader dröjer det innan det finns en miljon råttor i staden?
    Välj själv hur du vill skriva ut svaret, med en enda rad eller en rad för varje månad.

do while-loopen

Do-while är väldigt lik en while-loop fast med en skillnad, denna loop kommer alltid köras minst en gång. Orsaken till detta är att villkoret kommer sist i loopen, efter att det redan har körts en gång. Inom php så är denna loop inte så extremt användbar, den gör sig bättre inom andra programmeringsspråk framförallt när man skapar menyer eller andra funktioner som alltid skall köras minst en gång.

<?php
$i = 0;

do{
	echo "$i<br>";
	$i++;
} while ($i < 5);
?>

Utskriften av exemplet blir då

0
1
2
3
4

Våra tre argument som vi nu känner igen finner vi även här;

  1. På rad 2 får variabeln $i ett värde, i detta fall 0.
  2. På rad 7 sätter vi villkoret för loopen. De skall köras så länge som villkoret är uppfyllt, i detta fall så länge som $i<5.
  3. På rad 6 så ger vi varabeln $i ett nytt värde, vi ökar dess värde med 1. Hade vi inte gjort detta så hade vi fått en oändlig loop.

När alla instruktionerna inom måsvingarna har genomförts så kollar loopen om den kan köras igen genom att uttrycket testas.

Resurser & länkar

Uppgift: do-while-loopen

  1. Lös uppgift 7 fast med do-whileloop, kolla att svaret blir det samma.

Jämförelse iterationer

Om vi jämför de olika iterationsstrukturerna så ser vi att grunden är den samma, det finns alltid ett startvärde (turkos), ett villkor (grönt) och någon form av förändring (gult).

Nu har jag tagit ett väldigt enkelt exempel men det går att applicera detta även på svårare exempel. Vi återkommer till det senare.

Nästlade iterationer

På samma sätt som vi kunde ha annan kod inne i ett kodblock på en selektion så kan vi göra det inom en iteration. Här kommer ett exempel på hur det fungerar.

<?php
$i = 0;

do{								// Yttre loop
	$j = $i;				// ge $j samma värde som $i
	while($j<5){		// kör så länge $j < 5 i inre loopen
		echo "$j ";		// skriv ut $j
		$j++;					// öka $j med 1
	}
	$i++;						// öka $i med 1
	echo "<br>";		// skriv ut <br>
} while ($i < 5);	// villkoret på yttre loopen
?>
0 1 2 3 4
1 2 3 4
2 3 4
3 4
4

Uppgift: do-while-loopen

Denna uppgift är lite svårare så gör den om du känner för det. Troligtvis kommer du fixa den med lite trixande. Använd gärna \n och \t för att strukturera upp tabellen, det gör det mycket enklare att felsöka.

  1. Bygg en enkel multiplikationstabell till valfritt tal, sluttalet bör inte vara mindre än 5 och kan begränsas till max 12. Lägg in multiplikationstabellen i en <table> och skapa korrekt html-syntax.

Extrauppgift: Iteration och selektion

Här kommer en uppgift där du behöver använda flera iterationer och selektioner för att lösa.

Uppgiften är att skapa en tabell med två kolumner som listar alla tal mellan 1 och 20. Alla tal som är jämnt delbara med 3 skall ha en annan bakgrundsfärg än de andra, samma gäller för de talen som är jämnt delbara med 5, fast dessa skall ha en tredje färg. I den andra kolumnen skall du rita ut lika många stjärnor som talet i kolumn ett är. Se exemplet nedan om du tycker det verkar oklart.
* Klurighet 1: hur gör du med tal som både är delbara med 3 och 5?
* Klurighet 2: Kan du färga hela raden och inte bara cellen?

1*
2**
3***
4****
5*****
6******
7*******
8********
9*********
10**********
11***********
12************
13*************
14**************
15***************
16****************
17*****************
18******************
19*******************
20********************

Foreach-loopen

De tre iterationer vi har tittat på kan vi styra på olika sätt, vi kan bestämma startvärdet, hur länge loopen skall fortgå och även hur stora steg vi skall ta. Men om vi vill loopa från start till slut, i tex en array, och göra något med alla komponenter så finns det ett enklare sätt. Då är foreach-loopen att föredra.

<?php
// skapar en array, kanske med tärningsslag
$array = array(3,3,6,5,1);

// Looar igenom hela arrayen med foreach
foreach($array as $a){
	echo "$a<br>";		// Skriver ut varje värde
}
?>

Vilket ger utskriften

3
3
6
5
1

foreach med index

Eftersom en array innehåller komponenter som har ett index så kan vi använda detta även i foreach-loopen. Vi kikar på ett gammalt exempel där vi lagrade riktnummer för några städer.

<?php
// Skapar en array med index som skall användas
$riktnr = array(
   "031" => "Göteborg",
   "040" => "Malmö",
   "07XX" => "Mobil",
   "08" => "Stockholm"
 );

// Skriver ut alla värden i arrayen
foreach($riktnr as $nr => $ort){
	echo "<p>$ort har riktnr $nr.</p>";
}
?>

Vilket ger utskriften

Göteborg har riktnr 031

Malmö har riktnr 040

Mobil har riktnr 07XX

Stockholm har riktnr 08

Resurser & länkar

Uppgift

  1. I förra momentets uppgift 10 så fick du i uppgift att skapa två olika arrayer med namn och mailadresser. Du skall nu med hjälp av foreach loopa igenom den ena arrayen och skapa en utskriven lista med alla namn och mailadresser.

break & continue

I alla loopar kan det ibland finnas anledning att avbryta loopen i det specifika varvet eller helt och hållet hoppa ur loopen. Då är break eller continue bra att använda.

break

Break gör vad den låter som, den avbryter loopen och låter sedan koden fortsätta efter

<?php
// loopar från 1 till 10
for($i=1; $i<=10; $i++){
	if($i%2 == 0){			// kollar om talet är jämnt
		break;						// Abryter loopen om sant
	}
	echo "$i<br>";			// skriver ut
}
?>

Notera % som i programmeringsvärlden heter modulus. Modulus är en räkneoperator som utför en heltalsdivision och ger resten som resultat. 4%2 blir då 0, eftersom 4 delat med 2 går jämnt upp och resten blir 0. 7%3 blir då 1, 7 går två gånger i 3 och kvar blir 1.
Utskriften blir då

1

continue

Continue avbryter det varvet som loopen just nu utför, men hoppar sedan vidare till nästa varv.

<?php
// loopar från 1 till 10
for($i=1; $i<=10; $i++){
	if($i%2 == 1){			// kollar om talet är ojämnt
		continue;						// Abryter loopen om sant
	}
	echo "$i<br>";			// skriver ut
}
?>

Utskriften blir då

2
4
6
8
10

Uppgift

  1. Du skall med hjälp av en iterator samt break och continue se till att skriva ut talen 1-20 med följande regler. Alla tal som är jämnt delbara med 3 skall inte skrivas ut, när du kommer till 15 så skall loopen avbrytas.

Utskriften skall bli

1
2
4
5
7
8
10
11
13
14

Redovisning

Redovisa detta moment på följande sätt;

  1. Lägg upp dina övningar på din hemsida. Lägg dem på en sida med tydliga förklaringar eller skapa flera sidor med olika uppgifter. Viktigt att jag, och andra, kan gå mellan sidorna så vi inte missar något.
  2. Länka sidan/sidorna från din samlingssida.
  3. Länka också till CSource och se till att jag den vägen kan se all din kod.
  4. I Wordpress så reflekterar du över ditt arbete, berätta vilka uppgifter du gjort och varför. Resonera kring om PHP är svårt eller enkelt och vad du har lärt dig samt vilka problem du eventuellt har haft. Länka också till den sidan, se sidorna, där dina exempeluppgifter finns.
    Frågestöd
    • Hur känns det att programmera i PHP, börjar du få koll på vad som händer och hur du kan styra koden?
    • Vilken del av detta moment var särskilt svårt? Hur gjorde du för att komma över de svårigheterna?
    • Vilka resurser har du använt dig av för att lära dig PHP? Någon av de som jag har länkat eller någon annan bra resurs? Har du tips på någon bra resurs så länka gärna denna.