Firmaet har tekstfiler som inneholder et varierende antall observasjoner. Et utdrag er f.eks.:

Like dokumenter
varekategori (et felt uten blanke, IKKE case sensitiv)

Hvilke tall vises i listboksen etter at programmet er ferdig?

HØGSKOLEN I SØR-TRØNDELAG Avdeling for informatikk og e-læring - AITeL

HØGSKOLEN I SØR-TRØNDELAG Avdeling for informatikk og e-læring - AITeL

Eksamen i IBE202 Integrasjonslaboratorium Vår 2011 (SVARFORSLAG)

Høgskolen i Molde IBE150 Programmering Kontinuasjonseksamen (løsningsforslag) juni 2013

HØGSKOLEN I SØR-TRØNDELAG

HØGSKOLEN I SØR-TRØNDELAG Avdeling for informatikk og e-læring - AITeL

Løsningsforslag Eksamen i Programmering i Visual Basic høsten 2003 Laget av Runar Munkhaug

Visual Basic. Repetisjon fra onsdag

Løsningsforslag Øving 7

Visual Basic. Repetisjon fra mandag

HØGSKOLEN I SØR-TRØNDELAG

HØGSKOLEN I SØR-TRØNDELAG

HØGSKOLEN I SØR-TRØNDELAG

HØGSKOLEN I SØR-TRØNDELAG

Fasit til eksamen høst 2002, applikasjonsutvikling

HØGSKOLEN I SØR-TRØNDELAG

HØGSKOLEN I SØR-TRØNDELAG

UNIVERSITETET I OSLO

Bygg et Hus. Steg 1: Prøv selv først. Sjekkliste. Introduksjon. Prøv selv

Løse reelle problemer

Eksamensoppgaver 2014

Funksjoner og prosedyrer

Endret litt som ukeoppgave i INF1010 våren 2004

Lynkurs i shellprogrammering under Linux

EKSAMEN 6108/6108N PROGRAMMERING I JAVA Alt trykt og skriftlig materiale.

Bygg et Hus. Introduksjon. Steg 1: Prøv selv først. Skrevet av: Geir Arne Hjelle

UNIVERSITETET I OSLO

Obligatorisk oppgave 1 INF1020 h2005

Informasjon Prøveeksamen i IN1000 høsten 2018

Kap. 4: Ovenfra-ned (top-down) parsering

GJØVIK INGENIØRHØGSKOLE

Kapittel 1 En oversikt over C-språket

TDT4100 Objektorientert programmering

UNIVERSITETET I OSLO

TDT4165 PROGRAMMING LANGUAGES. Exercise 02 Togvogn-skifting

INF1000 (Uke 15) Eksamen V 04

INF1000 (Uke 15) Eksamen V 04

programeksempel Et større En større problemstilling Plan for forelesingen Problemstillingen (en tekstfil) inneholdt ordet "TGA"

Løse reelle problemer

INF1000 Eksamen 2014 (modifisert)

UNIVERSITETET I OSLO

TDT4102 Prosedyreog objektorientert programmering Vår 2016

Generelle Tips. INF Algoritmer og datastrukturer. Åpen og Lukket Hashing. Hashfunksjoner. Du blir bedømt etter hva du viser at du kan

UNIVERSITETET I OSLO

INF120: Oblig 3. Yngve Mardal Moe

Høgskoleni østfold EKSAMEN. Emne: Innføring i programmering

INF Algoritmer og datastrukturer

Betinget eksekvering og logiske tester i shell

<?php. count tar en array som argument, og returnerer et tall som uttrykker antallet innførsler i arrayen.

** Lag Sub lesutdelinger(f as String, u as Collection) som legger alle utdelinger i f til samlingen u. Dette er litt vanskelig, men her er noen hint:

Kap.4, del 2: Top Down Parsering Kap. 5, del 1: Bottom Up Parsing INF5110, 7/ Legger ut en oppgave til kap. 4 (se beskjed).

Hjelpemidler: 4 A4-sider (2 to-sidige ark eller 4 en-sidige ark) med egenproduserte notater (håndskrevne/maskinskrevne)

Kondisjonstest. Algoritmer og datastrukturer. Python-oppgaver. Onsdag 6. oktober Her er noen repetisjonsoppgaver i Python.

INF Ekstrainnlevering

UNIVERSITETET I OSLO

TDT4102 Prosedyre og Objektorientert programmering Vår 2015

IN Seminaroppgaver til uke 11

Algoritmer og datastrukturer A.1 BitInputStream

INF5110, onsdag 19. februar, Dagens tema: Parsering ovenfra-ned (top-down)

Høgskolen i Gjøvik. Avdeling for elektro- og allmennfag K O N T I N U A S J O N S E K S A M E N. EKSAMENSDATO: 11. august 1995 TID:

INF2810: Funksjonell Programmering

INF1010 notat: Binærsøking og quicksort

Oppdatering av person/studentforekomster i FS mot folkeregisteret

UNIVERSITETET I OSLO

Kap.4 del 2 Top Down Parsering INF5110 v2005. Arne Maus Ifi, UiO

løsningsforslag-uke5.txt

Ordliste. Obligatorisk oppgave 1 - Inf 1020

Algoritmer og datastrukturer E Løkker i Java

INF1000 Eksamen 2014 (modifisert)

Høgskoleni østfold EKSAMEN

INF2810: Funksjonell Programmering. Kommentarer til prøveeksamen

Eksamen i IBE150 Programmering Høst svarforslag!

Dagens tema: 12 gode råd for en kompilatorskriver

Dagens tema: 12 gode råd for en kompilatorskriver. Sjekking av navn. Lagring av navn. Hvordan finne et navn?

Rekursjon. Binærsøk. Hanois tårn.

Oblig 4 (av 4) INF1000, høsten 2012 Værdata, leveres innen 9. nov. kl

INF2810: Funksjonell Programmering

EKSAMENSOPPGAVE I INF-1100

TDT4105 Informasjonsteknologi grunnkurs: Uke 42 Strenger og strenghåndtering

Abaris-notat Teknisk beskrivelse av kodeverkskomponent for ICPC-2

Løse reelle problemer

INF2810: Funksjonell Programmering

Forside slutteksamen

UNIVERSITETET I OSLO

Eksamen i emnet INF100 Grunnkurs i programmering (Programmering I) og i emnet INF100-F Objektorientert programmering i Java I

Eksamensforelesning TDT4105

UNIVERSITETET I OSLO

Mammut Bokskred. Instruks for oppdatering av mammutfil og tilhørende mammut-rutiner i CS-Web.

Legg bort skilpaddene dine, i dag skal vi lære hvordan vi kan sende hemmelige beskjeder!

HØGSKOLEN I SØR-TRØNDELAG Avdeling for informatikk og e-læring - AITeL

INF2810: Funksjonell Programmering

UNIVERSITETET I OSLO

UNIVERSITETET I OSLO

EKSAMEN. Emne: Webprogrammering med PHP (kont.) Webprogrammering 1 (kont.) Eksamenstid:

Prøveeksamen inf november Arne Maus og Ole Christian Lingjærde

Leksjon 7. Filer og unntak

Forelesningsquiz. Forelesning inf Java 5. Sett dere to (eller tre) sammen og besvar de fire spørsmålene på utdelt ark. Tid: 15 min.

HØGSKOLEN I SØR-TRØNDELAG Avdeling for informatikk og e-læring - AITeL

Transkript:

OBS: Dokumentet inneholder spørsmålene, med svarforslag med kommentarer. Firmaet Hitogdit AS frakter containere og har lagret observasjoner om disse i tekstfiler. Du skal lage deler av et program med skjermbilde og knappenavn som under: Skriv programkode (helst Visual Basic), eventuelt bruk algoritmisk beskrivelse eller pseudokode for å forklare ditt svar. Besvar fem (5) av de seks (6) oppgavene (du velger!). De har lik vekt (20 %). 1 Innlesing Firmaet har tekstfiler som inneholder et varierende antall observasjoner. Et utdrag er f.eks.:... Fre Nov 19 14:00:49 CET 2007 Cont44_33 Havn-33 Sett Fre Nov 19 14:01:39 CET 2007 Cont44_33 Havn-33 Inspisert #Kapteinen i M/S Albatross ringte 18/11: Fre Nov 17 15:11:41 CET 2007 c_53_2x MS_AlbaTross SeTt Fre Nov 17 15:11:42 CET 2007 Cont53_299x MS_AlbaTross Sett... Lag prosedyren hentobs (filnavn) som leser inn filen filnavn. Denne blir f.eks. brukt ved oppstart (frmload) og hvis knappen btnlesfil velges. Hver linje angir en observasjon og inneholder: tid (seks felt for ukedag, måned, dato, klokkeslett, tidssone og årstall) cid (ett felt som angir unikt hvilken container observasjonen gjelder, casesensitiv) hvorid (ett felt som angir unikt hvor observasjonen ble gjort (havn, båt, lager, togvogn, m.m.; casesensitiv) hndid (ett felt som angir hva som hendte, ikke casesensitiv) For hver observasjon kalles prosedyren nyobs (tid, cid, hvorid, hndid), altså med fire (4) argument (prosedyren nyobs er spørsmål 2). OBS: Ikke ta 1

med linjer med feil antall felt, eller som begynner med grind (#, som er kommentarlinjer). Etterpå vises en melding om antall observasjoner som er OK, antall ignorerte kommentarlinjer og antall linjer med feil antall felt. Innlesingen skal ikke gi kjøretidsfeil (runtime error). sub hentobs (byval filnavn as string) dim antfeilantfelt as integer = 0 dim antkommentarer as integer = 0 dim antobservasjoner as integer = 0 dim melding as string = "" try dim sw as io.streamreader = io.file.opentext(filnavn) do while not sw.endofstream() dim ord() as string = s.readline().split() if not ord(0).substring(0,1) = # then antkommentarer += 1 elseif not ord.getupperbound(0) = 9 then antfeilantfelt += 1 else antobservasjoner += 1 Dim tid as string = "" for i as integer = 0 to 5 tid &= ord(i) & " " next Dim container as string = ord(6) Dim hvor as string = ord(7) Dim hendelse as string = ord(8) nyobservasjon (tid, container, hvor, hendelse) loop catch e as IO.Exception melding = "feil ved innlesing (avbrutt!)." finally melding &= " Observasjoner (lest): " & antobservasjoner & " Kommentarlinjer: " & antkommentarer & " Feil i linjen (ignorert): " & antfeilantfelt" msgbox (melding) end try Feltene har varierende bredde, så (som noen av studentene brukte) substr( 30,10) for utdrag av containerens ID vil ikke nødvendigvis virke. Utdrag av tidspunkt med substr(0,28) krever at dato starter i posisjon 0 (og en bør da angi en slik forutsetning i svaret). Pensum angir flere måter å finne ut hvor langt et felt er (finn neste blanke) før en tar ut substring av korrekt lengde. I svarforslaget brukes derimot split(), som også er pensum. Testen på om feltene er i orden (korrekt antall) kan (som noen brukte) gjøres ved å sjekke om noen av feltene er tom streng. Hvis en antar at kommentartegnet (grinda) starter i posisjon 0 (og at blanke aldri forekommer i starten av linja) bør dette angis. Det var ikke meningen at hentobs skulle lagre observasjonene (likevel gjorde noen av studentene dette). Ikke alle skriver melding etter innlesingen er avsluttet. Ikke alle tar seg av runtimefeil. 2

OBS: Allerede her merker en at flere ikke bruker innrykk (det trekker). Og, de sier sjelden hvordan de har tolket oppgaven. 2 Intern lagring Prosedyren nyobs (t, c, h, hnd) (nevnt i spørsmål 1) skal være spesialist i å ta vare på nye observasjoner. De fire argumentene er (som nevnt) t: tid (en streng med seks felt) c: containerens ID (streng) h: sier hvor observasjonen ble gjort (streng) hnd: hendelse (streng) Du skal lage flere prosedyrer for ulike måter å lagre på. Hver prosedyre tar de samme fire strenger som parameter. De tre prosedyrene under forutsetter deklarasjonen: Dim maxantobs as Integer = 1000 dim antobs as integer = 0 1. Skriv nyobs_struktur(t,c,h,hnd) som bruker en 1-dimensjonal tabell (gi den navn cobs ) med datastrukturer. Vis definisjonen av datastrukturen (bruk structure). Merk: Du vil bruke tabellen cobs i spørsmål 3 og 6. structure observasjon dim tid as string dim container as string dim hvor as string dim hendelse as string end structure dim obs(maxantobs-1) as observasjon sub nyobs_struktur (byval tid as string, byval container as string, byval hvor as string, byval hendelse as string) if antobs < maxantobs then obs(antobs).tid = tid obs(antobs).container = container obs(antobs).hvor = hvor obs(antobs).hendelse = hendelse antobs += 1 2. Skriv nyobs_todim(t,c,h,hnd) som lagrer observasjonene i en 2-dimensjonal tabell (kall den gjerne cobs2d ). 3

Dim obs2d(maxantobs-1,3) as string sub nyobs_todim (byval tid as string, byval container as string, byval hvor as string, byval hendelse as string) if antobs < maxantobs then obs2d(antobs,0) = tid obs2d(antobs,1) = container obs2d(antobs,2) = hvor obs2d(antobs,3) = hendelse antobs += 1 3. Skriv nyobs_firetabeller(t,c,h,hnd) som lagrer observasjonene ved hjelp av fire 1-dimensjonale tabeller (velg passende navn). Dim obstid(maxantobs-1) as string Dim obscontainer(maxantobs-1) as string Dim obshvor(maxantobs-1) as string Dim obshendelse(maxantobs-1) as string sub nyobs_firetabeller (byval tid as string, byval container as string, byval hvor as string, byval hendelse as string) if antobs < maxantobs then obstid(antobs) = tid obscontainer(antobs) = container obshvor(antobs) = hvor obshendelse(antobs) = hendelse antobs += 1 Husk alle nødvendige deklarasjonene. Nye observasjoner skal legges til ledig plass, og husk: Tabellene (med plass til ti tusen) kan gå full! Flere hadde overraskende nok (selv om det ikke er et viktig moment i oppgaven) andre prosedyrenavn (som lagre(), selv om det uttrykkelig står hva prosedyren skal hete! En annen overraskelse, var at flere hadde lagret til fil (som ikke er nevnt i oppgaven) istedetfor til tabeller. Dette er en alvorlig feil. Vel, de som hadde oppfattet oppgaven slik at man skulle legge inn i en tabell var (oftest) betenksom nok til å sjekke om tabellen(e) hadde plass. Noen nektet å overfylle, andre redimensjonerte (utvidelse) etter behov. 3 Vising Anta at observasjonene ligger i tabellen cobs med datastrukturer (type 1 fra spørsmål 2). Og, vi har knappeprosedyren sub btnvis_click () handles... dim n as integer = cint(inputbox("oppgi n: ")) dim k as integer = cint(inputbox("oppgi k: ")) visobs (n, k) 4

Din oppgave: Lag prosedyren visobs ( n, k ) som viser observasjonene i en listbox (lsta). Den skal ikke vise mer enn n observasjoner. Og, den skal bare vise hver k de observasjon. Som eksempel, visobs(30, 1) viser ikke mer enn de 30 første, visobs(40, 2) viser observasjon nummer 1, 3, 5, 7... inntil maksimalt 40 er vist. Hver observasjon vises som under (den 4de i eksemplet fra spørsmål 1), men data om observasjonene skal vises i en annen rekkefølge enn de ligger på fil: 4: Cont53_299x SETT at MS_AlbaTrossFre (Nov 17 15:11:42 CET 2007) Hvis du ikke klarer å ta hensyn til k kan du jo gi et enklere svar som viser maksimalt n, eller (hvis det også blir for vanskelig), gi et svar som viser alle observasjonene. sub visobs (byval n as integer, byval k as integer) dim i as integer = 0 lsta.items.clear() do while i < n and i i*k < antobs lsta.items.add(i*k & ": " & obs(i*k).container & " " & obs(i*k). hendelse.toupper() & " at " & obs(i*k).hvor & " (" & obs(i*k ).tid & ")" i+=1 next Ikke alle besvarelsene skriver ut med angitt format (kolon, paranteser, blanke og andre tegn). Runtimefeil hvis en leser utenfor tabellen blir ikke alltid unngått eller håndtert men, oppgaven sier riktignok ikke noe om at dette skal håndteres. Minst en student brukte step-varianten: for i = 0 to X step k der X settes til rett sluttverdi men, en må også her sikre at en ikke leser utenfor tabellens grenser. Få hadde sikret store bokstaver for hendelse (med toupper). Noen har i sitt svar, lest inn filen og vist den i listboksen, hvilket ikke gir poeng! 4 Containerliste Anta at du har cnavn, som er en sortert tabell over kjente containernavn, uten gjentakelser (duplikat). Observasjonene i eksemplet (fra spørsmål 1) gir Cont44_33 Cont53_299x c_53_2x Tabellen har plass til 500 navn, men trenger ikke være helt full. Din oppgave er: Lag funksjonen poscontainer (cnavn) som leter etter cnavn og gir rett posisjon hvis funnet, eller -1 hvis ikke funnet. Klienten kan altså bruke denne til å finne posisjon, som i dim pos as integer = poscontainer ( container_navn ) if not pos = -1 then msgbox ( container_navn & " fant vi i posisjon " & pos) end Funksjonen brukes ofte og bør jobbe raskt! Hvis cnavn er siste av 500 bør funksjonen være meget lurere enn å ha sjekket de 499 foran! 5

function poscontainer (byval c as string) as Integer tilpasser eksempel 5, s. 367 i pensumboken (Schneider) Dim first, middle, last as integer Dim foundpos as Integer = -1 first = 0 last = antobs-1 do while (first <= last) and (foundpos = -1) middle = cint(int((first + last) / 2)) select case cnavn(middle) case c foundpos = middle case is > c last = middle - 1 case is < c first = middle + 1 end select loop return foundpos end function Oppgaven bruker cnavn om tabellen, og sier at en skal skrive en funksjon som tar cnavn som parameter, og i ettertid ser en at dette kan forvirre hvis en ikke har godt tak på prinsippene. Ellers: Flere hadde lagt inn en sortering (før selve letingen), selv om oppgaven sier at tabellen er (ferdig) sortert. I besvarelsene hadde enkelte ikke angitt at funksjonen returnerer et tall. Flere studenter la resultatet i et ByRef-supplert parameter (ikke som funksjonens returverdi, slik angitt i oppgaven). Andre hadde tilpasset Schneiders rutine og (ubevisst) tatt med toupper() slik at containerens ID ikke kan betraktes som case-sensitiv. En kan ikke bruke getupperbound(0) for å unngå runtimefeil! Til sist: De som leter gjennom hele tabellen (i sin hele lengde), og ikke bare blant de element der det faktisk ligger navn, må vurdere hva som skjer når en leter i tomrom. 5 Normalisering Anta at du har tabell med unike containernavn (cnavn, se spørsmål 4) Hvis knappen btnnormalisering trykkes, skal tabellen normaliseres slik at alle navn enten får store eller små bokstaver (avhengig av brukerens valg). Vi har knappe-prosedyren sub btnnormaliser_click() handles... if radlowercase.checked() then normalisercont(cnavn, "lower") else normalisercont(cnavn, "upper") Anta at det er 48 navn i cnavn som har plass til 500 element. Din oppgave er å se på to måter å normalisere på: 1. En av de erfarne programmererne har laget prosedyren sub normalisercont ( byval a() as String, byval t as String ) 6

for i as integer = 0 to a.getupperbound(0) if t = "upper" then a(i) = a(i).toupper else a(i) = a(i).tolower endif next Dessverre feiler denne. Finn ut hvorfor, og forklar årsaken, samt foreslå korrigering. Hvis det ikke ligger noe i et element kan en få runtimefeil (altså bør en vurdere om hele tabellen skal sjekkes, eller bare det antall navn man er sikker på å ha). Det er syntaktisk feil at endif ikke er skrevet (med mellomrom). En student påpekte at en burde eksplisitt teste om t var lower istedet for å anta det. Dette minimerte sjansen for den tredje sorten feil (logiske). En student fant ut at med ByVal overføring av tabellargumentet, ville prosedyren endre kopien og ikke originalen (også en logisk feil). Noen mente at toupper og tolower ville feile for tall, men det vil ikke skje (bare bokstavene tas i betraktning i disse funksjonene). Et forslag om at en i kallet av prosedyren, skulle ha med paranteser bak tabellnavnet (i argumentlisten) er ikke riktig det er i selve funksjonen (i parameterlisten) at en angir paranteser for tabeller. Andre lot seg forville av toupper (funksjonen) og upper (strengen) og foreslo nyttesløse endringer. Forslag om try-catch for blind oppfanging av eventuelle feil (fordi man ikke fant feilen) ble prisverdig fremsatt av flere. 2. En av de andre programmererne foreslår istedet at vi går over til å bruke en ganske annen variant: sub normalisercont ( byval a as String, byval i as integer, byref t as String ) if t = "upper" then a(i) = a(i).toupper else a(i) = a(i).tolower normalisercont (a, i+1, t) Denne har tre parametre, og kalles derfor med: normalisercont ( cnavn, 1, "upper" ) Nå er den ikke prøvekjørt, så det er uklart om det blir feil. Gi din vurdering og foreslå korrigeringer til eventuelle feil og problem du ser. Her finnes en syntaksfeil, at parameter for tabellen ikke har paranteser, det skal stå a() og ikke bare a. Et annet (meget viktig) problem er at den rekursive (det ser man jo at den er) funksjonen ikke stopper når arbeidet er ferdig. Den burde innledes med en test som i det minste bryter ut (det vil si, ikke kaller seg selv nok en gang) 7

når alle navnene er normalisert, og iallefall hvis i > a.getupperbound( 0) (gardering mot runtimefeil). En annen feil er at rekursjonen innledes med i satt til 1, slik at det første elementet (som ligger i index 0) utelates. Som for den ikke-rekursive, vil en med ByVal ikke endre originalen, men en kopi (logisk feil). 6 Statistikk Knappen btnstatistikk skal gi brukeren en frekvenstelling over datoer blant observasjonene. Anta at vi har knappe-prosedyren: Private Sub btnstatistikk_click() Handles... finnogvisfrekvens ( ) End Sub Lag prosedyren finnogvisfrekvens ( ) som finner og viser (i lsta) hvor ofte de ulike datoene opptrer i tabellen med observasjoner (anta at de ligger i cobs med strukturer, type 1 fra spørsmål 2). Frekvenstellingen kan f.eks. gi dato 1 2... 31 antall 229 77... 422 Prosedyren skal gi utskriften (hvis vi antar 14000 observasjoner): 1 (229) 1.6% 2 (77) 0.6 %... 31 (422) 3.1 % Over ser en at 229 observasjoner av dato 1 utgjorde 1.6 %. Dim cstat() as String sub finnogvisfrekvens ( ) dim ant(31) as integer dim antok as Integer for i as integer = 0 to antobs - 1 dim o() as string = tid(i).split dim dato as integer = cint(o(2)) if dato > 0 and dato < 32 then ant(dato) += 1 antok += 1 next for i as integer = 0 to n-1 cstat(i) = i & " (" & ant(i) & ") " & ant(i)/antok * 100.0 & "%" end for Flere hadde brukt tellerne tellerdato1, tellerdato2,..., tellerdato31, istedetfor en mye enklere tabell. I et tilfelle ble datoene lagret i en tabell, før tabellen ble opptelt (en trenger ikke et slikt mellomsteg, da en kan telle opp umiddelbart). 8