Læringsmål:
- Switch
- Utskrift
- Betingelser
- Funksjoner
- FOR-løkker
- WHILE-løkker
- Doble FOR-løkker
Pensum:
- 3.3 - Input and Output
- 3.7 - User-Defined Functions That Return a Single Value
- 4.1 - The if Statement
- 4.2 - The if-else Statement
- 4.3 - Nested if-else Statement
- 4.4 - The switch statement
- 5.1 - The FOR-loop
- 5.2 - Nested FOR-loops
- 5.3 - While loops
- 5.4 - Loops with Vectors and Matrices: Vectorizing
Denne øvingen er en mye mer omfattende øving enn hva dere er vant med til nå. Vi skal nå implementere flere forskjellige funksjoner, og til slutt sette alle disse sammen til et program som gir oss en utskrift av en kalender.
Når koden til slutt kjøres skal det se omtrent slik ut:
Oktober 2017 ma ti on to fr lo so 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31
Dette problemet må brytes ned i mindre oppgaver. Fra utskriften ser man at den består av tre deler:
- Månedsnavn og årstall:
Oktober 2017
- Navn på ukedager:
(
ma ti on to fr lo so) - Datoer for alle dager på riktig plass. (Datoene 1 til 31)
Vi skal nå implementere de forskjellige funksjonene som gir oss disse tre delene. Deretter skal alle disse settes sammen til å produsere utskriften som vist over.
a) Første funksjon vi skal lage gir oss navnet på en måned, gitt et månedsnummer input. Hvis funksjonen tar inn tallet 1 skal den returnere 'Januar', hvis den tar inn 2 skal den returnere 'Februar', etc. Lag nå funksjonen getMonthName(monthNumber)
som returnerer navnet på måneden gitt månedsnummer som inputparameter.
>> getMonthName(7) ans = 'Juli'
Hvis vi nå ser på oppgaven igjen, og den utskriften vi til slutt skal komme frem til, ser vi at vi på en eller annen måte må få skrevet ut de forskjellige ukedagene i kalenderen. Vi har allerede skrevet kode for deg som tar inn et årstall og et månedsnummer og returnerer en matrise som gir deg en liknende utskrift. Ta nå og kopier koden nedenfor, og lagre det som getCalendar.m i øvingsmappen din.
function calendar = getCalendar ( year , month ) startDay = getMonthStartDay ( year , month ); numDays = daysInMonth ( month , year ); calendar = zeros ( 6, 7 ); date = 0; for week = 1:6 for day = 1:7 if ( date == 0 ) if ( week == 1 && day == startDay ) date = 1; end else if ( date < numDays ) date = date + 1; else date = 0; end end calendar (week , day ) = date ; end end end
Når du har lagt inn denne koden, vil ikke denne kjøre med det første, dette er noe vi skal fikse etterpå. Det eneste du trenger å merke deg nå er utskriften denne funksjonen (til slutt) skal gi ut:
month = 0 0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 0 0 0 0 0 0 0 0 0
Her representerer tallet 0 dager som ikke finnes i måneden. Vi ser at dette begynner å ligne på kalenderen som ble vist som eksempel øverst i øvingsoppgaven.
b) Du har sikkert lagt merke til at vi bruker noen funksjoner i getCalendar()
som vi ikke har laget enda. Din oppgave nå er å implementere funksjonen daysInMonth(monthNumber, year)
. Funksjonen skal returnere antall dager i en måned, gitt et månedsnummer av samme type som i oppgave a). Du må også ta hensyn til skuddår.
daysInMonth (1, 1999) % skal skrive ut 31 daysInMonth (2, 2001) % skal skrive ut 28 daysInMonth (4, 2017) % skal skrive ut 30 daysInMonth (2, 2004) % skal skrive ut 29
getCalendar
-funksjonen over. Gå gjennom funksjonen og skriv ned verdien til variablene week, day og date for hver iterasjon i den indre for-løkken. Du skal med andre ord ikke skrive eller kjøre kode, dette er en øving i å se for seg hvordan koden vil kjøre på forhånd, noe som kreves på eksamen.Det holder å skrive ned de første 12 iterasjonene, og deler av tabellen er fylt ut nedenfor.
Iterasjon | week | day | date |
---|---|---|---|
1 %fyll inn 12 | 1 % 2 | 1 % 5 | 0 % 10 |
d) Vi kommer nå etterhvert til funksjonen getMonthStartDay().
For å skrive denne trenger vi først å vite hvilken dag året starter på. Derfor lager vi først en hendig hjelpefunksjon til å regne ut dette for oss.
getYearStartDay(year)
. Funksjonen skal ta inn et årstall som parameter og returnere hvilken ukedag året starter på (1 = Mandag, 2 = Tirsdag, ..., 7 = Søndag). For å teste denne funksjonen kan du kjøre følgende skript:
getYearStartDay (1900) % skal returnere 1 getYearStartDay (1901) % skal returnere 2 getYearStartDay (1902) % skal returnere 3 getYearStartDay (1903) % skal returnere 4 getYearStartDay (1904) % skal returnere 5 getYearStartDay (1905) % skal returnere 7 getYearStartDay (1906) % skal returnere 1 getYearStartDay (2012) % skal returnere 7
e) Lag nå funksjonen getMonthStartDay(year, monthNumber)
. Den skal ta inn et årstall og et månedsnummer som parameter (1 = Januar, 2 = Februar, ..., 12 = Desember). Funksjonen skal returnere hvilken ukedag måneden starter på (1 = Mandag, 2 = Tirsdag, ..., 7 = Søndag).
getMonthStartDay (2012 , 0) % skal returnere 0 getMonthStartDay (2012 , 1) % skal returnere 7 getMonthStartDay (2012 , 2) % skal returnere 3 getMonthStartDay (2012 , 3) % skal returnere 4 getMonthStartDay (2012 , 4) % skal returnere 7 getMonthStartDay (2012 , 5) % skal returnere 2 getMonthStartDay (2012 , 6) % skal returnere 5 getMonthStartDay (2012 , 7) % skal returnere 7 getMonthStartDay (2012 , 8) % skal returnere 3 getMonthStartDay (2012 , 9) % skal returnere 6 getMonthStartDay (2012 , 10) % skal returnere 1 getMonthStartDay (2012 , 11) % skal returnere 4 getMonthStartDay (2012 , 12) % skal returnere 6 getMonthStartDay (2012 , 13) % skal returnere 0
Du har hittil brutt kalenderen ned i mindre funksjoner. Nå skal de settes sammen og en kalender skal vises. disp()
er for enkel, derfor må fprintf()
benyttes. Se fprintf
for bruk.
Å vise matrisedelen av kalenderen bør være en egen funksjon:
f) Lag funksjonen printDays(month)
. Den skal ta inn en matrise med datoer som parameter, og skrive ut disse som vist under. Her må vi nå benytte oss av getCalendar()
-funksjonen vi la inn tidligere, og du kan se eksempelutskriften fra denne for å se for deg hvordan input vil se ut. printDays() skal ikke returnere noen verdi, men skrive ut en utskrift ved hjelp av fprintf()
.
>> printDays(month) 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31
Merk deg at vi nå har erstattet 0-tallene fra getCalendar med mellomrom (whitespace). Det er opp til deg selv å finne en god løsning på dette.
g) Lag funksjonen printCalendar(year, monthNumber)
. Parameterene er år og månedsnummer. Funksjonen skal sette sammen alle de tidligere funksjonene. For å gjøre dette må funksjonen benytte seg av getMonthName
og getCalendar
og lagre resultatene fra å kjøre disse funksjonene, før den til slutt kaller på printDays()
. Denne funksjonen skal heller ikke returnere noe, men skal skrive ut utskriften som vist i eksempelet nedenfor.
Det ferdige resultatet kan se slik ut, dersom man kaller på printCalendar(2017, 10):
Oktober 2017 ma ti on to fr lo so 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31
h) () Frivillig.
Utvid printCalendar til også å printe ukenummer. For å få til dette, må du også lage nye funksjoner og utvide eksisterende.
Dette er en veldig vanskelig oppgave.
>> printCalendar(2017, 9) September 2017 Uke ma ti on to fr lo so 35 1 2 3 36 4 5 6 7 8 9 10 37 11 12 13 14 15 16 17 38 18 19 20 21 22 23 24 39 25 26 27 28 29 30 >> printCalendar(2017, 1) Januar 2017 Uke ma ti on to fr lo so 52 1 1 2 3 4 5 6 7 8 2 9 10 11 12 13 14 15 3 16 17 18 19 20 21 22 4 23 24 25 26 27 28 29 5 30 31