Læringsmål:
- Switch
- fprintfUtskrift
- If-setningerBetingelser
- Funksjoner
- FOR-løkker
- ForWHILE-løkker
- Doble FOR-løkker
Pensum:
- 3.3 - Input and Output
- 3.7 - User-Defined Functions That Return a Single Value
- Kap 4.1 - The if Statement
- 4.2 - The if-else Statement
- 4
- Kap 3.3.2
- Kap 3.7
- Kap 5.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 I denne øvingen skal vi implementere funksjonen printCalendar
. Den skal vise en gyldig månedskalender gitt månednummer og år som parameter.
Om koden kjøres skal det se omtrent slik ut:
Code Block | ||
---|---|---|
| ||
Oktober 20142017 ma ti on to fr lo so 1 2 3 4 5 6 7 8 9 9 10 11 12 13 14 15 15 16 17 18 19 20 21 22 22 23 24 25 26 27 28 29 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. Første rad.Dagsnavn. Andre rad.:
Oktober 2017
- Navn på ukedager:
(
ma ti on to fr lo so) - Datoer for alle dager på riktig plass. Tredje til syvende rad. (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å a) Månedsnummer må gjøres om til månedsnavn. Lag funksjonen getMonthName(monthNumber)
som returnerer navnet på måneden gitt månedsnr.
Andre rad er en enkel iterasjon gjennom en liste av navn på dagene. De siste radene er mer bry: Disse utgjør en 6x7 matrise hvor radene er uker og kolonnene er ukedager. Denne matrisen kan se slik ut:månedsnummer som inputparameter.
Code Block | ||
---|---|---|
| ||
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 |
Tallet 0 representerer dager som ikke finnes i måneden.
Neste steg er å definere en funksjon som lager denne matrisen. Det gjør følgende funksjon:
>> getMonthName(7)
ans =
'Juli' |
Expand | ||
---|---|---|
| ||
Her kan det være lurt å benytte seg av en SWITCH-setning. |
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.
Code Block | ||
---|---|---|
| ||
Code Block | ||
| ||
function calendar = getCalendar ( year , month ) startDay = getMonthStartDay ( year , month ); numDays = daysInMonth ( yearmonth , monthyear ); 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 |
Her returnerer funksjonen daysInMonth
antall dager i måned, getMonthStartDay
returnerer nummeret på den første ukedagen i måneden (1 = Mandag, 2 = Tirsdag, ..., 7 = Søndag). I eksempelet med oktober 2014, returnerer daysInMonth
31 og getMonthStartDay
3.
...
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:
Code Block | ||
---|---|---|
| ||
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.
Expand | ||
---|---|---|
| ||
Her kan du bruke kode du har skrevet i tidligere øvinger dersom du ønsker det. |
Code Block | ||
---|---|---|
| ||
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 ...
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 |
Legg inn funksjonen getCalendar
(se over). Denne krever at vi implementerer funksjonene daysInMonth
og getMonthStartDay
. Du kan bruke filene daysInMonth.m og isLeapYear.m fra tidligere øvinger.
For å kunne definere funksjonen getMonthStartDay
trenger d) Vi kommer nå etterhvert til funksjonen getMonthStartDay().
For å skrive denne trenger vi først å vite hvilken dag året starter på.c) 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 ...
...
Expand | ||
---|---|---|
| ||
Året 1900 startet på en mandag. For hvert år flytter startdagen seg med en dag. |
...
Det vil si at 1901 startet på en tirsdag. Hvis året er et skuddår, flytter startdagen i neste år |
...
seg med to dager. Dersom du ønsker kan du også her benytte deg av kode du har skrevet i tidligere øvinger. |
For å teste denne funksjonen kan du kjøre følgende skript:
Code Block | ||||
---|---|---|---|---|
| ||||
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 |
de) 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).
Code Block | ||
---|---|---|
| ||
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 matrisedelene matrisedelen av kalenderen bør være en egen funksjon.:
ef) Lag funksjonen printDays(
daysmonth)
. Den skal ta inn matrisen som funksjonen i oppgave 3 lager som parameteren matrise med datoer som parameter, og printe skrive ut datoene disse som vist i toppen av øvingen. Denne funksjonen skal ikke returnere noen verdi. Funksjonshodet kan dermed se slik ut:
Code Block | ||
---|---|---|
| ||
function printDays ( days )
% Din kode
end |
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()
.
Code Block | ||
---|---|---|
| ||
>> 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.
gf) Lag funksjonen printCalendar(year, monthNumber)
. Parameterene er år og månedsnummer. Den benytter Funksjonen skal sette sammen alle de tidligere funksjonene. For å gjøre dette må funksjonen benytte seg av getMonthName
og getCalendar
og printer ut de to første linjene av kalenderen før den og lagre resultatene fra å kjøre disse funksjonene, før den til slutt kaller på printDays()
. Den Denne funksjonen skal heller ikke returnere noe, bare vise utskrift. men skal skrive ut utskriften som vist i eksempelet nedenfor.
Det ferdige resultatet kan se slik ut, dersom man kaller på printCalendar(2017, 10):
Code Block | ||
---|---|---|
| ||
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.
Code Block | ||
---|---|---|
| ||
>> 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 |