- Kursmaterial
- Planering
- Arbete
- Kunskapsdokument
- Alla kurser
- Om Kursolle
3. Moment03 – Villkor
Momentets innehåll
I Moment02 lärde du dig att läsa in värden, lagra dem i variabler, göra beräkningar och skriva ut resultat. Nu ska du låta programmet välja vad som ska hända. Räcker pengarna till ett köp? Vilket pris gäller? Uppfyller användaren kraven?
I det här momentet lär du dig att:
- Jämföra värden och avgöra om ett villkor är sant eller falskt.
- Styra program med
if,else ifochelse. - Kombinera flera villkor och göra beräkningar i rätt ordning.
- Använda
switchför enkla, fasta alternativ. - Planera med pseudokod och testa att programmet ger rätt resultat.
Momentet avslutas med ett teoretiskt quiz och en praktisk diagnos.
3.1 Jämförelser och enkla val
Presentation









Hittills har dina program främst gjort samma saker i samma ordning. Med ett villkor kan programmet välja väg utifrån de värden det arbetar med. Ett villkor är en fråga som programmet kan besvara med sant eller falskt.
Efter den här lektionen ska du kunna jämföra två värden och skriva program som väljer mellan två alternativ.
Arbeta med ett exempel i taget
Kodexemplen visar innehållet i programmet. Om ditt projekt använder Main skriver du koden inuti den metoden. Kommentera bort tidigare kod när du provar ett nytt exempel, eller använd ett nytt projekt. Du ska inte klistra in alla exempel efter varandra.
3.1.1 Sant eller falskt
Datatypen bool har två möjliga värden: true (sant) och false (falskt). En jämförelse ger också ett sådant värde.
int poang = 12; bool klaratGransen = poang >= 10; Console.WriteLine(klaratGransen);
Utskrift
True
Uttrycket poang >= 10 frågar om poängen är större än eller lika med 10. Eftersom poängen är 12 blir resultatet true. Resultatet lagras i variabeln klaratGransen.
Ett uttryck som ger sant eller falskt kallas ett booleskt uttryck. I C#-kod skriver du true och false med små bokstäver. När värdena skrivs ut med Console.WriteLine() visas de som True och False.
3.1.2 Jämförelseoperatorer
En jämförelseoperator jämför värdet till vänster med värdet till höger.
| Operator | Betydelse | Exempel | Resultat |
|---|---|---|---|
== | Lika med | 5 == 5 | true |
!= | Inte lika med | 5 != 5 | false |
< | Mindre än | 5 < 8 | true |
> | Större än | 5 > 8 | false |
<= | Mindre än eller lika med | 5 <= 5 | true |
>= | Större än eller lika med | 5 >= 5 | true |
Tilldelning och jämförelse är olika saker
poang = 10; tilldelar variabeln värdet 10. poang == 10 jämför variabelns värde med 10. Använd två likhetstecken när du vill undersöka om två värden är lika.
Övning 3.1a – Sant eller falskt?
Förutsäg resultatet av varje utskrift innan du kör koden.
int a = 8; int b = 12; Console.WriteLine(a < b); Console.WriteLine(a == b); Console.WriteLine(a != b); Console.WriteLine(a >= 8); Console.WriteLine(b < 12); Console.WriteLine(b <= 12);
Kör programmet och jämför med dina svar. Ändra sedan a till 12. Vilka utskrifter ändras?
Lösningsförslag
När a är 8 blir utskrifterna:
Utskrift
True False True True False True
När a ändras till 12 ändras de tre första resultaten till False, True och False. De övriga är oförändrade.
3.1.3 Kör kod när ett villkor är sant – if
Med if kan du bestämma att viss kod bara ska köras när ett villkor är sant.
int temperatur = -3;
if (temperatur < 0)
{
Console.WriteLine("Det är minusgrader.");
}
Console.WriteLine("Temperaturkontrollen är klar.");
Utskrift
Det är minusgrader. Temperaturkontrollen är klar.
ifbetyder ”om”. Villkoret skrivs inom parenteser.- Klammerparenteserna
{ }avgränsar ett kodblock. - Koden i blocket körs om villkoret är sant. Annars hoppas blocket över.
- Den sista utskriften ligger efter blocket och körs oavsett villkorets resultat.
Indraget visar vilken kod som hör till villkoret. Vi använder alltid klammerparenteser runt våra villkorsblock, även när de bara innehåller en rad.
Övning 3.1b – Vilka rader körs?
- Utgå från temperaturprogrammet. Förutsäg utskriften när temperaturen är 4 och sedan när den är 0.
- Provkör med båda värdena.
- Ändra programmet så att det skriver ”Noll grader eller kallare.” när temperaturen är 0 eller lägre.
Lösningsförslag
I originalprogrammet skrivs bara ”Temperaturkontrollen är klar.” ut för både 4 och 0. Noll är inte mindre än noll.
int temperatur = 0;
if (temperatur <= 0)
{
Console.WriteLine("Noll grader eller kallare.");
}
Console.WriteLine("Temperaturkontrollen är klar.");
3.1.4 Välj mellan två alternativ – if och else
Ibland vill du göra en sak om villkoret är sant och något annat om det är falskt. Då använder du else, som betyder ”annars”.
Console.Write("Hur många poäng fick du? ");
int poang = Convert.ToInt32(Console.ReadLine());
if (poang >= 10)
{
Console.WriteLine("Du har nått poänggränsen.");
}
else
{
Console.WriteLine("Du har inte nått poänggränsen ännu.");
}
Console.WriteLine("Tack för ditt svar!");
Utskrift
Hur många poäng fick du? 10 Du har nått poänggränsen. Tack för ditt svar!
Programmet kör ett av de två blocken. Om poängen är minst 10 körs blocket efter if. Annars körs blocket efter else. Därefter fortsätter programmet med den sista utskriften.
else har inget eget villkor. Det fångar det andra fallet, alltså när villkoret i if är falskt.
Skriv inte semikolon efter villkoret
Skriv if (poang >= 10), utan semikolon direkt efter parentesen. Ett semikolon där avslutar if-satsens kropp med en tom sats. Det efterföljande blocket styrs då inte av villkoret.
Utskrifter och tilldelningar inne i blocket avslutas däremot med semikolon som vanligt.
Övning 3.1c – Ett villkor som inte fungerar
Programmet ska bara skriva ”Du har vunnit!” när poängen är minst 20, men med koden nedan visas meddelandet även vid 5 poäng.
int poang = 5;
if (poang >= 20);
{
Console.WriteLine("Du har vunnit!");
}
- Rätta felet.
- Lägg till ett alternativ som skriver ”Fortsätt samla poäng.” när poängen är under 20.
- Testa med 5, 20 och 25 poäng.
Lösningsförslag
Ta bort semikolonet direkt efter villkoret och lägg till else.
int poang = 5;
if (poang >= 20)
{
Console.WriteLine("Du har vunnit!");
}
else
{
Console.WriteLine("Fortsätt samla poäng.");
}
5 ger ”Fortsätt samla poäng.”. Både 20 och 25 ger ”Du har vunnit!”.
3.1.5 Planera med pseudokod
Innan du skriver C# kan du beskriva lösningen med pseudokod. Det är en plan med vanliga ord som hjälper dig att bestämma vad programmet ska göra. Pseudokoden kan inte köras av datorn.
Vi skriver en handling per rad, använder ord som LÄS IN, OM, ANNARS och SKRIV UT, och gör indrag för det som hör till ett villkor. SLUT OM visar var valet slutar.
Här är en plan för poängprogrammet:
Utskrift
LÄS IN poäng
OM poängen är minst 10
SKRIV UT att poänggränsen är nådd
ANNARS
SKRIV UT att poänggränsen inte är nådd
SLUT OM
SKRIV UT ett tackmeddelande
Beskriv själva regeln. ”OM poängen är minst 10” hjälper dig mer än ”kontrollera poängen”. Du behöver inte skriva pseudokod till varje liten övning, men den är ett stöd när du behöver reda ut en lösning.
3.1.6 Kombinera villkor och beräkningar
På en parkering är de första 60 minuterna gratis. Därefter kostar varje extra minut 2 kr. Programmet behöver därför först avgöra om parkeringstiden överstiger 60 minuter.
Console.Write("Hur många minuter har du parkerat? ");
int minuter = Convert.ToInt32(Console.ReadLine());
if (minuter > 60)
{
int extraMinuter = minuter - 60;
int kostnad = extraMinuter * 2;
Console.WriteLine($"Tid utöver gratisperioden: {extraMinuter} minuter.");
Console.WriteLine($"Att betala: {kostnad} kr.");
}
else
{
Console.WriteLine("Parkeringen är gratis.");
}
Utskrift
Hur många minuter har du parkerat? 75 Tid utöver gratisperioden: 15 minuter. Att betala: 30 kr.
Vid 75 minuter är villkoret sant. Programmet räknar först ut antalet minuter som kostar pengar: 75 - 60 = 15. Sedan beräknar det avgiften: 15 * 2 = 30 kr. Vid högst 60 minuter väljer programmet i stället else-blocket.
Ett villkorsblock kan alltså innehålla flera beräkningar och utskrifter. Alla rader i det valda blocket körs i ordning uppifrån och ner.
Variablerna extraMinuter och kostnad skapas och används i samma block. De kan inte användas efter blockets avslutande klammerparentes. I nästa lektion tittar vi mer på variabler tillsammans med olika val.
Övning 3.1d – Extra surf
I ett mobilabonnemang ingår 10 GB surf per månad. Varje GB över 10 kostar 20 kr extra. Skriv ett program som läser in hur många GB kunden har använt.
- Vid högst 10 GB ska programmet skriva att ingen extra avgift tillkommer.
- Vid mer än 10 GB ska programmet visa antalet GB över gränsen och den extra avgiften.
Du kan anta att användaren anger ett heltal som är 0 eller större. Räkna bara ut den extra avgiften, inte abonnemangets ordinarie pris.
Testa med 8, 10 och 13 GB. Bestäm förväntat resultat innan du kör programmet.
Lösningsförslag
Console.Write("Hur många GB har du använt? ");
int anvandSurf = Convert.ToInt32(Console.ReadLine());
if (anvandSurf > 10)
{
int extraSurf = anvandSurf - 10;
int extraAvgift = extraSurf * 20;
Console.WriteLine($"Surf över gränsen: {extraSurf} GB.");
Console.WriteLine($"Extra avgift: {extraAvgift} kr.");
}
else
{
Console.WriteLine("Ingen extra avgift tillkommer.");
}
8 och 10 GB ger ingen extra avgift. 13 GB ger 3 GB över gränsen och 60 kr extra.
3.1.7 Testa båda alternativen
En lyckad körning räcker inte för att veta att ett villkor fungerar. Testa värden som gör villkoret sant och värden som gör det falskt. Testa också exakt på gränsen, eftersom > och >= ger olika resultat där.
| Test av parkeringsprogrammet | Förväntat resultat |
|---|---|
| 59 minuter – strax under gränsen | Parkeringen är gratis. |
| 60 minuter – exakt på gränsen | Parkeringen är gratis. |
| 61 minuter – strax över gränsen | 1 minut utöver gratisperioden. Att betala: 2 kr. |
Om resultatet blir fel: kontrollera jämförelseoperatorn, värdet du jämför med och vilka rader som ligger inuti respektive block.
Nu skriver du egna program
Uppgifterna nedan är fristående. Börja från tom kod i ett nytt projekt eller kommentera bort tidigare kod. I den här lektionen får du anta att användaren skriver giltiga tal som är 0 eller större. Du behöver inte hantera bokstäver där programmet förväntar sig ett tal.
Använd gärna Convert.ToDouble(Console.ReadLine()) när belopp kan innehålla decimaler. I C#-koden skrivs decimaler med punkt. Vid inmatning följer decimaltecknet datorns inställningar; på en svensk dator används vanligtvis komma. F2 i en interpolerad utskrift visar två decimaler, till exempel {belopp:F2}.
Uppgift: m03u01 – Räcker pengarna?
Skapa ett program som hjälper en kund att se om pengarna räcker till en vara.
Krav på programmet
- Fråga vad varan kostar och hur mycket pengar kunden har.
- Om pengarna räcker ska programmet tala om det och visa hur mycket som blir över.
- Om pengarna inte räcker ska programmet visa hur mycket som saknas.
- Om kunden har exakt rätt belopp räcker pengarna och 0 kronor blir över.
- Visa det beräknade beloppet med två decimaler.
Exempel på körning
Utskrift
Vad kostar varan? 249 Hur mycket pengar har du? 300 Pengarna räcker. Du får 51,00 kr över.
Utskrift
Vad kostar varan? 249 Hur mycket pengar har du? 200 Det saknas 49,00 kr.
Testa din lösning
Testa när pengarna räcker, när de inte räcker och när kunden har exakt rätt belopp. Försök lösa uppgiften innan du öppnar lösningsförslaget.
Lösningsförslag
Console.Write("Vad kostar varan? ");
double pris = Convert.ToDouble(Console.ReadLine());
Console.Write("Hur mycket pengar har du? ");
double pengar = Convert.ToDouble(Console.ReadLine());
if (pengar >= pris)
{
double pengarKvar = pengar - pris;
Console.WriteLine($"Pengarna räcker. Du får {pengarKvar:F2} kr över.");
}
else
{
double saknas = pris - pengar;
Console.WriteLine($"Det saknas {saknas:F2} kr.");
}
Jämförelsen inkluderar likhet eftersom exakt rätt belopp också räcker. I varje block beräknas skillnaden så att det utskrivna beloppet blir 0 eller positivt.
Uppgift: m03u02 – Fri frakt eller fraktavgift?
En webbutik vill visa vad kunden ska betala för sina varor inklusive frakt. Skapa ett program som räknar ut totalpriset.
Krav på programmet
- Fråga efter varornas sammanlagda pris före frakt.
- Om varorna kostar minst 500 kr är frakten gratis.
- Om varorna kostar mindre än 500 kr tillkommer 49 kr i frakt.
- Visa fraktavgiften och totalpriset med två decimaler.
Skriv en kort pseudokod innan du börjar med C#-koden. Beskriv inmatningen, beslutet och vad som ska beräknas och skrivas ut.
Exempel på körning
Utskrift
Vad kostar varorna? 350 Frakt: 49,00 kr Totalt att betala: 399,00 kr
Utskrift
Vad kostar varorna? 500 Frakt: 0,00 kr Totalt att betala: 500,00 kr
Testa din lösning
Testa med varupriserna 499, 500 och 501 kr. Skriv ner vilket totalpris du förväntar dig innan du kör programmet. Kom ihåg att gränsen gäller varornas pris före frakt.
Lösningsförslag
Utskrift
LÄS IN varornas pris
OM varornas pris är minst 500 kr
SKRIV UT att frakten är 0 kr
SKRIV UT varornas pris som totalpris
ANNARS
BERÄKNA totalpriset som varornas pris plus 49 kr
SKRIV UT att frakten är 49 kr
SKRIV UT totalpriset
SLUT OM
Console.Write("Vad kostar varorna? ");
double varupris = Convert.ToDouble(Console.ReadLine());
if (varupris >= 500)
{
Console.WriteLine($"Frakt: {0:F2} kr");
Console.WriteLine($"Totalt att betala: {varupris:F2} kr");
}
else
{
double frakt = 49;
double totalpris = varupris + frakt;
Console.WriteLine($"Frakt: {frakt:F2} kr");
Console.WriteLine($"Totalt att betala: {totalpris:F2} kr");
}
Testerna ger totalpriserna 548 kr, 500 kr och 501 kr. Att totalpriset minskar när varupriset går från 499 till 500 kr följer av butikens fraktregel.
3.1.8 Sammanfattning
- En jämförelse ger ett booleskt värde:
trueellerfalse. =tilldelar ett värde.==jämför två värden.ifkör ett kodblock när villkoret är sant.elsekör ett alternativt block när villkoret är falskt.- Klammerparenteserna visar vad som hör till ett block. Koden efter hela valet körs oavsett vilken väg som valdes.
- Pseudokod hjälper dig att planera beslut och beräkningar.
- Testa båda alternativen och värden precis vid gränsen.
3.2 Flera alternativ och oberoende villkor
Presentation









I avsnitt 3.1 använde du if och else för att välja mellan två alternativ. Nu ska du skriva program med fler möjliga utfall. Du ska också skilja på situationer där programmet ska välja ett enda alternativ och situationer där flera saker kan hända vid samma körning.
Efter avsnittet ska du kunna
- Använda
else ifför att välja mellan flera alternativ. - Ordna villkor så att rätt alternativ väljs, även vid intervallgränser.
- Avgöra när du behöver en villkorskedja och när du behöver separata
if-satser. - Tilldela en variabel olika värden i olika grenar och använda värdet efter valet.
Arbeta med ett kodexempel i taget. Skriv koden inuti Main om ditt projekt använder den strukturen. Kommentera bort tidigare kod eller använd ett nytt projekt när du börjar på nästa exempel.
3.2.1 Fler alternativ med else if
Ett program ska beskriva en temperatur som minusgrader, exakt noll grader eller plusgrader. Det finns tre möjliga utfall. Med else if kan du lägga till ett nytt villkor när det första är falskt.
Console.Write("Ange temperaturen i hela grader: ");
int temperatur = Convert.ToInt32(Console.ReadLine());
if (temperatur < 0)
{
Console.WriteLine("Det är minusgrader.");
}
else if (temperatur == 0)
{
Console.WriteLine("Det är exakt noll grader.");
}
else
{
Console.WriteLine("Det är plusgrader.");
}
Console.WriteLine("Temperaturkontrollen är klar.");
Utskrift
Ange temperaturen i hela grader: 0 Det är exakt noll grader. Temperaturkontrollen är klar.
- Först kontrollerar programmet om temperaturen är under 0.
- Om det villkoret är falskt kontrollerar programmet om temperaturen är exakt 0.
- Om båda villkoren är falska kör programmet
else-blocket. - Efter valet fortsätter programmet med den sista utskriften.
Du kan använda flera else if i samma kedja. Varje else if har ett eget villkor. Ett avslutande else saknar villkor och tar hand om det som återstår.
Övning 3.2a – Vilken gren väljs?
Utgå från temperaturprogrammet. Förutsäg resultatet för -4, 0 och 6 innan du provkör.
Vilken rad skrivs ut vid alla tre körningarna? Förklara varför.
Lösningsförslag
| Temperatur | Valt block | Första utskrift |
|---|---|---|
| -4 | if | Det är minusgrader. |
| 0 | else if | Det är exakt noll grader. |
| 6 | else | Det är plusgrader. |
”Temperaturkontrollen är klar.” skrivs ut vid alla tre körningarna eftersom raden ligger efter hela villkorskedjan.
3.2.2 Första sanna villkoret avgör
När programmet hittar ett sant villkor i en kedja kör det blocket. Resten av kedjan hoppas över. Därför spelar ordningen mellan villkoren roll.
Ett spel ger guldnivå från 100 poäng och silvernivå från 50 poäng. Lägre poäng ger bronsnivå. Följande kod har ett logiskt fel:
int poang = 120;
if (poang >= 50)
{
Console.WriteLine("Silvernivå");
}
else if (poang >= 100)
{
Console.WriteLine("Guldnivå");
}
else
{
Console.WriteLine("Bronsnivå");
}
Utskrift
Silvernivå
120 är större än eller lika med 50, så programmet väljer det första blocket. Det kommer aldrig fram till kontrollen för guldnivå. Alla poäng som räcker till guld uppfyller också det första villkoret.
Övning 3.2b – Rätta ordningen
Ändra villkorskedjan så att rätt nivå visas. Använd fortfarande if, else if och else.
Testa med 40, 75 och 120 poäng. Programmet ska visa brons, silver respektive guld.
Lösningsförslag
int poang = 120;
if (poang >= 100)
{
Console.WriteLine("Guldnivå");
}
else if (poang >= 50)
{
Console.WriteLine("Silvernivå");
}
else
{
Console.WriteLine("Bronsnivå");
}Guldgränsen kontrolleras först. När programmet når silvervillkoret vet vi redan att poängen är under 100.
Ordna efter de regler som ska gälla
Vid kontroller av typen ”minst” kan du ofta börja med den högsta gränsen. Vid kontroller av typen ”mindre än” kan du ofta börja med den lägsta. Följ alltid kedjan uppifrån och kontrollera vilka värden som når varje gren.
3.2.3 Intervall och gränsvärden
En villkorskedja kan dela upp värden i intervall. I följande exempel delas temperaturen upp i under 10 grader, från 10 till under 20 grader, och 20 grader eller mer.
Console.Write("Ange temperaturen i hela grader: ");
int temperatur = Convert.ToInt32(Console.ReadLine());
if (temperatur < 10)
{
Console.WriteLine("Kallt");
}
else if (temperatur < 20)
{
Console.WriteLine("Milt");
}
else
{
Console.WriteLine("Varmt");
}
Utskrift
Ange temperaturen i hela grader: 15 Milt
I den andra grenen behöver vi bara skriva temperatur < 20. För att komma dit måste det första villkoret ha varit falskt. Temperaturen är därför redan känd som minst 10 grader.
| Gren | Temperaturer som når grenen |
|---|---|
if (temperatur < 10) | Under 10 grader |
else if (temperatur < 20) | Minst 10 men under 20 grader |
else | 20 grader eller mer |
Testa strax under, exakt på och strax över varje gräns. Här behöver du kontrollera både 10 och 20 grader.
Övning 3.2c – Testa intervallen
Skriv vilket resultat du förväntar dig för 9, 10, 11, 19, 20 och 21 grader. Provkör sedan programmet.
Ändra det första villkoret till temperatur <= 10. Vilket av testfallen ändras?
Lösningsförslag
| Temperatur | Resultat med originalkoden |
|---|---|
| 9 | Kallt |
| 10 | Milt |
| 11 | Milt |
| 19 | Milt |
| 20 | Varmt |
| 21 | Varmt |
Med <= 10 blir resultatet för exakt 10 grader ”Kallt”. De andra testfallen är oförändrade.
3.2.4 Ett alternativ eller flera oberoende beslut?
En villkorskedja passar när programmet ska välja ett av flera alternativ, exempelvis en prisgrupp. Separata if-satser passar när flera regler kan gälla samtidigt.
På en utflykt kan du behöva både en varm tröja och en regnjacka. Då ska programmet kontrollera båda behoven.
int temperatur = 7;
string regn = "ja";
if (temperatur < 10)
{
Console.WriteLine("Ta med en varm tröja.");
}
if (regn == "ja")
{
Console.WriteLine("Ta med en regnjacka.");
}
Utskrift
Ta med en varm tröja. Ta med en regnjacka.
Båda villkoren är sanna, så båda meddelandena visas. Den andra kontrollen görs oavsett hur den första kontrollen gick.
Här används == för att jämföra text. regn == "ja" är sant när variabeln innehåller exakt texten "ja".
Textsvar i det här avsnittet
Vi antar att användaren svarar exakt ja eller nej med små bokstäver. C# skiljer på stora och små bokstäver i den här jämförelsen. I nästa avsnitt lär du dig att hantera exempelvis Ja och JA på samma sätt.
Övning 3.2d – Vad händer med else if?
Utgå från utflyktsprogrammet ovan.
- Byt den andra
if-satsen tillelse if. - Förutsäg utskriften när temperaturen är 7 och det regnar. Provkör.
- Ändra temperaturen till 15 och behåll regnsvaret
"ja". Vad visas nu? - Återställ till två separata
if-satser. Förklara varför det passar bättre för packningsråden.
Lösningsförslag
Med else if visas bara rådet om en varm tröja vid 7 grader och regn. Det första villkoret är sant, så programmet hoppar över resten av kedjan.
Vid 15 grader och regn är första villkoret falskt. Då kontrolleras regnsvaret och rådet om en regnjacka visas.
Två separata if-satser passar eftersom båda råden kan behövas samtidigt.
| Struktur | Hur fungerar den? | Passar när … |
|---|---|---|
if / else if / else | Ett block väljs. | alternativen utesluter varandra. |
Flera separata if | Varje villkor kontrolleras. Noll, ett eller flera block kan köras. | flera regler kan gälla samtidigt. |
3.2.5 Använd resultatet efter villkoret
Ibland vill du välja ett värde i en villkorskedja och sedan fortsätta med en gemensam beräkning eller utskrift. Då behöver variabeln finnas tillgänglig även efter valet.
Ett museum har två biljettpriser. Den som är under 18 år betalar 60 kr och övriga betalar 100 kr. Vi deklarerar variabeln biljettpris före villkoret och tilldelar den rätt värde inuti respektive gren.
Console.Write("Hur gammal är besökaren? ");
int alder = Convert.ToInt32(Console.ReadLine());
int biljettpris;
if (alder < 18)
{
biljettpris = 60;
}
else
{
biljettpris = 100;
}
Console.WriteLine($"Biljettpris: {biljettpris} kr.");
Utskrift
Hur gammal är besökaren? 16 Biljettpris: 60 kr.
int biljettpris;deklarerar variabeln före valet.biljettpris = 60;ochbiljettpris = 100;tilldelar ett värde. Skriv inteintigen när du använder den redan deklarerade variabeln.- Efter valet använder utskriften det värde som den valda grenen tilldelade.
Variabeln måste finnas och ha ett värde
En variabel som du deklarerar inuti ett villkorsblock kan inte användas efter blocket. Deklarera den före valet om den behövs efteråt.
C# kräver också att variabeln har fått ett värde innan du använder den. I exemplet ovan tilldelar både if och else ett värde. Om du tar bort else finns en väg där variabeln inte får något värde, och programmet går då inte att kompilera.
Ibland finns ett naturligt startvärde, exempelvis int avgift = 0;. Använd ett sådant värde när det stämmer med programmets regler, inte bara för att få bort ett felmeddelande.
Övning 3.2e – En gemensam beräkning
Utgå från museiprogrammet. Läs även in hur många biljetter kunden vill köpa. Alla biljetter i köpet ska ha samma pris som den angivna besökarens biljett.
Beräkna totalpriset efter villkorskedjan och skriv ut det. Du får anta att antalet biljetter är ett positivt heltal.
Testa med 16 år och 3 biljetter samt med 18 år och 2 biljetter.
Lösningsförslag
Console.Write("Hur gammal är besökaren? ");
int alder = Convert.ToInt32(Console.ReadLine());
Console.Write("Hur många biljetter vill du köpa? ");
int antal = Convert.ToInt32(Console.ReadLine());
int biljettpris;
if (alder < 18)
{
biljettpris = 60;
}
else
{
biljettpris = 100;
}
int totalpris = biljettpris * antal;
Console.WriteLine($"Totalt att betala: {totalpris} kr.");16 år och 3 biljetter ger 180 kr. 18 år och 2 biljetter ger 200 kr.
Nu skriver du egna program
Uppgifterna nedan är fristående. Börja från tom kod. Du får anta att användaren anger giltiga heltal och följer instruktionerna för textsvar. Du behöver inte hantera bokstäver där programmet förväntar sig ett tal.
Planera gärna med pseudokod. Här är det särskilt viktigt att avgöra om programmet ska välja ett enda alternativ eller kontrollera flera oberoende regler.
Uppgift: m03u03 – Biljettkassan
En biograf behöver ett program som bestämmer biljettpriset utifrån besökarens ålder.
| Ålder | Biljettpris |
|---|---|
| 0–6 år | 0 kr |
| 7–17 år | 60 kr |
| 18–64 år | 100 kr |
| 65 år eller äldre | 70 kr |
Krav på programmet
- Läs in besökarens ålder som ett heltal. Du får anta att åldern är 0 eller större.
- Välj biljettpris med en sammanhängande
if / else if / else-kedja. - Deklarera en variabel för biljettpriset före kedjan och tilldela värdet i den valda grenen.
- Skriv ut biljettpriset med en gemensam utskrift efter kedjan.
Exempel på körning
Utskrift
Hur gammal är besökaren? 17 Biljettpris: 60 kr.
Utskrift
Hur gammal är besökaren? 65 Biljettpris: 70 kr.
Testa din lösning
Testa med 0, 6, 7, 17, 18, 64 och 65 år. Bestäm rätt pris från tabellen innan du provkör.
Lösningsförslag
Console.Write("Hur gammal är besökaren? ");
int alder = Convert.ToInt32(Console.ReadLine());
int biljettpris;
if (alder < 7)
{
biljettpris = 0;
}
else if (alder < 18)
{
biljettpris = 60;
}
else if (alder < 65)
{
biljettpris = 100;
}
else
{
biljettpris = 70;
}
Console.WriteLine($"Biljettpris: {biljettpris} kr.");När programmet når en senare gren är de tidigare villkoren redan falska. Därför behövs bara den övre gränsen i varje jämförelse. Testfallen ska ge 0, 0, 60, 60, 100, 100 och 70 kr.
Uppgift: m03u04 – Packningshjälpen
Skapa en packningshjälp för en utflykt. Programmet ska ge råd utifrån vädret och utflyktens längd. Flera råd kan behövas vid samma tillfälle.
Krav på programmet
- Läs in temperaturen som ett heltal. Temperaturen kan vara negativ.
- Fråga om det väntas regn. Du får anta svaret
jaellernejmed små bokstäver. - Läs in hur många hela timmar utflykten varar. Du får anta ett positivt heltal.
- Vid temperatur under 10 grader ska programmet rekommendera en varm tröja.
- Om det väntas regn ska programmet rekommendera en regnjacka.
- Vid en utflykt på minst 3 timmar ska programmet rekommendera matsäck.
- Programmet ska alltid rekommendera en vattenflaska.
- Alla råd som stämmer ska visas en gång, i ordningen varm tröja, regnjacka, matsäck och sist vattenflaska. Använd separata
if-satser för de villkorade råden.
Exempel på körning
Utskrift
Hur många grader väntas? 7 Väntas regn (ja/nej)? ja Hur många timmar varar utflykten? 4 Ta med en varm tröja. Ta med en regnjacka. Ta med matsäck. Ta med en vattenflaska.
Utskrift
Hur många grader väntas? 15 Väntas regn (ja/nej)? nej Hur många timmar varar utflykten? 2 Ta med en vattenflaska.
Planera och testa
Skriv först pseudokod. Var ska rådet om vattenflaskan stå för att det alltid ska visas?
Testa att alla råd kan visas och att bara vattenflaskan kan visas. Testa sedan varje villkor för sig. Kontrollera särskilt exakt 10 grader och exakt 3 timmar.
Lösningsförslag
Varje OM i pseudokoden är ett eget beslut:
Utskrift
LÄS IN temperatur
LÄS IN om det väntas regn
LÄS IN antal timmar
OM temperaturen är under 10 grader
SKRIV UT råd om varm tröja
SLUT OM
OM det väntas regn
SKRIV UT råd om regnjacka
SLUT OM
OM utflykten varar minst 3 timmar
SKRIV UT råd om matsäck
SLUT OM
SKRIV UT råd om vattenflaska
Console.Write("Hur många grader väntas? ");
int temperatur = Convert.ToInt32(Console.ReadLine());
Console.Write("Väntas regn (ja/nej)? ");
string regn = Console.ReadLine();
Console.Write("Hur många timmar varar utflykten? ");
int timmar = Convert.ToInt32(Console.ReadLine());
if (temperatur < 10)
{
Console.WriteLine("Ta med en varm tröja.");
}
if (regn == "ja")
{
Console.WriteLine("Ta med en regnjacka.");
}
if (timmar >= 3)
{
Console.WriteLine("Ta med matsäck.");
}
Console.WriteLine("Ta med en vattenflaska.");Vid exakt 10 grader visas inget råd om varm tröja. Vid exakt 3 timmar visas rådet om matsäck. Vattenflaskan står utanför villkorsblocken och visas alltid.
3.2.6 Sammanfattning
else iflägger till ett alternativ med ett eget villkor.- En villkorskedja väljer det första block vars villkor är sant. Med ett avslutande
elseväljs alltid ett block. - Villkorens ordning avgör vilka värden som når de senare grenarna.
- Separata
if-satser kontrollerar flera oberoende regler. Flera block kan köras. - En variabel som behövs efter valet deklareras före det och måste ha fått ett värde innan den används.
- Testa på båda sidor om varje gräns och exakt på gränsen.
3.3 Kombinera villkor
Presentation








I 3.2 valde du mellan flera alternativ och använde separata if-satser när flera saker kunde hända. Nu ska du kombinera flera krav i samma villkor. Du ska också bearbeta textsvar så att extra blanksteg och stora bokstäver inte påverkar jämförelsen.
Efter avsnittet ska du kunna
- Använda
&&när båda kraven måste vara uppfyllda. - Använda
||när minst ett krav måste vara uppfyllt. - Använda en boolesk variabel direkt i ett villkor och vända värdet med
!. - Bearbeta textsvar med
Trim()ochToLower(). - Gruppera villkor med parenteser och testa olika kombinationer.
Skriv koden inuti Main om ditt projekt använder den strukturen. Arbeta med ett exempel i taget. Kommentera bort tidigare kod eller använd ett nytt projekt.
3.3.1 Båda kraven måste vara uppfyllda – &&
En aktivitet är öppen för deltagare från 13 till och med 17 år. Åldern måste vara minst 13 och högst 17. Operatorn && betyder och. Hela villkoret är sant bara när båda jämförelserna är sanna.
Console.Write("Hur gammal är du? ");
int alder = Convert.ToInt32(Console.ReadLine());
if (alder >= 13 && alder <= 17)
{
Console.WriteLine("Du är i rätt åldersgrupp.");
}
else
{
Console.WriteLine("Du är utanför åldersgruppen.");
}
Utskrift
Hur gammal är du? 15 Du är i rätt åldersgrupp.
| Del av villkoret | Betydelse vid 15 år |
|---|---|
| alder >= 13 | 15 är minst 13: sant |
| alder <= 17 | 15 är högst 17: sant |
| alder >= 13 && alder <= 17 | Båda är sanna: hela villkoret är sant |
Varje jämförelse måste vara fullständig
Skriv alder >= 13 && alder <= 17. I C# kan du inte skriva intervallet som 13 <= alder <= 17. Variabeln behöver vara med i båda jämförelserna.
Övning 3.3a – Testa båda gränserna
Förutsäg resultatet för 12, 13, 17 och 18 år. Skriv också om var och en av jämförelserna är sann eller falsk. Provkör sedan.
Varför räcker det inte att bara kontrollera alder >= 13?
Lösningsförslag
| Ålder | Minst 13 | Högst 17 | Rätt åldersgrupp |
|---|---|---|---|
| 12 | Falskt | Sant | Nej |
| 13 | Sant | Sant | Ja |
| 17 | Sant | Sant | Ja |
| 18 | Sant | Falskt | Nej |
Utan den övre gränsen skulle även personer som är 18 år eller äldre godkännas.
3.3.2 Minst ett krav måste vara uppfyllt – ||
En besökare får rabatt om personen är student eller pensionär. Operatorn || betyder eller. Hela villkoret är sant när minst ett av kraven är uppfyllt. Det är också sant när båda är uppfyllda.
Här använder vi två booleska variabler med färdiga värden. De beskriver besökarens situation. En boolesk variabel innehåller redan true eller false och kan därför användas direkt i ett villkor.
bool arStudent = true;
bool arPensionar = false;
if (arStudent || arPensionar)
{
Console.WriteLine("Du får rabatt.");
}
else
{
Console.WriteLine("Du betalar ordinarie pris.");
}
Utskrift
Du får rabatt.
| Första kravet | Andra kravet | &&: båda | ||: minst ett |
|---|---|---|---|
| false | false | false | false |
| false | true | false | true |
| true | false | false | true |
| true | true | true | true |
Med && skulle besökaren behöva vara både student och pensionär. Med || räcker det att vara det ena. En enda if-sats ger rabattbeskedet en gång, även när båda värdena är sanna.
Övning 3.3b – Och eller eller?
- Kör rabattprogrammet med alla fyra kombinationer av
trueochfalse. - Byt
||till&&. Vilka kombinationer ändrar resultat? - Förklara varför två separata
if-satser med samma rabattutskrift kan ge ett oönskat resultat.
Lösningsförslag
Med || får besökaren rabatt i alla fall utom när båda värdena är falska. Med && krävs att båda är sanna. Resultatet ändras alltså i de två fall där exakt ett värde är sant.
Två separata if-satser kan skriva samma rabattbesked två gånger när personen både är student och pensionär.
3.3.3 Booleska värden och motsatsen – !
En boolesk variabel passar bra för ett tillstånd, exempelvis om ett evenemang är slutsålt. if (slutsalt) betyder att blocket körs när slutsalt är sant. Du behöver inte skriva slutsalt == true.
Operatorn ! betyder inte och vänder ett booleskt värde: sant blir falskt och falskt blir sant.
bool slutsalt = false;
if (!slutsalt)
{
Console.WriteLine("Det finns biljetter kvar.");
}
else
{
Console.WriteLine("Evenemanget är slutsålt.");
}
Utskrift
Det finns biljetter kvar.
Variabeln innehåller false. Uttrycket !slutsalt blir därför true, och det första blocket körs. Uttrycket ändrar inte värdet i variabeln.
Ett villkor ska ge sant eller falskt
En jämförelse som svar == "ja" ger ett booleskt värde. Variabeln slutsalt innehåller redan ett sådant värde. Båda kan användas direkt i ett villkor.
! vänder ett booleskt värde. != är jämförelseoperatorn ”inte lika med”, exempelvis alder != 18.
Övning 3.3c – När körs blocket?
Utgå från bool slutsalt = false;. Förklara med ord vad slutsalt och !slutsalt betyder som villkor. Förutsäg utskriften från programmet och provkör.
Ändra sedan variabeln till true. Vad visas nu? Har uttrycket !slutsalt ändrat variabelns innehåll?
Lösningsförslag
Med false är evenemanget inte slutsålt. !slutsalt är sant och programmet skriver att biljetter finns kvar. Med true är !slutsalt falskt och else skriver att evenemanget är slutsålt.
Uttrycket vänder bara värdet när villkoret beräknas. Variabelns innehåll ändras inte.
3.3.4 Bearbeta inmatad text före jämförelsen
En användare kan skriva ja, Ja eller JA . Vi kan bearbeta svaret så att dessa inmatningar behandlas på samma sätt.
Trim()tar bort blanksteg och andra tomrum före och efter texten.ToLower()gör texten till gemener, alltså små bokstäver.
Vi börjar med ett steg per rad för att se vad som händer:
Console.Write("Vill du fortsätta (ja/nej)? ");
string svar = Console.ReadLine();
svar = svar.Trim();
svar = svar.ToLower();
if (svar == "ja")
{
Console.WriteLine("Du valde att fortsätta.");
}
else
{
Console.WriteLine("Du valde inte ja.");
}
| Steg | Textens innehåll, visat mellan citattecken |
|---|---|
| Inmatning | " JA " |
| Efter Trim() | "JA" |
| Efter ToLower() | "ja" |
Citattecknen i tabellen visar var texten börjar och slutar. De ingår inte i svaret. Metoderna ger tillbaka en bearbetad sträng. Tilldelningen med = gör att variabeln behåller den nya texten.
När du förstår stegen kan du skriva dem på samma rad:
svar = svar.Trim().ToLower();
Först körs Trim(). Därefter körs ToLower() på resultatet. Vi jämför sedan svaret direkt i if. Ingen extra boolesk variabel behövs för denna enda kontroll.
Vad bearbetningen inte gör
Trim() tar inte bort mellanslag inne i texten. "j a" blir alltså inte "ja". Bearbetningen rättar inte heller stavfel eller avgör om svaret är giltigt.
I uppgifterna får du anta att användaren följer instruktionen och svarar ja eller nej, men kan använda stora bokstäver och extra blanksteg runt svaret. Vi arbetar med att fråga igen när vi kommer till loopar.
Övning 3.3d – Samma svar på olika sätt
Kör programmet med ja, Ja, JA, ja och nej. Prova även j a och en tom rad. Förutsäg resultatet före varje körning.
Ändra sedan villkoret så att även svaret j räknas som ja. Behåll textbearbetningen.
Lösningsförslag
De fyra första svaren blir "ja" och ger ”Du valde att fortsätta.” Svaret nej, texten j a och en tom rad är inte lika med "ja" och ger ”Du valde inte ja.” En tom rad är en tom sträng.
if (svar == "ja" || svar == "j")
{
Console.WriteLine("Du valde att fortsätta.");
}
else
{
Console.WriteLine("Du valde inte ja.");
}Med den nya jämförelsen accepteras också J och j efter bearbetningen. Varje sida om || är en fullständig jämförelse.
3.3.5 Parenteser gör kombinationen tydlig
Ibland innehåller en regel både ”och” och ”eller”. En butik ger rabatt till den som är medlem och dessutom antingen har en rabattkod eller handlar under en kampanj.
Parenteserna visar vilka alternativ som hör ihop:
bool arMedlem = true;
bool harRabattkod = false;
bool kampanj = true;
if (arMedlem && (harRabattkod || kampanj))
{
Console.WriteLine("Du får rabatt.");
}
else
{
Console.WriteLine("Du betalar ordinarie pris.");
}
Utskrift
Du får rabatt.
- Parentesen beskriver kravet ”rabattkod eller kampanj”. Med värdena ovan är det uppfyllt.
- Medlemskap krävs också. Det kravet är uppfyllt.
- Hela uttrycket är därför sant.
Beskriv gärna delen inom parentes med ord först. Du behöver inte lära dig långa blandningar av operatorer utantill.
Parenteserna påverkar betydelsen
&& har högre prioritet än ||. Utan parenteserna skulle arMedlem && harRabattkod || kampanj betyda (arMedlem && harRabattkod) || kampanj. Då skulle en kampanj ge rabatt även till den som inte är medlem. Det stämmer inte med butikens regel.
Övning 3.3e – Vilka får rabatt?
Förutsäg resultatet för fallen nedan och testa sedan. Förklara särskilt varför en person utan medlemskap inte får rabatt under kampanjen.
| Medlem | Rabattkod | Kampanj |
|---|---|---|
| true | false | true |
| true | true | false |
| true | false | false |
| false | false | true |
Lösningsförslag
Resultaten blir rabatt, rabatt, ordinarie pris och ordinarie pris. Medlemskapet ligger som ett eget krav tillsammans med &&. Därför räcker det inte med enbart kampanj.
Nu skriver du egna program
Börja från tom kod och skriv kort pseudokod före varje uppgift. Du får anta giltiga heltal och ja/nej-svar. Textsvaren kan ha stora bokstäver och extra blanksteg före eller efter. Bearbeta svaren innan du jämför dem.
Testa både när kraven uppfylls och när något krav inte uppfylls. Skriv det förväntade resultatet innan du kör programmet.
Uppgift: m03u05 – Tillträde till verkstaden
En verkstad kräver att deltagaren är minst 15 år och har gått säkerhetsintroduktionen. Båda kraven måste vara uppfyllda.
Krav på programmet
- Läs in åldern som ett heltal som är 0 eller större.
- Fråga om personen har gått säkerhetsintroduktionen. Svaret ska vara ja eller nej.
- Bearbeta svaret med
Trim()ochToLower(). - Använd
&&för att kontrollera båda kraven i samma villkor. - Visa ett tydligt besked om personen får delta. Du behöver inte ange vilket krav som saknas.
Exempel på körning
Utskrift
Hur gammal är du? 15 Har du gått säkerhetsintroduktionen (ja/nej)? JA Du får delta i verkstaden.
Testa din lösning
| Ålder | Svar, mellan citattecken | Förväntat resultat |
|---|---|---|
| 14 | "ja" | Får inte delta |
| 15 | "ja" | Får delta |
| 16 | "ja" | Får delta |
| 15 | "nej" | Får inte delta |
| 14 | "nej" | Får inte delta |
| 15 | " JA " | Får delta |
Lösningsförslag
Utskrift
LÄS IN ålder
LÄS IN svar om säkerhetsintroduktion
TA BORT blanksteg runt svaret
GÖR svaret till gemener
OM åldern är minst 15 OCH svaret är ja
SKRIV UT att personen får delta
ANNARS
SKRIV UT att personen inte får delta
SLUT OMConsole.Write("Hur gammal är du? ");
int alder = Convert.ToInt32(Console.ReadLine());
Console.Write("Har du gått säkerhetsintroduktionen (ja/nej)? ");
string svar = Console.ReadLine();
svar = svar.Trim().ToLower();
if (alder >= 15 && svar == "ja")
{
Console.WriteLine("Du får delta i verkstaden.");
}
else
{
Console.WriteLine("Du får inte delta i verkstaden.");
}Åldern 15 ingår eftersom jämförelsen använder >=. Ett ja-svar räcker inte om deltagaren är för ung. Tillräcklig ålder räcker inte om introduktionen saknas.
Uppgift: m03u06 – Spelkvällens entré
En spelkväll kostar normalt 80 kr per person. Studenter eller föreningsmedlemmar betalar 50 kr. Den som både är student och medlem betalar också 50 kr.
Ett köp kan gälla flera personer. I den här uppgiften har alla personer i köpet samma förutsättningar och betalar därför samma pris.
Krav på programmet
- Läs in om besökaren är student och om besökaren är föreningsmedlem. Använd två ja/nej-frågor.
- Bearbeta båda svaren med
Trim()ochToLower(). - Läs in antal personer som ett positivt heltal.
- Använd
||för att avgöra om rabattpriset gäller. Jämför textsvaren direkt i villkoret. - Deklarera en variabel för biljettpriset före valet och tilldela priset i respektive gren.
- Beräkna totalpriset efter hela villkorskedjan.
- Visa pris per person och totalpris i hela kronor.
Exempel på körning
Utskrift
Är du student (ja/nej)? Nej Är du föreningsmedlem (ja/nej)? JA Hur många personer gäller köpet? 3 Pris per person: 50 kr Totalt att betala: 150 kr
Testa din lösning
| Student | Medlem | Antal | Pris per person | Totalpris |
|---|---|---|---|---|
| nej | nej | 2 | 80 | 160 |
| ja | nej | 2 | 50 | 100 |
| nej | ja | 3 | 50 | 150 |
| ja | ja | 2 | 50 | 100 |
| " JA " | " Nej " | 1 | 50 | 50 |
Citattecknen i sista raden visar extra blanksteg och ska inte skrivas in. Förklara varför priset inte blir lägre när båda svaren är ja.
Lösningsförslag
Utskrift
LÄS IN svar om student
BEARBETA svaret
LÄS IN svar om medlemskap
BEARBETA svaret
LÄS IN antal personer
OM studentsvaret är ja ELLER medlemssvaret är ja
SÄTT biljettpriset till 50
ANNARS
SÄTT biljettpriset till 80
SLUT OM
BERÄKNA totalpris som biljettpris gånger antal
SKRIV UT biljettpris och totalprisConsole.Write("Är du student (ja/nej)? ");
string student = Console.ReadLine();
student = student.Trim().ToLower();
Console.Write("Är du föreningsmedlem (ja/nej)? ");
string medlem = Console.ReadLine();
medlem = medlem.Trim().ToLower();
Console.Write("Hur många personer gäller köpet? ");
int antal = Convert.ToInt32(Console.ReadLine());
int biljettpris;
if (student == "ja" || medlem == "ja")
{
biljettpris = 50;
}
else
{
biljettpris = 80;
}
int totalpris = biljettpris * antal;
Console.WriteLine($"Pris per person: {biljettpris} kr");
Console.WriteLine($"Totalt att betala: {totalpris} kr");Villkoret väljer ett enda pris. När båda svaren är ja är samma villkor fortfarande sant, så priset blir 50 kr en gång. Totalberäkningen använder sedan det valda priset oavsett vilken gren som kördes.
3.3.6 Sammanfattning
&&kräver att båda delvillkoren är sanna.||kräver att minst ett delvillkor är sant. Båda får vara sanna.!vänder ett booleskt värde utan att ändra variabeln.- En boolesk variabel kan användas direkt i ett villkor. En jämförelse ger också ett booleskt värde.
Trim()tar bort tomrum runt texten ochToLower()gör den till gemener. Tilldela resultatet till variabeln.- Jämför textsvar direkt i villkoret när en extra boolesk variabel inte behövs.
- Parenteser visar hur kombinerade krav hör ihop.
- Testa intervallgränser och olika kombinationer av uppfyllda och ouppfyllda krav.
3.4 Beslut i flera steg
Presentation









Ibland blir ett beslut aktuellt först när ett tidigare krav är uppfyllt. I det här avsnittet använder du villkor inuti andra villkor och planerar i vilken ordning beslut och beräkningar ska göras. Du får också prova switch för en enkel meny med fasta alternativ.
Efter avsnittet ska du kunna
- Följa ett nästlat villkor och se vilket
elsesom hör till vilketif. - Välja mellan nästlade och sammansatta villkor.
- Låta beräkningarna följa problemets regler.
- Använda
switch,case,breakochdefaultför ett enkelt menyval. - Planera med pseudokod och testa olika vägar genom programmet.
Skriv koden inuti Main om ditt projekt använder den strukturen. Kommentera bort tidigare kod eller använd ett nytt projekt för varje övning. Du får anta giltiga tal. Bearbeta ja/nej-svar med Trim() och ToLower().
3.4.1 Ett villkor inuti ett annat
Ett evenemang måste ha en ledig plats innan vi behöver bestämma besökarens biljettpris. Om det finns plats kostar biljetten 60 kr för den som är under 18 år och annars 100 kr.
Ett nästlat villkor är ett villkor som ligger inuti ett annat villkorsblock. Det inre villkoret kontrolleras bara om programmet kommer in i det yttre blocket.
Console.Write("Finns en ledig plats (ja/nej)? ");
string plats = Console.ReadLine();
plats = plats.Trim().ToLower();
if (plats == "ja")
{
Console.Write("Hur gammal är besökaren? ");
int alder = Convert.ToInt32(Console.ReadLine());
if (alder < 18)
{
Console.WriteLine("Biljettpris: 60 kr");
}
else
{
Console.WriteLine("Biljettpris: 100 kr");
}
}
else
{
Console.WriteLine("Evenemanget är fullbokat.");
}
Utskrift
Finns en ledig plats (ja/nej)? ja Hur gammal är besökaren? 16 Biljettpris: 60 kr
Utskrift
Finns en ledig plats (ja/nej)? nej Evenemanget är fullbokat.
| Del | Vad styr den? |
|---|---|
| Yttre if: plats == "ja" | Om åldern ska läsas in och priset väljas. |
| Inre if: alder < 18 | Vilket pris besökaren får när det finns plats. |
| Inre else | Priset för besökare som är minst 18 år. |
| Yttre else | Beskedet att evenemanget är fullbokat. |
Klamrarna avgör vilka block som hör ihop
Det inre if/else-paret ligger helt inuti det yttre if-blocket. Båda prisalternativen kräver alltså att det finns plats. Indragen hjälper dig att se strukturen, men det är klamrarna som avgränsar blocken.
Variabeln alder deklareras och används inne i det yttre if-blocket. Den behövs inte när evenemanget är fullbokat.
Övning 3.4a – Vilka kontroller görs?
Följ programmet för dessa tre fall innan du provkör:
- Det finns plats och besökaren är 17 år.
- Det finns plats och besökaren är 18 år.
- Det finns ingen plats.
Ange vilka villkor som kontrolleras och vilken utskrift som visas. Varför frågar programmet inte efter åldern i det sista fallet?
Lösningsförslag
| Fall | Yttre villkor | Inre villkor | Resultat |
|---|---|---|---|
| Plats, 17 år | Sant | Sant | Biljettpris: 60 kr |
| Plats, 18 år | Sant | Falskt | Biljettpris: 100 kr |
| Ingen plats | Falskt | Kontrolleras inte | Evenemanget är fullbokat. |
Åldersfrågan och det inre villkoret ligger i det yttre if-blocket. När platsvillkoret är falskt hoppas hela det blocket över.
3.4.2 Nästlade eller sammansatta villkor?
I verkstaden från 3.3 behövde deltagaren vara minst 15 år och ha gått säkerhetsintroduktionen. Om vi bara vill ge ett gemensamt ja/nej-besked passar && bra.
Console.Write("Hur gammal är du? ");
int alder = Convert.ToInt32(Console.ReadLine());
Console.Write("Har du gått introduktionen (ja/nej)? ");
string svar = Console.ReadLine();
svar = svar.Trim().ToLower();
if (alder >= 15 && svar == "ja")
{
Console.WriteLine("Du får delta.");
}
else
{
Console.WriteLine("Du får inte delta.");
}
Med nästling kan vi göra kontrollerna i steg. Här frågar vi bara efter introduktionen om ålderskravet är uppfyllt. Varje avslag får ett eget besked.
Console.Write("Hur gammal är du? ");
int alder = Convert.ToInt32(Console.ReadLine());
if (alder >= 15)
{
Console.Write("Har du gått introduktionen (ja/nej)? ");
string svar = Console.ReadLine();
svar = svar.Trim().ToLower();
if (svar == "ja")
{
Console.WriteLine("Du får delta.");
}
else
{
Console.WriteLine("Du behöver gå introduktionen först.");
}
}
else
{
Console.WriteLine("Du måste vara minst 15 år.");
}
Utskrift
Hur gammal är du? 15 Har du gått introduktionen (ja/nej)? nej Du behöver gå introduktionen först.
| Situation | En lämplig struktur |
|---|---|
| Flera krav ska ge ett gemensamt ja/nej-besked | Ett sammansatt villkor med && eller ||. |
| Nästa fråga eller beslut behövs bara efter ett godkänt första steg | Ett nästlat villkor. |
| Flera oberoende saker kan behöva göras | Separata if-satser, som i 3.2. |
Välj en struktur du kan förklara
Samma problem kan ofta lösas på flera sätt. Nästling är användbar när nästa steg beror på det förra. Om flera kontroller bara leder till samma besked kan ett sammansatt villkor bli enklare att läsa. Här håller vi oss till högst två nivåer av villkor.
Övning 3.4b – Skriv om beslutet
Utgå från den nästlade verkstadskoden. Skriv om den så att båda uppgifterna läses in först och ett enda villkor med && avgör om personen får delta.
Använd ett gemensamt avslagsbesked. Testa 14 år/ja, 15 år/nej och 15 år/ja. Beskriv vad som förändras i frågorna och återkopplingen jämfört med den nästlade versionen.
Lösningsförslag
Läs först in alder och det bearbetade svar, som i det första exemplet i 3.4.2. Ersätt sedan nästlingen med:
if (alder >= 15 && svar == "ja")
{
Console.WriteLine("Du får delta.");
}
else
{
Console.WriteLine("Du får inte delta.");
}Resultaten blir nej, nej och ja. Nu ställs introduktionsfrågan även till den som är under 15 år. Avslaget säger inte längre vilket krav som saknas. Det slutliga beslutet om deltagande är detsamma.
3.4.3 Beräkningar i rätt ordning
En förening säljer en aktivitet för 200 kr. Ett valbart materialpaket kostar 50 kr extra. Medlemmar får 10 procent rabatt på grundavgiften, men ingen rabatt på materialpaketet.
Börja med att skriva reglerna som en plan. Välj sedan variabler för delbeloppen.
Utskrift
LÄS IN svar om medlemskap
LÄS IN svar om materialpaket
SÄTT aktivitetsavgiften till 200 kr
OM kunden är medlem
MINSKA aktivitetsavgiften med 10 procent
SLUT OM
SÄTT materialkostnaden till 0 kr
OM kunden vill ha materialpaketet
SÄTT materialkostnaden till 50 kr
SLUT OM
SUMMERA aktivitetsavgiften och materialkostnaden
SKRIV UT totalprisetConsole.Write("Är du medlem (ja/nej)? ");
string medlem = Console.ReadLine();
medlem = medlem.Trim().ToLower();
Console.Write("Vill du ha materialpaket (ja/nej)? ");
string material = Console.ReadLine();
material = material.Trim().ToLower();
double grundavgift = 200;
double aktivitetsavgift = grundavgift;
if (medlem == "ja")
{
aktivitetsavgift = grundavgift * 0.9;
}
double materialkostnad = 0;
if (material == "ja")
{
materialkostnad = 50;
}
double totalpris = aktivitetsavgift + materialkostnad;
Console.WriteLine($"Aktivitetsavgift: {aktivitetsavgift:F2} kr");
Console.WriteLine($"Material: {materialkostnad:F2} kr");
Console.WriteLine($"Totalt: {totalpris:F2} kr");
Utskrift
Är du medlem (ja/nej)? ja Vill du ha materialpaket (ja/nej)? ja Aktivitetsavgift: 180,00 kr Material: 50,00 kr Totalt: 230,00 kr
De två if-satserna är oberoende: kunden kan vara medlem och välja material samtidigt. Materialkostnaden börjar på 0 eftersom det är rätt kostnad när inget paket väljs. Aktivitetsavgiften börjar på ordinarie pris.
För en medlem med materialpaket ger uttrycken nedan olika resultat:
| Beräkning | Resultat | Följer reglerna? |
|---|---|---|
| 200 * 0.9 + 50 | 230 kr | Ja. Bara grundavgiften rabatteras. |
| (200 + 50) * 0.9 | 225 kr | Nej. Materialpaketet får också rabatt. |
Rätt syntax betyder inte rätt beräkning
Båda uttrycken är giltig C#-kod, men bara det första följer föreningens regler. Det andra innehåller ett logiskt fel. Kontrollera vad rabatten ska gälla innan du väljer beräkningsordning.
Övning 3.4c – Hitta rabattfelet
En annan lösning räknar först ihop grundavgift och material. Sedan ger den medlemmar rabatt på hela beloppet:
double totalpris = grundavgift + materialkostnad;
if (medlem == "ja")
{
totalpris = totalpris * 0.9;
}Kodutdraget förutsätter att medlemskap och materialkostnad redan är bestämda. Skriv om det så att bara grundavgiften rabatteras.
Beräkna förväntat totalpris för alla fyra kombinationer av medlem/icke medlem och med/utan material. Vilken kombination avslöjar felet?
Lösningsförslag
double aktivitetsavgift = grundavgift;
if (medlem == "ja")
{
aktivitetsavgift = grundavgift * 0.9;
}
double totalpris = aktivitetsavgift + materialkostnad;| Medlem | Material | Rätt totalpris |
|---|---|---|
| nej | nej | 200 kr |
| nej | ja | 250 kr |
| ja | nej | 180 kr |
| ja | ja | 230 kr |
Felet syns när kunden både är medlem och väljer material. Den felaktiga lösningen ger då 225 kr. De övriga tre kombinationerna ger rätt belopp även med felet, vilket visar varför flera testfall behövs.
3.4.4 Switch för fasta alternativ
När en variabel ska jämföras med flera bestämda värden kan switch göra alternativen tydliga. Här väljer användaren mellan två menyalternativ.
Vi läser menyvalet som text. Det behövs ingen talomvandling eftersom vi bara vill jämföra valet med "1" och "2".
Console.WriteLine("1. Visa öppettider");
Console.WriteLine("2. Visa kontaktuppgifter");
Console.Write("Ditt val: ");
string val = Console.ReadLine();
val = val.Trim();
switch (val)
{
case "1":
Console.WriteLine("Öppet vardagar 10–18.");
break;
case "2":
Console.WriteLine("Kontakta receptionen på plats.");
break;
default:
Console.WriteLine("Ogiltigt val.");
break;
}
Console.WriteLine("Programmet är klart.");
Utskrift
1. Visa öppettider 2. Visa kontaktuppgifter Ditt val: 2 Kontakta receptionen på plats. Programmet är klart.
| Del | Betydelse |
|---|---|
| switch (val) | Väljer ett alternativ utifrån innehållet i val. |
| case "1": | Koden här körs när val är exakt "1". |
| break; | Lämnar switch-satsen. Programmet fortsätter efter den. |
| default: | Körs när inget case matchar. |
Menyn körs en gång
break avslutar inte hela programmet. I detta exempel lämnar det switch-satsen, och den sista utskriften körs. Menyn visas inte igen automatiskt. Senare använder vi loopar för att upprepa menyer och arbetar mer med switch i Banken-projektet.
Här räcker Trim(), eftersom siffrorna i texten inte har stora eller små bokstäver. Ett annat svar, till exempel hej eller en tom rad, väljer default.
Övning 3.4d – Lägg till ett menyval
Lägg till alternativ 3: ”Visa besöksadress”. Väljs det ska programmet skriva ”Besöksadress: Exempelgatan 1.” Kom ihåg att ändra både menytexten och switch-satsen.
Testa 1, 2, 3 och 9. Testa också en tom rad och ett val med blanksteg runt siffran. Vilka rader körs efter break?
Lösningsförslag
Lägg till menytexten före frågan om val:
Console.WriteLine("3. Visa besöksadress");Lägg till detta alternativ inne i switch-satsen, före default:
case "3":
Console.WriteLine("Besöksadress: Exempelgatan 1.");
break;1, 2 och 3 visar respektive information. 9 och en tom rad ger ”Ogiltigt val.” Blanksteg runt ett giltigt val tas bort med Trim. Efter break fortsätter programmet efter switch-satsen och skriver ”Programmet är klart.”
Självständiga uppgifter
Skriv kort pseudokod innan du programmerar. Använd ett nytt projekt eller kommentera bort tidigare kod. Du får anta giltiga tal och ja/nej-svar, med möjlighet till stora bokstäver och blanksteg runt texten. Testa varje väg genom programmet. Uppgifterna nedan kräver inte switch.
Uppgift: m03u07 – Anmälan till turneringen
En turnering tar emot lag med 3–5 spelare. Avgiften är 80 kr per spelare. Först måste programmet kontrollera att anmälan fortfarande är öppen.
Krav på programmet
- Fråga om anmälan är öppen och bearbeta ja/nej-svaret.
- Om anmälan är stängd: visa ett besked och ställ inga fler frågor.
- Om anmälan är öppen: läs in lagets antal spelare som ett positivt heltal.
- Använd ett nästlat villkor för att kontrollera att laget har minst 3 och högst 5 spelare.
- Vid godkänd lagstorlek: visa att laget kan anmälas och beräkna avgiften.
- Vid fel lagstorlek: visa att laget måste ha 3–5 spelare. Visa ingen avgift.
Exempel på körning
Utskrift
Är anmälan öppen (ja/nej)? JA Hur många spelare har laget? 4 Laget kan anmälas. Anmälningsavgift: 320 kr
Utskrift
Är anmälan öppen (ja/nej)? nej Anmälan är stängd.
Testa din lösning
| Öppen | Antal spelare | Förväntat resultat |
|---|---|---|
| nej | Frågan ska inte ställas | Anmälan är stängd. |
| ja | 2 | Fel lagstorlek, ingen avgift |
| ja | 3 | Kan anmälas, 240 kr |
| ja | 5 | Kan anmälas, 400 kr |
| ja | 6 | Fel lagstorlek, ingen avgift |
Lösningsförslag
Utskrift
LÄS IN om anmälan är öppen
BEARBETA svaret
OM anmälan är öppen
LÄS IN antal spelare
OM antalet är minst 3 OCH högst 5
BERÄKNA avgiften som antal gånger 80
SKRIV UT att laget kan anmälas och visa avgiften
ANNARS
SKRIV UT att laget måste ha 3–5 spelare
SLUT OM
ANNARS
SKRIV UT att anmälan är stängd
SLUT OMConsole.Write("Är anmälan öppen (ja/nej)? ");
string oppen = Console.ReadLine();
oppen = oppen.Trim().ToLower();
if (oppen == "ja")
{
Console.Write("Hur många spelare har laget? ");
int antal = Convert.ToInt32(Console.ReadLine());
if (antal >= 3 && antal <= 5)
{
int totalavgift = antal * 80;
Console.WriteLine("Laget kan anmälas.");
Console.WriteLine($"Anmälningsavgift: {totalavgift} kr");
}
else
{
Console.WriteLine("Laget måste ha 3–5 spelare.");
}
}
else
{
Console.WriteLine("Anmälan är stängd.");
}Antalet läses bara in när anmälan är öppen. Avgiften beräknas bara när även lagstorleken är godkänd. Det yttre else-blocket hanterar stängd anmälan och det inre hanterar fel lagstorlek.
Uppgift: m03u08 – Beställ profiltröjor
En förening säljer profiltröjor för 200 kr styck. Medlemmar får 10 procent rabatt på tröjornas pris. Namntryck kostar 40 kr extra per tröja och omfattas inte av rabatten.
Alla tröjor i beställningen har samma medlemsvillkor. Kunden väljer namntryck på alla tröjor eller på inga. Du behöver inte läsa in själva namnen.
Krav på programmet
- Läs in antal tröjor som ett positivt heltal.
- Läs in ja/nej-svar om medlemskap och namntryck. Bearbeta båda svaren.
- Beräkna tröjornas ordinarie sammanlagda pris, rabatt i kronor och sammanlagd tryckkostnad som separata delbelopp.
- Beräkna totalpriset efter villkoren. Rabatten får bara gälla tröjorna.
- Visa samtliga delbelopp och totalpriset med två decimaler. Visa 0 för rabatt eller tryck när det inte gäller.
Exempel på körning
Utskrift
Hur många tröjor vill du beställa? 3 Är du medlem (ja/nej)? ja Vill du ha namntryck (ja/nej)? ja Tröjor före rabatt: 600,00 kr Medlemsrabatt: 60,00 kr Namntryck: 120,00 kr Totalt: 660,00 kr
Decimaltecknet kan bli punkt eller komma beroende på datorns inställningar.
Testa din lösning
| Antal | Medlem | Tryck | Tröjor före rabatt | Rabatt | Tryckkostnad | Totalt |
|---|---|---|---|---|---|---|
| 1 | nej | nej | 200 | 0 | 0 | 200 |
| 1 | nej | ja | 200 | 0 | 40 | 240 |
| 1 | ja | nej | 200 | 20 | 0 | 180 |
| 1 | ja | ja | 200 | 20 | 40 | 220 |
| 3 | ja | ja | 600 | 60 | 120 | 660 |
Testa även ett svar med stora bokstäver och blanksteg runt. Förklara varför medlemskap och namntryck bör kontrolleras med separata if-satser.
Lösningsförslag
Utskrift
LÄS IN antal tröjor
LÄS IN och BEARBETA svar om medlemskap
LÄS IN och BEARBETA svar om namntryck
BERÄKNA tröjbelopp som antal gånger 200
SÄTT rabatt till 0
OM kunden är medlem
BERÄKNA rabatt som 10 procent av tröjbeloppet
SLUT OM
SÄTT tryckkostnad till 0
OM kunden vill ha namntryck
BERÄKNA tryckkostnad som antal gånger 40
SLUT OM
BERÄKNA totalpris som tröjbelopp minus rabatt plus tryckkostnad
SKRIV UT delbelopp och totalprisConsole.Write("Hur många tröjor vill du beställa? ");
int antal = Convert.ToInt32(Console.ReadLine());
Console.Write("Är du medlem (ja/nej)? ");
string medlem = Console.ReadLine();
medlem = medlem.Trim().ToLower();
Console.Write("Vill du ha namntryck (ja/nej)? ");
string tryck = Console.ReadLine();
tryck = tryck.Trim().ToLower();
double trojbelopp = antal * 200;
double rabatt = 0;
if (medlem == "ja")
{
rabatt = trojbelopp * 0.1;
}
double tryckkostnad = 0;
if (tryck == "ja")
{
tryckkostnad = antal * 40;
}
double totalpris = trojbelopp - rabatt + tryckkostnad;
Console.WriteLine($"Tröjor före rabatt: {trojbelopp:F2} kr");
Console.WriteLine($"Medlemsrabatt: {rabatt:F2} kr");
Console.WriteLine($"Namntryck: {tryckkostnad:F2} kr");
Console.WriteLine($"Totalt: {totalpris:F2} kr");Medlemskap och namntryck är oberoende val och kan gälla samtidigt. Två separata if-satser låter därför båda beräkningarna köras. Rabatten beräknas från tröjbeloppet, innan tryckkostnaden läggs till.
3.4.5 Sammanfattning
- Ett nästlat villkor ligger inuti ett annat villkorsblock. Det kontrolleras bara när programmet når det.
- Klamrarna visar vilka block och else-grenar som hör ihop. Indrag gör strukturen lättare att läsa.
- Använd sammansatta villkor för gemensamma krav och nästling när ett beslut leder vidare till nästa steg.
- Oberoende val kan behöva separata if-satser.
- Beräkningarnas ordning måste följa reglerna för exempelvis rabatt och tillägg.
- Switch passar för fasta alternativ. Break lämnar switch-satsen och default hanterar val som inte matchar något case.
- Testa alla beslutens vägar, gränsvärden och kombinationer som kan avslöja logiska fel.
3.5 Problemlösning och repetition
Presentation










Nu ska du använda teknikerna från Moment03 för att bygga sammanhängande program. Inga nya grundtekniker tillkommer. Fokus ligger på att förstå reglerna, planera lösningen och kontrollera att programmet gör rätt.
Arbetet under lektionen
Arbeta först med genomgången och de korta övningarna. Därefter är m03u09 den gemensamma grunduppgiften. När du är klar fortsätter du med m03u10, som kan slutföras efter lektionen.
Lektionens sista 20 minuter är avsatta för det teoretiska quizet. Den praktiska diagnosen genomförs vid ett senare tillfälle.
3.5.1 Från uppgiftstext till tydliga regler
Börja med att förstå problemet. Besvara frågorna nedan innan du skriver kod.
| Fråga | Vad du letar efter |
|---|---|
| Vad ska användaren ange? | Indata och datatyper. |
| Vilka regler gäller? | Villkor, gränser och undantag. |
| Vad ska beräknas? | Delbelopp och beräkningarnas ordning. |
| Vad ska visas? | Utdata och tydliga besked. |
| Hur kontrolleras lösningen? | Testfall med förväntade resultat. |
Genomgångsexempel – Fotoutskrifter
En fotobutik säljer standardbilder för 4 kr styck och premiumbilder för 6 kr styck. Kunden väljer en papperstyp för hela beställningen.
Medlemmar får 10 procent rabatt på bilderna. Efter rabatten tillkommer en fast hanteringsavgift på 20 kr. Avgiften rabatteras aldrig.
Läs in antal bilder som ett positivt heltal, papperstyp och medlemskap. Visa bildkostnad före rabatt, rabatt i kronor, hanteringsavgift och totalpris. Du får anta att kunden anger standard eller premium och ja eller nej, men kan använda stora bokstäver och blanksteg runt texten.
Övning 3.5a – Plocka ut delarna
Besvara de fem frågorna för fotobutiken. Vilket belopp ska rabatten beräknas från? Räkna för hand på 10 standardbilder för en medlem och 10 premiumbilder för en icke-medlem.
Lösningsförslag
| Del | Förslag |
|---|---|
| Indata | Antal: int. Papperstyp och medlemskap: string. |
| Regler | Standard 4 kr, premium 6 kr. Medlem får 10 procent på bilderna. |
| Beräkning | Antal gånger styckpris, rabatt på bildkostnaden, sedan 20 kr i avgift. |
| Utdata | Bildkostnad, rabatt, avgift och totalpris. |
| Testning | Båda papperstyperna med och utan medlemskap. |
Standard för medlem: 40 − 4 + 20 = 56 kr. Premium för icke-medlem: 60 − 0 + 20 = 80 kr.
3.5.2 Planera besluten med pseudokod
Välj struktur utifrån reglerna. Samma program kan behöva flera strukturer.
| Situation | Lämplig struktur |
|---|---|
| Ett av flera alternativ | if / else if / else |
| Flera regler kan gälla samtidigt | Separata if-satser |
| Flera krav styr samma beslut | && eller || |
| Nästa beslut beror på ett tidigare | Nästlade villkor |
| Menyval med fasta alternativ | switch |
För fotobutiken väljer vi ett styckpris och kontrollerar sedan medlemskapet separat. Rabatt kan gälla för båda papperstyperna.
Utskrift
LÄS IN antal bilder
LÄS IN och BEARBETA papperstyp och medlemskap
OM papperstypen är premium
SÄTT styckpriset till 6 kr
ANNARS
SÄTT styckpriset till 4 kr
SLUT OM
BERÄKNA bildkostnad som antal gånger styckpris
SÄTT rabatt till 0
OM kunden är medlem
BERÄKNA rabatt som 10 procent av bildkostnaden
SLUT OM
BERÄKNA totalpris som bildkostnad minus rabatt plus 20 kr
SKRIV UT delbeloppen och totalprisetEftersom vi antar att kunden anger standard eller premium kan else hantera standardalternativet.
Övning 3.5b – Välj en struktur
Välj en struktur och motivera ditt val:
- Ett paket får skickas bara om både vikt och längd ligger inom gränserna.
- Ett paket kan få både ömtålighetstillägg och expresstillägg.
- En meny har valen 1, 2 och 3.
- Om anmälan är öppen ska programmet fråga efter antal deltagare och kontrollera gruppstorleken.
Lösningsförslag
- Ett sammansatt villkor med &&.
- Separata if-satser, eftersom båda tilläggen kan gälla.
- Switch passar fasta menyval. En if/else if-kedja är också möjlig.
- Ett yttre if för öppen anmälan och ett inre villkor för gruppstorleken.
Det viktiga är att strukturen följer reglerna och att du kan förklara den.
3.5.3 Bygg programmet i fungerande steg
Skriv inte allt på en gång. Kör efter varje större steg så blir det lättare att se vilken ändring som orsakar ett fel.
- Läs in uppgifterna. Skriv tillfälligt ut dem för att kontrollera inläsning och textbearbetning.
- Välj styckpris. Testa standard och premium.
- Beräkna bildkostnaden. Kontrollera antal gånger styckpris.
- Lägg till rabatten. Testa med och utan medlemskap.
- Samla slutberäkning och utskrifter. Lägg på hanteringsavgiften efter rabatten.
Här är den sammanhängande lösningen. Följ den med dina testvärden.
Console.Write("Antal bilder: ");
int antal = Convert.ToInt32(Console.ReadLine());
Console.Write("Papperstyp (standard/premium): ");
string papper = Console.ReadLine();
papper = papper.Trim().ToLower();
Console.Write("Medlem (ja/nej)? ");
string medlem = Console.ReadLine();
medlem = medlem.Trim().ToLower();
double styckpris;
if (papper == "premium")
{
styckpris = 6;
}
else
{
styckpris = 4;
}
double bildkostnad = antal * styckpris;
double rabatt = 0;
if (medlem == "ja")
{
rabatt = bildkostnad * 0.1;
}
double hanteringsavgift = 20;
double totalpris = bildkostnad - rabatt + hanteringsavgift;
Console.WriteLine($"Bilder före rabatt: {bildkostnad:F2} kr");
Console.WriteLine($"Rabatt: {rabatt:F2} kr");
Console.WriteLine($"Hanteringsavgift: {hanteringsavgift:F2} kr");
Console.WriteLine($"Totalt: {totalpris:F2} kr");
Utskrift
Antal bilder: 10 Papperstyp (standard/premium): standard Medlem (ja/nej)? JA Bilder före rabatt: 40,00 kr Rabatt: 4,00 kr Hanteringsavgift: 20,00 kr Totalt: 56,00 kr
Variablernas placering hjälper dig
Styckpris deklareras före valet och får ett värde i båda grenarna. Rabatt börjar på 0, vilket är rätt för en icke-medlem. Båda variablerna kan sedan användas i slutberäkningen.
Namn som bildkostnad, rabatt och hanteringsavgift gör det lättare att kontrollera delbeloppen.
3.5.4 Testa reglerna, inte bara en lyckad körning
Bestäm förväntat resultat före provkörningen och jämför med programmets faktiska resultat.
| Antal | Papper | Medlem | Förväntad total |
|---|---|---|---|
| 10 | standard | nej | 60 kr |
| 10 | standard | ja | 56 kr |
| 10 | premium | nej | 80 kr |
| 10 | premium | ja | 74 kr |
| 1 | premium | ja | 25,40 kr |
Fotobutiken har inga antalgränser för rabatt. I program med intervall behöver du även testa strax under, exakt på och strax över gränsen. Testa också textsvar med stora bokstäver och blanksteg runt.
Övning 3.5c – Ett test som avslöjar felet
Programmet har redan läst in och bearbetat papper och medlem. Det använder sedan detta kodutdrag:
double styckpris = 4;
double rabattProcent = 0;
if (papper == "premium")
{
styckpris = 6;
}
else if (medlem == "ja")
{
rabattProcent = 0.1;
}Rabatten ska gälla för båda papperstyperna. Välj ett testfall som avslöjar felet, förklara orsaken och rätta koden.
Lösningsförslag
En medlem som väljer premium avslöjar felet. Första villkoret är sant, så else if hoppas över och rabattProcent stannar på 0. Tio premiumbilder kostar då 80 kr inklusive avgift i stället för 74 kr, om resten av beräkningen följer reglerna.
double styckpris = 4;
double rabattProcent = 0;
if (papper == "premium")
{
styckpris = 6;
}
if (medlem == "ja")
{
rabattProcent = 0.1;
}Separata if-satser behövs eftersom premium och medlemskap kan gälla samtidigt.
Självständigt arbete
Börja med m03u09. Skriv pseudokod och välj minst ett eget testfall utöver tabellen. Öppna ledtrådarna en i taget om du kör fast och hela lösningen först efter ett eget försök.
Skriv koden inuti Main om ditt projekt använder den strukturen. Kommentera bort tidigare kod eller använd ett nytt projekt. Alla tal får antas vara giltiga enligt uppgiften.
Uppgift: m03u09 – Resultat från kunskapstävlingen
En tävling har 20 frågor. Deltagaren kan svara rätt, svara fel eller lämna frågor obesvarade.
Regler
- Varje rätt svar ger 3 poäng. Varje fel ger 1 poängs avdrag. Obesvarade frågor ger 0.
- Negativ beräknad poäng ska sättas till 0.
- Minst 45 poäng ger guld, 25–44 ger silver och under 25 ger brons.
- Minst 15 rätt och inga fel ger ett separat bonusbesked. Utmärkelsen ändrar inte poängen.
Krav
Läs in antal rätt och fel. Du får anta heltal 0–20 där summan är högst 20. Du behöver inte läsa in obesvarade frågor. Visa poäng, exakt en nivå och bonusbeskedet bara när kraven är uppfyllda. Nivåerna är spelregler, inte kursbetyg.
Exempel
Utskrift
Antal rätt (0–20): 15 Antal fel (0–20): 0 Poäng: 45 Nivå: Guld Bonusutmärkelse: minst 15 rätt och inga fel!
Testfall
| Rätt | Fel | Poäng | Nivå | Bonus |
|---|---|---|---|---|
| 0 | 0 | 0 | Brons | Nej |
| 0 | 5 | 0 | Brons | Nej |
| 8 | 0 | 24 | Brons | Nej |
| 9 | 2 | 25 | Silver | Nej |
| 15 | 1 | 44 | Silver | Nej |
| 15 | 0 | 45 | Guld | Ja |
| 16 | 2 | 46 | Guld | Nej |
| 20 | 0 | 60 | Guld | Ja |
Ledtråd 1 – Dela upp problemet
Läs in, beräkna poäng, korrigera negativ poäng, välj nivå och skriv ut. Bonusbeskedet är ett eget beslut.
Ledtråd 2 – Välj villkor
Välj nivån i en sammanhängande kedja och börja med guldgränsen. Bonusen ska kunna visas samtidigt som nivån och behöver en separat kontroll.
Ledtråd 3 – Början på koden
int poang = ratt * 3 - fel;
if (poang < 0)
{
poang = 0;
}Fortsätt med en variabel för nivån och en kedja som tilldelar den ett värde.
Lösningsförslag
Utskrift
LÄS IN rätt och fel
BERÄKNA poäng som rätt gånger 3 minus fel
OM poängen är negativ
SÄTT poängen till 0
SLUT OM
OM poängen är minst 45
SÄTT nivån till guld
ANNARS OM poängen är minst 25
SÄTT nivån till silver
ANNARS
SÄTT nivån till brons
SLUT OM
SKRIV UT poäng och nivå
OM antalet rätt är minst 15 OCH antalet fel är 0
SKRIV UT bonusbesked
SLUT OMConsole.Write("Antal rätt (0–20): ");
int ratt = Convert.ToInt32(Console.ReadLine());
Console.Write("Antal fel (0–20): ");
int fel = Convert.ToInt32(Console.ReadLine());
int poang = ratt * 3 - fel;
if (poang < 0)
{
poang = 0;
}
string niva;
if (poang >= 45)
{
niva = "Guld";
}
else if (poang >= 25)
{
niva = "Silver";
}
else
{
niva = "Brons";
}
Console.WriteLine($"Poäng: {poang}");
Console.WriteLine($"Nivå: {niva}");
if (ratt >= 15 && fel == 0)
{
Console.WriteLine("Bonusutmärkelse: minst 15 rätt och inga fel!");
}Guld kontrolleras före silver. Bonuskontrollen står utanför kedjan. 16 rätt och 2 fel ger exempelvis guld utan bonus.
Uppgift: m03u10 – Beställning i skolcafét
Bygg ett program för en beställning i skolcafét. Fortsätt med denna uppgift när m03u09 är klar.
Regler
- Menyval 1 är toast för 35 kr per portion. Menyval 2 är sallad för 60 kr.
- Alla portioner i beställningen är samma produkt.
- Medlemmar i elevföreningen får 10 procent rabatt på maten.
- Dryck kostar 15 kr per portion och rabatteras aldrig. Kunden väljer dryck till alla portioner eller inga.
- Det finns inga andra avgifter eller rabatter.
Krav
- Visa menyn, läs valet som text och välj styckpris med switch.
- Vid ogiltigt menyval: visa ett felmeddelande utan fler frågor eller prisutskrift.
- Vid giltigt val: läs in antal portioner som ett positivt heltal, medlemskap och dryckval.
- Bearbeta ja/nej-svaren med Trim och ToLower. Du får anta giltiga svar med eventuella stora bokstäver och blanksteg runt.
- Visa mat före rabatt, rabatt i kronor, dryckkostnad och totalpris med två decimaler.
Exempel
Utskrift
1. Toast, 35 kr 2. Sallad, 60 kr Ditt val: 1 Antal portioner: 2 Medlem i elevföreningen (ja/nej)? JA Dryck till varje portion (ja/nej)? ja Mat före rabatt: 70,00 kr Rabatt: 7,00 kr Dryck: 30,00 kr Totalt: 93,00 kr
Decimaltecknet kan vara komma eller punkt beroende på datorns inställningar.
Testfall
| Val | Antal | Medlem | Dryck | Förväntad total |
|---|---|---|---|---|
| 1 | 2 | nej | nej | 70 kr |
| 1 | 2 | ja | nej | 63 kr |
| 1 | 2 | nej | ja | 100 kr |
| 1 | 2 | ja | ja | 93 kr |
| 2 | 3 | ja | ja | 207 kr |
| 9 | – | – | – | Felmeddelande, inga fler frågor |
Tips om du kör fast
Bygg menyn först. En boolesk variabel kan ange om valet är giltigt. Låt resten köras bara när den är sann. Rabatt och dryck är oberoende val: beräkna dem separat och summera sist.
Lösningsförslag
Utskrift
LÄS IN menyval
VÄLJ styckpris utifrån menyvalet
OM valet är ogiltigt
SKRIV UT felmeddelande
ANNARS
LÄS IN antal, medlemskap och dryckval
BEARBETA textsvaren
BERÄKNA matkostnad
SÄTT rabatt och dryckkostnad till 0
OM kunden är medlem
BERÄKNA 10 procent rabatt på maten
SLUT OM
OM kunden vill ha dryck
BERÄKNA antal gånger 15
SLUT OM
BERÄKNA matkostnad minus rabatt plus dryckkostnad
SKRIV UT delbelopp och totalpris
SLUT OMConsole.WriteLine("1. Toast, 35 kr");
Console.WriteLine("2. Sallad, 60 kr");
Console.Write("Ditt val: ");
string val = Console.ReadLine();
val = val.Trim();
double styckpris = 0;
bool giltigtVal = true;
switch (val)
{
case "1":
styckpris = 35;
break;
case "2":
styckpris = 60;
break;
default:
giltigtVal = false;
Console.WriteLine("Ogiltigt produktval.");
break;
}
if (giltigtVal)
{
Console.Write("Antal portioner: ");
int antal = Convert.ToInt32(Console.ReadLine());
Console.Write("Medlem i elevföreningen (ja/nej)? ");
string medlem = Console.ReadLine();
medlem = medlem.Trim().ToLower();
Console.Write("Dryck till varje portion (ja/nej)? ");
string dryck = Console.ReadLine();
dryck = dryck.Trim().ToLower();
double matkostnad = antal * styckpris;
double rabatt = 0;
if (medlem == "ja")
{
rabatt = matkostnad * 0.1;
}
double dryckkostnad = 0;
if (dryck == "ja")
{
dryckkostnad = antal * 15;
}
double totalpris = matkostnad - rabatt + dryckkostnad;
Console.WriteLine($"Mat före rabatt: {matkostnad:F2} kr");
Console.WriteLine($"Rabatt: {rabatt:F2} kr");
Console.WriteLine($"Dryck: {dryckkostnad:F2} kr");
Console.WriteLine($"Totalt: {totalpris:F2} kr");
}Default sätter giltigtVal till false. Därför hoppas efterföljande frågor och beräkningar över. Break lämnar switch-satsen, medan if avgör om resten ska köras.
3.5.5 Inför quiz och praktisk diagnos
På quizet behöver du kunna läsa kort kod och förklara vad som händer. Inför den praktiska diagnosen behöver du också kunna bygga en egen lösning från en uppgiftstext.
| Du ska kunna förklara | Du ska kunna göra |
|---|---|
| Skillnaden mellan = och ==. | Läsa in och jämföra värden. |
| Vilket block som väljs och varför. | Använda if, else if och else. |
| Skillnaden mellan &&, || och !. | Skriva villkor med flera krav. |
| När separata if eller nästling passar. | Strukturera beslut i ett program. |
| Vad Trim och ToLower gör. | Bearbeta textsvar före jämförelsen. |
| Varför variabler måste finnas och ha värden. | Använda ett resultat efter villkoret. |
| Vad case, break och default gör. | Skriva en enkel meny med switch. |
| Varför ett program ger fel resultat. | Planera med pseudokod och välja testfall. |
Egen avstämning
Kan du förklara varför du valde varje villkor? Kan du följa en körning för hand och ange variablernas värden? Kan du välja ett test som avslöjar om en gräns eller operator blivit fel?
Om något känns osäkert: återvänd till motsvarande exempel i 3.1–3.4 och gör en liten ändring som du kan förutsäga resultatet av.
3.6 Extra träning och fördjupning
För dig som vill ha en större utmaning
Extrauppgifterna är frivilliga och kombinerar flera tekniker. Tipsen kan innehålla fördjupningar. Teknik som bara visas här krävs inte på momentets quiz eller praktiska diagnos.
Extrauppgift: m03x01 – Vilket träningskort lönar sig?
Ett gym erbjuder två sätt att betala för träningen. Hjälp en kund att jämföra kostnaderna utifrån hur många besök kunden planerar under en månad.
Prisalternativ
- Klippkort: 100 kr i månadsavgift plus 40 kr per besök.
- Månadskort: 500 kr per månad. Alla besök ingår.
Krav på programmet
- Läs in kundens planerade antal besök. Du får anta ett heltal som är 0 eller större.
- Beräkna och visa månadskostnaden för båda alternativen.
- Visa vilket alternativ som är billigast och hur mycket kunden sparar med det.
- Om alternativen kostar lika mycket ska programmet tala om det.
- Visa kostnader och besparing med två decimaler.
Skriv en kort pseudokod innan du programmerar. Din lösning ska beräkna kostnaderna från priserna, inte välja ett färdigt svar enbart utifrån antalet besök.
Exempel på körning
Utskrift
Hur många besök planerar du? 6 Klippkort: 340,00 kr Månadskort: 500,00 kr Klippkortet är billigast. Du sparar 160,00 kr.
Utskrift
Hur många besök planerar du? 10 Klippkort: 500,00 kr Månadskort: 500,00 kr Alternativen kostar lika mycket.
Testa din lösning
Välj testfall där klippkortet är billigast, där månadskortet är billigast och där priserna är lika. Testa även 0 besök: månadsavgiften för klippkortet gäller fortfarande.
Tips om du kör fast
Börja med att beräkna och skriva ut båda kostnaderna. Kontrollera dem innan du lägger till jämförelserna.
Du kan använda flera separata if-satser. Programmet kontrollerar då varje villkor i tur och ordning. I den här uppgiften kan bara en av jämförelserna mindre än, större än eller lika med vara sann för samma två kostnader.
Beräkna besparingen som den högre kostnaden minus den lägre, så att den blir positiv.
Lösningsförslag
Console.Write("Hur många besök planerar du? ");
int antalBesok = Convert.ToInt32(Console.ReadLine());
double klippkort = 100 + antalBesok * 40;
double manadskort = 500;
Console.WriteLine($"Klippkort: {klippkort:F2} kr");
Console.WriteLine($"Månadskort: {manadskort:F2} kr");
if (klippkort < manadskort)
{
double besparing = manadskort - klippkort;
Console.WriteLine($"Klippkortet är billigast. Du sparar {besparing:F2} kr.");
}
if (klippkort > manadskort)
{
double besparing = klippkort - manadskort;
Console.WriteLine($"Månadskortet är billigast. Du sparar {besparing:F2} kr.");
}
if (klippkort == manadskort)
{
Console.WriteLine("Alternativen kostar lika mycket.");
}
Vid 0 besök kostar klippkortet 100 kr och är 400 kr billigare. Vid 10 besök kostar båda alternativen 500 kr. Vid 12 besök kostar klippkortet 580 kr och månadskortet är 80 kr billigare.
Variablerna med namnet besparing finns i olika block. Varje sådan variabel används bara i det block där den skapades.
Fördjupning efter avsnitt 3.2
De här tre frivilliga uppgifterna tränar problemlösning med det du har lärt dig till och med 3.2. Svårigheten ligger i att kombinera flera steg, välja rätt villkor och testa noggrant. Du behöver inga loopar, logiska operatorer eller nästlade villkor.
Skriv en kort pseudokod före varje uppgift. Dela upp lösningen i inmatning, bearbetning och utskrift. Du får anta att användaren följer instruktionerna för inmatningen. Använd ett nytt projekt för varje uppgift, eller kommentera bort tidigare kod. Om projektet har en Main-metod skriver du koden där.
Extrauppgift: m03x02 – Tryckeriets mängdpris
Ett tryckeri tar olika betalt för olika delar av en beställning. Bygg ett program som räknar ut kostnaden för ett antal affischer. Här är det viktigt att skilja på priset för hela beställningen och priset för affischerna inom ett visst intervall.
Regler
| Affischernas nummer i beställningen | Pris per affisch |
|---|---|
| 1–10 | 12 kr |
| 11–30 | 8 kr |
| 31 och uppåt | 5 kr |
Varje pris gäller bara affischerna i det intervallet. Vid 12 affischer betalar kunden alltså 12 kr styck för de första 10 och 8 kr styck för de sista 2. Det finns ingen startavgift.
Krav på programmet
- Läs in antal affischer som ett heltal från 0 och uppåt.
- Beräkna kostnaden med en villkorskedja. Kostnaden ska finnas i en variabel som kan användas efter kedjan.
- Skriv ut antal affischer och total kostnad i hela kronor.
- Visa dessutom hur många kronor kunden sparar jämfört med om alla affischer kostade 12 kr styck. Vid 0 affischer är både kostnaden och besparingen 0 kr.
Exempel på körning
Utskrift
Antal affischer: 35 Antal: 35 Total kostnad: 305 kr Besparing mot ordinarie pris: 115 kr
Testa din lösning
| Antal | Total kostnad | Besparing |
|---|---|---|
| 0 | 0 | 0 |
| 9 | 108 | 0 |
| 10 | 120 | 0 |
| 11 | 128 | 4 |
| 29 | 272 | 76 |
| 30 | 280 | 80 |
| 31 | 285 | 87 |
| 35 | 305 | 115 |
Utöver testfallen i tabellen: välj ett eget testfall, skriv det förväntade resultatet innan du kör och jämför sedan med programmets resultat.
Förklara din lösning
Varför blir det fel att multiplicera hela antalet med 5 när kunden beställer 35 affischer? Förklara också varför 20 affischer, inte 30, får priset 8 kr styck.
Tips om du kör fast
Räkna först för hand på 10, 30 och 35 affischer. Vad kostar de första 10 tillsammans? Vad kostar de första 30 tillsammans?
För fler än 30 affischer betalar kunden ett fast belopp för de första 30 och 5 kr för varje affisch därutöver. Beräkna ordinarie pris och besparing efter villkorskedjan.
Lösningsförslag
Console.Write("Antal affischer: ");
int antal = Convert.ToInt32(Console.ReadLine());
int kostnad;
if (antal <= 10)
{
kostnad = antal * 12;
}
else if (antal <= 30)
{
kostnad = 10 * 12 + (antal - 10) * 8;
}
else
{
kostnad = 10 * 12 + 20 * 8 + (antal - 30) * 5;
}
int ordinariePris = antal * 12;
int besparing = ordinariePris - kostnad;
Console.WriteLine($"Antal: {antal}");
Console.WriteLine($"Total kostnad: {kostnad} kr");
Console.WriteLine($"Besparing mot ordinarie pris: {besparing} kr");Den andra grenen gäller 11–30 affischer eftersom det första villkoret redan var falskt. I sista grenen räknas de första 30 affischerna till sina respektive priser. Det är bara antalet utöver 30 som multipliceras med 5.
Extrauppgift: m03x03 – Finalens resultatlista
Två spelare tävlar i en final. Varje spelare får poäng i en grundomgång och en bonusomgång. Programmet ska avgöra vem som vinner och ge en tydlig sammanfattning.
Regler
- Varje omgång ger ett heltal mellan 0 och 100 poäng.
- Spelarens totalpoäng är summan av de två omgångarna.
- Den som har högst totalpoäng vinner. Samma totalpoäng ger oavgjort, oavsett hur poängen fördelades mellan omgångarna.
- En segermarginal på 1–9 poäng ger texten Jämn final, 10–29 ger Tydlig seger och 30 eller mer ger Stor seger. Oavgjort ger texten Ingen segermarginal.
Krav på programmet
- Läs in fyra poängtal: grundpoäng och bonuspoäng för spelare A respektive spelare B.
- Beräkna båda totalpoängen och avgör resultatet.
- Beräkna marginalen som ett tal som är 0 eller större. Använd jämförelser och subtraktion.
- Skriv ut båda totalpoängen, resultatet, marginalen och en beskrivning av marginalen.
- Samla slututskriften efter beräkningarna. Använd variabler för resultatet och beskrivningen.
Exempel på körning
Utskrift
Grundpoäng A: 65 Bonuspoäng A: 30 Grundpoäng B: 80 Bonuspoäng B: 5 Totalpoäng A: 95 Totalpoäng B: 85 Resultat: Spelare A vinner Marginal: 10 poäng Tydlig seger
Testa din lösning
| A: grund + bonus | B: grund + bonus | Resultat | Marginal och beskrivning |
|---|---|---|---|
| 65 + 30 | 80 + 5 | A vinner | 10 – Tydlig seger |
| 50 + 0 | 49 + 0 | A vinner | 1 – Jämn final |
| 50 + 0 | 41 + 0 | A vinner | 9 – Jämn final |
| 50 + 0 | 21 + 0 | A vinner | 29 – Tydlig seger |
| 20 + 0 | 50 + 0 | B vinner | 30 – Stor seger |
| 20 + 30 | 40 + 10 | Oavgjort | 0 – Ingen segermarginal |
| 0 + 0 | 0 + 0 | Oavgjort | 0 – Ingen segermarginal |
| 100 + 100 | 0 + 0 | A vinner | 200 – Stor seger |
Utöver testfallen i tabellen: välj ett eget testfall, skriv det förväntade resultatet innan du kör och jämför sedan med programmets resultat.
Förklara din lösning
Vad händer om du byter plats på villkoren marginal < 10 och marginal < 30 utan att ändra något annat? Ge ett konkret exempel. Varför behöver du testa både en vinst för A och en vinst för B?
Tips om du kör fast
Lös uppgiften i två beslut: avgör först vinnare och beräkna marginalen. Klassificera därefter marginalen i en ny villkorskedja. Den andra kedjan behöver bara känna till marginalen, inte vem som vann.
Deklarera variabler för resultat och marginal före den första kedjan. I grenen där B vinner räknar du B:s total minus A:s total.
Lösningsförslag
Console.Write("Grundpoäng A: ");
int grundA = Convert.ToInt32(Console.ReadLine());
Console.Write("Bonuspoäng A: ");
int bonusA = Convert.ToInt32(Console.ReadLine());
Console.Write("Grundpoäng B: ");
int grundB = Convert.ToInt32(Console.ReadLine());
Console.Write("Bonuspoäng B: ");
int bonusB = Convert.ToInt32(Console.ReadLine());
int totalA = grundA + bonusA;
int totalB = grundB + bonusB;
int marginal;
string resultat;
if (totalA > totalB)
{
resultat = "Spelare A vinner";
marginal = totalA - totalB;
}
else if (totalB > totalA)
{
resultat = "Spelare B vinner";
marginal = totalB - totalA;
}
else
{
resultat = "Oavgjort";
marginal = 0;
}
string beskrivning;
if (marginal == 0)
{
beskrivning = "Ingen segermarginal";
}
else if (marginal < 10)
{
beskrivning = "Jämn final";
}
else if (marginal < 30)
{
beskrivning = "Tydlig seger";
}
else
{
beskrivning = "Stor seger";
}
Console.WriteLine($"Totalpoäng A: {totalA}");
Console.WriteLine($"Totalpoäng B: {totalB}");
Console.WriteLine($"Resultat: {resultat}");
Console.WriteLine($"Marginal: {marginal} poäng");
Console.WriteLine(beskrivning);Vinnaren avgör vilken subtraktion som ger en positiv marginal. Vid oavgjort tilldelas marginalen 0. Den efterföljande kedjan väljer exakt en beskrivning. Alla variabler som används i slututskriften har fått ett värde oavsett vilken gren som kördes.
Extrauppgift: m03x04 – Robotens energiplan
En robot ska genomföra ett uppdrag. Bygg en enkel modell som räknar ut energibehovet och avgör om batteriet räcker. Flera delar av uppdraget kan öka energibehovet samtidigt.
Regler
- Batterinivån anges i hela energienheter från 0 till 100.
- Uppdraget har en grundförbrukning på 10 energienheter och kostar dessutom 3 energienheter per meter. Sträckan är ett heltal från 0 till 20 meter.
- Tung last ökar förbrukningen med 15 energienheter.
- Ojämnt underlag ökar förbrukningen med 10 energienheter.
- Om batteriet inte räcker ska roboten inte starta. Visa då hur många energienheter som saknas.
- Om batteriet räcker ska programmet visa hur mycket som blir kvar: 0–9 betyder Ladda direkt efter uppdraget, 10–29 betyder Planera laddning snart och 30 eller mer betyder God energimarginal.
Krav på programmet
- Läs in batterinivå, sträcka och svar på om roboten har tung last respektive kör på ojämnt underlag. Svaren skrivs exakt
jaellernejmed små bokstäver. - Beräkna först hela energibehovet. Båda tilläggen ska räknas med när båda svaren är ja.
- Visa energibehovet. Avgör sedan om roboten får starta och ge rätt besked om energin.
- Vid för låg batterinivå: visa bristen som ett positivt tal och skriv inte att uppdraget genomförts.
- Vid exakt tillräcklig energi får roboten starta och har 0 kvar efter uppdraget.
Exempel på körning
Utskrift
Batterinivå: 80 Sträcka i meter: 10 Tung last (ja/nej): ja Ojämnt underlag (ja/nej): ja Energibehov: 65 Roboten kan starta. Energi kvar efter uppdraget: 15 Planera laddning snart
Testa din lösning
| Batteri | Meter | Tung last | Ojämnt | Behov | Förväntat besked |
|---|---|---|---|---|---|
| 80 | 10 | ja | ja | 65 | Starta, 15 kvar – planera laddning |
| 60 | 10 | ja | ja | 65 | Starta inte, 5 saknas |
| 40 | 10 | nej | nej | 40 | Starta, 0 kvar – ladda direkt |
| 49 | 10 | nej | nej | 40 | Starta, 9 kvar – ladda direkt |
| 50 | 10 | nej | nej | 40 | Starta, 10 kvar – planera laddning |
| 69 | 10 | nej | nej | 40 | Starta, 29 kvar – planera laddning |
| 70 | 10 | nej | nej | 40 | Starta, 30 kvar – god marginal |
| 55 | 10 | ja | nej | 55 | Starta, 0 kvar – ladda direkt |
| 50 | 10 | nej | ja | 50 | Starta, 0 kvar – ladda direkt |
| 0 | 0 | nej | nej | 10 | Starta inte, 10 saknas |
| 100 | 20 | ja | ja | 95 | Starta, 5 kvar – ladda direkt |
Utöver testfallen i tabellen: välj ett eget testfall, skriv det förväntade resultatet innan du kör och jämför sedan med programmets resultat.
Förklara din lösning
Varför får tilläggen inte ligga i samma if/else if-kedja? Vad kan bli fel om startbeskedet bestäms innan tilläggen har räknats med? Visa med ett eget testfall.
Tips om du kör fast
Börja med grundförbrukningen och sträckan. Använd två separata if-satser för tilläggen. Du kan uppdatera en variabel med exempelvis energibehov = energibehov + 15;.
Beräkna sedan energiKvar = batteri - energibehov. Ett negativt resultat betyder att energi saknas. En enda villkorskedja kan hantera negativt värde, mindre än 10, mindre än 30 och övriga värden. Det första villkoret gör att de följande grenarna bara hanterar uppdrag som går att genomföra.
Lösningsförslag
Console.Write("Batterinivå: ");
int batteri = Convert.ToInt32(Console.ReadLine());
Console.Write("Sträcka i meter: ");
int stracka = Convert.ToInt32(Console.ReadLine());
Console.Write("Tung last (ja/nej): ");
string tungLast = Console.ReadLine();
Console.Write("Ojämnt underlag (ja/nej): ");
string ojamntUnderlag = Console.ReadLine();
int energibehov = 10 + stracka * 3;
if (tungLast == "ja")
{
energibehov = energibehov + 15;
}
if (ojamntUnderlag == "ja")
{
energibehov = energibehov + 10;
}
int energiKvar = batteri - energibehov;
string besked;
string rad;
if (energiKvar < 0)
{
int saknas = energibehov - batteri;
besked = $"Roboten kan inte starta. Det saknas {saknas} energienheter.";
rad = "Ladda före uppdraget.";
}
else if (energiKvar < 10)
{
besked = $"Roboten kan starta. Energi kvar efter uppdraget: {energiKvar}";
rad = "Ladda direkt efter uppdraget";
}
else if (energiKvar < 30)
{
besked = $"Roboten kan starta. Energi kvar efter uppdraget: {energiKvar}";
rad = "Planera laddning snart";
}
else
{
besked = $"Roboten kan starta. Energi kvar efter uppdraget: {energiKvar}";
rad = "God energimarginal";
}
Console.WriteLine($"Energibehov: {energibehov}");
Console.WriteLine(besked);
Console.WriteLine(rad);Tilläggen är oberoende och beräknas därför med separata if-satser. Beskedet väljs först när hela energibehovet är känt. Ett negativt energiKvar används som beräkningsresultat för att upptäcka brist; det betyder inte att roboten faktiskt kör med negativ batterinivå.
Fördjupning efter 3.4
Här kombinerar du kunskaper från hela Moment03 hittills. Planera med pseudokod, dela upp problemet i beslut och beräkningar och välj testfall innan du programmerar. Uppgifterna kräver inga loopar, arrayer eller egna metoder.
Du får anta giltiga tal inom angivna intervall. Ja/nej-svar kan ha stora bokstäver och extra blanksteg runt texten. Bearbeta dem med Trim() och ToLower(). Menyval kan vara ogiltiga och ska hanteras enligt respektive uppgift. Varje program kör en gång.
Extrauppgift: m03x08 – Paketcentralen
En paketcentral behöver först avgöra om ett paket får skickas. För godkända paket ska programmet välja grundpris och lägga till rätt avgifter.
Regler
- Paketet får väga högst 20 kg och den längsta sidan får vara högst 150 cm.
- Grundpriset är 60 kr vid 1–5 kg, 90 kr vid 6–10 kg och 140 kr vid 11–20 kg.
- Ett hanteringstillägg på 40 kr gäller om paketet är längre än 100 cm eller väger mer än 15 kg. Tillägget tas ut en gång även när båda villkoren är sanna.
- Ömtåligt innehåll ger ytterligare 30 kr i tillägg.
Krav
Läs in vikt (heltal 1–30), längsta sida (heltal 1–200) och om innehållet är ömtåligt. För godkända paket ska grundpris, sammanlagda tillägg och totalpris visas. För nekade paket ska inget pris visas. Visa i stället alla överskridna gränser, vikt före längd.
Exempel
Utskrift
Vikt i hela kg (1–30): 16 Längsta sida i cm (1–200): 120 Ömtåligt innehåll (ja/nej)? JA Grundpris: 140 kr Tillägg: 70 kr Totalt: 210 kr
Testfall
| Vikt | Längd | Ömtåligt | Förväntat resultat |
|---|---|---|---|
| 5 | 100 | nej | 60 kr |
| 6 | 100 | nej | 90 kr |
| 10 | 100 | nej | 90 kr |
| 11 | 100 | nej | 140 kr |
| 15 | 100 | nej | 140 kr |
| 16 | 100 | nej | 180 kr |
| 5 | 101 | nej | 100 kr |
| 16 | 120 | ja | 210 kr |
| 20 | 150 | nej | 180 kr |
| 21 | 150 | nej | Nekat: vikt |
| 20 | 151 | nej | Nekat: längd |
| 21 | 151 | ja | Nekat: båda gränserna |
Att klura på
Varför blir två separata kontroller som vardera lägger på 40 kr fel? Vilka kontroller bör vara oberoende och vilka hör ihop?
Tips om du kör fast
Skilj mellan tillåtelse, grundpris och tillägg. Låt bara godkända paket gå vidare till prisberäkningen. Använd ett gemensamt villkor med || för hanteringstillägget, men en separat kontroll för ömtåligt innehåll.
Lösningsförslag
Console.Write("Vikt i hela kg (1–30): ");
int vikt = Convert.ToInt32(Console.ReadLine());
Console.Write("Längsta sida i cm (1–200): ");
int langd = Convert.ToInt32(Console.ReadLine());
Console.Write("Ömtåligt innehåll (ja/nej)? ");
string omtaligt = Console.ReadLine();
omtaligt = omtaligt.Trim().ToLower();
bool tillatenVikt = vikt <= 20;
bool tillatenLangd = langd <= 150;
if (tillatenVikt && tillatenLangd)
{
int grundpris;
if (vikt <= 5)
{
grundpris = 60;
}
else if (vikt <= 10)
{
grundpris = 90;
}
else
{
grundpris = 140;
}
int tillagg = 0;
if (langd > 100 || vikt > 15)
{
tillagg = tillagg + 40;
}
if (omtaligt == "ja")
{
tillagg = tillagg + 30;
}
int totalpris = grundpris + tillagg;
Console.WriteLine($"Grundpris: {grundpris} kr");
Console.WriteLine($"Tillägg: {tillagg} kr");
Console.WriteLine($"Totalt: {totalpris} kr");
}
else
{
Console.WriteLine("Paketet kan inte skickas.");
}
if (!tillatenVikt)
{
Console.WriteLine("Paketet får väga högst 20 kg.");
}
if (!tillatenLangd)
{
Console.WriteLine("Längsta sidan får vara högst 150 cm.");
}De två gränsreglerna används både för huvudbeslutet och för avslagsorsakerna, så booleska variabler hjälper här. Tillägget på 40 kr räknas en gång. Det ömtåliga innehållet kan ge ytterligare ett tillägg.
Extrauppgift: m03x09 – Spelresultat med bonus och avdrag
Ett spel har två banor. Resultatet påverkas av tid, misstag och hjälp. Reglerna måste användas i rätt ordning innan resultatet får en nivå.
Regler
| Menyval | Bana | Grundpoäng | Tidsgräns för bonus |
|---|---|---|---|
| 1 | Lätt | 100 | 60 sekunder |
| 2 | Svår | 200 | 90 sekunder |
- Bonus på 50 poäng ges bara om tiden är högst banans tidsgräns, spelaren har 0 misstag och ingen hjälp användes.
- Varje misstag ger 15 poängs avdrag.
- Hjälp ger 30 poängs avdrag en gång.
- Slutpoängen får aldrig bli negativ. Om beräkningen ger ett negativt tal ska resultatet sättas till 0.
- Minst 200 poäng ger guld, 100–199 ger silver och under 100 ger brons.
Krav
Läs in banvalet som text och välj grundpoäng samt tidsgräns med switch. Vid ogiltigt val ska ett felmeddelande visas och inga fler frågor ställas. Vid giltigt val: läs in tid (1–600 sekunder), antal misstag (0–50) och ja/nej om hjälp. Visa bonus, slutpoäng och nivå. En lång tid ger i sig inget avdrag.
Exempel
Utskrift
1. Lätt bana 2. Svår bana Välj bana: 2 Tid i hela sekunder (1–600): 90 Antal misstag (0–50): 0 Användes hjälp (ja/nej)? nej Bonus: 50 poäng Slutpoäng: 250 Nivå: Guld
Testfall
| Bana | Tid | Misstag | Hjälp | Slutpoäng | Nivå |
|---|---|---|---|---|---|
| 1 | 60 | 0 | nej | 150 | Silver |
| 1 | 61 | 0 | nej | 100 | Silver |
| 1 | 60 | 0 | ja | 70 | Brons |
| 1 | 60 | 1 | nej | 85 | Brons |
| 2 | 90 | 0 | nej | 250 | Guld |
| 2 | 91 | 0 | nej | 200 | Guld |
| 2 | 90 | 1 | nej | 185 | Silver |
| 2 | 90 | 6 | nej | 110 | Silver |
| 2 | 90 | 7 | nej | 95 | Brons |
| 1 | 60 | 10 | ja | 0 | Brons |
| 9 | – | – | – | Ingen beräkning | Felmeddelande |
Att klura på
Kan en spelare få guld utan bonus? Varför ska nivån bestämmas efter avdragen? Vilka tester avslöjar om någon skrivit || i stället för && i bonusvillkoret?
Tips om du kör fast
Låt switch välja banans värden. En boolesk variabel kan visa om valet är giltigt. Lägg resten av programmet i ett if-block som bara körs vid giltigt val.
Beräkna bonus och avdrag, sätt vid behov poängen till 0 och välj nivån sist. Kontrollera guldgränsen före silvergränsen.
Lösningsförslag
Console.WriteLine("1. Lätt bana");
Console.WriteLine("2. Svår bana");
Console.Write("Välj bana: ");
string bana = Console.ReadLine();
bana = bana.Trim();
int grundpoang = 0;
int tidsgrans = 0;
bool giltigBana = true;
switch (bana)
{
case "1":
grundpoang = 100;
tidsgrans = 60;
break;
case "2":
grundpoang = 200;
tidsgrans = 90;
break;
default:
giltigBana = false;
Console.WriteLine("Ogiltigt banval.");
break;
}
if (giltigBana)
{
Console.Write("Tid i hela sekunder (1–600): ");
int tid = Convert.ToInt32(Console.ReadLine());
Console.Write("Antal misstag (0–50): ");
int misstag = Convert.ToInt32(Console.ReadLine());
Console.Write("Användes hjälp (ja/nej)? ");
string hjalp = Console.ReadLine();
hjalp = hjalp.Trim().ToLower();
int bonus = 0;
if (tid <= tidsgrans && misstag == 0 && hjalp == "nej")
{
bonus = 50;
}
int hjalpavdrag = 0;
if (hjalp == "ja")
{
hjalpavdrag = 30;
}
int slutpoang = grundpoang + bonus - misstag * 15 - hjalpavdrag;
if (slutpoang < 0)
{
slutpoang = 0;
}
string niva;
if (slutpoang >= 200)
{
niva = "Guld";
}
else if (slutpoang >= 100)
{
niva = "Silver";
}
else
{
niva = "Brons";
}
Console.WriteLine($"Bonus: {bonus} poäng");
Console.WriteLine($"Slutpoäng: {slutpoang}");
Console.WriteLine($"Nivå: {niva}");
}Svår bana med 91 sekunder, inga misstag och ingen hjälp ger 200 poäng och guld utan bonus. Villkorskedjan väljer exakt en nivå. Grundvärdena 0 används inte för ett ogiltigt banval eftersom resultatberäkningen då hoppas över.
Extrauppgift: m03x10 – Gruppbeställningen
En restaurang vill ha en prisräknare för gruppbeställningar. Måltidsval, grupprabatt, medlemskap och efterrätt påverkar totalen. Det är särskilt viktigt att avgöra vilka rabatter som kan kombineras och när serviceavgiften ska beräknas.
Regler
- Menyval 1 är lunch för 90 kr per person. Menyval 2 är middag för 140 kr per person.
- Alla i beställningen väljer samma måltid.
- Minst 6 personer ger 15 procent grupprabatt på maten.
- Medlemmar får 10 procent rabatt på maten, men rabatterna får inte kombineras. Om båda gäller används grupprabatten.
- Efterrätt väljs till alla eller inga och kostar 35 kr per person. Efterrätten rabatteras aldrig.
- Om mat efter rabatt plus efterrätter kostar mindre än 500 kr tillkommer 40 kr i serviceavgift. Vid exakt 500 kr tas ingen avgift ut.
Krav
Välj måltid med switch. Ett ogiltigt menyval ska ge ett felmeddelande utan fler frågor eller prisberäkningar. Vid giltigt val: läs in antal personer (1–20), medlemskap och önskemål om efterrätt. Visa mat före rabatt, rabatt i kronor, efterrättskostnad, serviceavgift och totalpris. Använd double för beloppen och visa två decimaler.
Exempel
Utskrift
1. Lunch, 90 kr per person 2. Middag, 140 kr per person Välj måltid: 1 Antal personer (1–20): 6 Medlem (ja/nej)? ja Efterrätt till alla (ja/nej)? nej Mat före rabatt: 540,00 kr Rabatt: 81,00 kr Efterrätt: 0,00 kr Serviceavgift: 40,00 kr Totalt: 499,00 kr
Decimaltecknet kan vara punkt eller komma beroende på datorns inställningar.
Testfall
| Måltid | Antal | Medlem | Efterrätt | Rabatt | Service | Totalt |
|---|---|---|---|---|---|---|
| Lunch | 5 | nej | nej | 0,00 | 40,00 | 490,00 |
| Lunch | 6 | nej | nej | 81,00 | 40,00 | 499,00 |
| Lunch | 6 | ja | nej | 81,00 | 40,00 | 499,00 |
| Lunch | 6 | ja | ja | 81,00 | 0,00 | 669,00 |
| Lunch | 4 | nej | ja | 0,00 | 0,00 | 500,00 |
| Lunch | 4 | ja | ja | 36,00 | 40,00 | 504,00 |
| Middag | 4 | ja | nej | 56,00 | 0,00 | 504,00 |
| Middag | 6 | ja | ja | 126,00 | 0,00 | 924,00 |
Testa också ett ogiltigt menyval och textsvar med blandade stora och små bokstäver.
Att klura på
Varför kan fyra medlemmar som köper lunch och efterrätt få betala mer än fyra icke-medlemmar? Det är inte ett programmeringsfel om det följer reglerna. Förklara med beloppen.
Varför skulle två oberoende if-satser som båda drar av rabatt kunna ge fel? Vilken beräkning måste vara klar innan serviceavgiften bestäms?
Tips om du kör fast
Dela upp programmet i menyval, inmatning, val av rabatt och slutberäkning. Kontrollera grupprabatten först och medlemsrabatten som ett alternativ i samma kedja.
Beräkna ett mellanbelopp för mat efter rabatt plus efterrätt. Låt det beloppet styra serviceavgiften. Lägg avgiften till totalen sist.
Lösningsförslag
Console.WriteLine("1. Lunch, 90 kr per person");
Console.WriteLine("2. Middag, 140 kr per person");
Console.Write("Välj måltid: ");
string val = Console.ReadLine();
val = val.Trim();
double styckpris = 0;
bool giltigtVal = true;
switch (val)
{
case "1":
styckpris = 90;
break;
case "2":
styckpris = 140;
break;
default:
giltigtVal = false;
Console.WriteLine("Ogiltigt måltidsval.");
break;
}
if (giltigtVal)
{
Console.Write("Antal personer (1–20): ");
int antal = Convert.ToInt32(Console.ReadLine());
Console.Write("Medlem (ja/nej)? ");
string medlem = Console.ReadLine();
medlem = medlem.Trim().ToLower();
Console.Write("Efterrätt till alla (ja/nej)? ");
string efterratt = Console.ReadLine();
efterratt = efterratt.Trim().ToLower();
double matbelopp = styckpris * antal;
double rabatt = 0;
if (antal >= 6)
{
rabatt = matbelopp * 0.15;
}
else if (medlem == "ja")
{
rabatt = matbelopp * 0.1;
}
double efterrattskostnad = 0;
if (efterratt == "ja")
{
efterrattskostnad = antal * 35;
}
double efterRabatt = matbelopp - rabatt + efterrattskostnad;
double serviceavgift = 0;
if (efterRabatt < 500)
{
serviceavgift = 40;
}
double totalpris = efterRabatt + serviceavgift;
Console.WriteLine($"Mat före rabatt: {matbelopp:F2} kr");
Console.WriteLine($"Rabatt: {rabatt:F2} kr");
Console.WriteLine($"Efterrätt: {efterrattskostnad:F2} kr");
Console.WriteLine($"Serviceavgift: {serviceavgift:F2} kr");
Console.WriteLine($"Totalt: {totalpris:F2} kr");
}Fyra luncher med efterrätt kostar 500 kr utan medlemskap och ger ingen serviceavgift. Medlemsrabatten sänker mellanbeloppet till 464 kr, men serviceavgiften höjer totalen till 504 kr. Uppgiften kräver att medlemsregeln används, inte att programmet väljer bort rabatten. Grupprabatten kontrolleras först, så sex medlemmar får 15 procent rabatt en gång.
Inför diagnoserna
Nästa steg är att repetera momentets checklista, genomföra quizet och förbereda den praktiska diagnosen. Använd övningarna för att träna extra på de punkter där du är osäker.
3.7 Checklista efter momentet
Använd checklistan för att kontrollera dina kunskaper inför diagnoserna. Markera varje punkt med det alternativ som passar bäst:
- ✅ Kan – jag känner mig trygg med detta.
- ❓ Osäker – jag behöver repetera lite.
- 🔴 Träna – detta behöver jag öva mer på.
Checklista inför diagnos
Förklara varför ett booleskt uttryck blir true eller false. |
|
Använda jämförelseoperatorerna ==, !=, <, >, <= och >=. |
|
Skilja på tilldelning med = och jämförelse med ==. |
|
Använda if och else för att välja mellan två alternativ. |
|
| Följa vilka kodrader som körs inuti och efter ett villkorsblock. | |
| Kombinera inmatning, beräkningar och villkor i ett eget program. | |
| Beskriva ett enkelt beslut och programmets arbetsgång med pseudokod. | |
| Testa båda alternativen i ett villkor samt värden under, på och över en gräns. | |
Använda else if för att välja mellan flera alternativ. |
|
| Förklara varför det första sanna villkoret avgör vilken gren som körs i en villkorskedja. | |
| Ordna villkor så att programmets intervall och gränser blir korrekta. | |
Välja mellan en sammanhängande villkorskedja och flera separata if-satser. |
|
Jämföra ett textsvar med en bestämd sträng med ==. |
|
| Deklarera en variabel före ett villkor, tilldela den ett värde i grenarna och använda den efteråt. | |
| Förklara varför en variabel måste ha fått ett värde innan den används. | |
| Testa varje intervallgräns och kombinationer där flera oberoende villkor är sanna. | |
Använda && när båda kraven måste vara uppfyllda. |
|
Använda || när minst ett krav måste vara uppfyllt. |
|
Använda en boolesk variabel direkt i ett villkor och förklara !. |
|
Bearbeta textsvar med Trim() och ToLower() före jämförelsen. |
|
| Skriva fullständiga jämförelser på båda sidor om en logisk operator. | |
| Använda parenteser för att gruppera kombinerade villkor. | |
| Testa gränsvärden och olika kombinationer av sant och falskt. | |
| Följa ett nästlat villkor och förklara när det inre villkoret kontrolleras. | |
Avgöra vilket else som hör till vilket if med hjälp av klamrarna. |
|
| Välja mellan nästlade villkor, sammansatta villkor och separata if-satser. | |
| Planera beslut i flera steg med pseudokod. | |
| Beräkna delbelopp, rabatter och tillägg i en ordning som följer problemets regler. | |
Använda switch, case, break och default för ett enkelt menyval. |
|
| Testa olika vägar genom programmet och kombinationer som kan avslöja logiska fel. | |
| Dela upp en uppgiftstext i indata, regler, beräkningar och utdata. | |
| Planera ett sammanhängande program med pseudokod före programmeringen. | |
| Bygga och provköra ett program i mindre fungerande steg. | |
| Välja testfall och ange förväntat resultat före provkörningen. | |
| Förklara varför lösningen följer reglerna och hitta testfall som avslöjar logiska fel. |