søndag 30. september 2007

Oblig 5: Tabellomformer

Du skal lage et program som (til venstre) lar brukeren oppgi HVA som skal skje med en tabell (ved navn X). Resultatet (X) vises i en scrollbar listboks (til høyre) ved navn lstA. Programmet har EN global variabel: En tabell av heltall ved navn X, initielt med 0 (null) element. Flere globale i ditt program tolereres IKKE! Det skal lages en rekke eventprosedyrer som tar seg av brukerens ønske og viser resultatet i lstA. Noen forslag til tillegg ("Hvis du vil") er angitt (men ikke obligatorisk).
  • Lag deg en funksjon hentHeltall(t) som returnerer et heltall fra parameter t (en String). Funksjonen SKAL brukes minst to steder!
  • Bruker ser en knapp for "størrelseendring" (btnStorrelseEndring) som, hvis trykket, ber brukeren med inputbox() oppgi en størrelse intAntElement. Bruk hentHeltall(). Hvis dette er identisk med X's lengde skriver du "Ingen endring!" i msgbox(). Hvis ikke, kaller du subrutinen nyStorrelse(a, n) med X og intAntElement som argument. Innholdet skal preserveres. Be brukeren med inputbox() bekrefte (ja/nei) hvis tabellen skal ned i omfang (og verdier kan bli borte!).
  • Brukeren ser en knapp for "elementendring" (btnElementEndring) som, hvis trykket, ber brukeren oppgi en index (intIndex) med inputbox() og hentHeltall(). Hvis legal index, skal brukeren oppgi ny verdi (intVerdi) med inputbox() og hentHeltall() som deretter legges inn i X i posisjon intIndex.
  • brukeren ser en knapp "Sjekk stigende" (btnSjekkStigende) som hvis trykket, skriver "tabellen er (ikke) stigende" i msgbox(), avhengig av resultatet fra den boolske funksjonen erStigende(a) som kalles med X som argument. Hvis du vil: Denne funksjonen (erStigende) skriver melding med msgbox() som sier f.eks. "erStigende: feil i linje 11 og 12".
  • brukeren ser en knapp "Reverser" (btnReverser), som hvis trykket, kaller rutinen reverser(a) med X som argument. Denne subrutinen (ikke funksjon!) snur opp ned på tabellen.
  • Hver gang bruker har gjort noe, og X blir endret, skal resultatet vises. Etter f.eks. reversering, kalles subrutinen visTabell(a,l) med X og lstA som argument. Denne visTabell(a,l) viser tabell-elementene som med nr og innhold, f.eks. "3: 77" hvis det ligger 77 i fjerde element.
Resten er Hvis du vil
  • Brukeren ser en knapp for "Lineariser" (btnLineariser), som hvis trykket, ber bruker oppgi intStartverdi og intStigningstall (med inputbox og hentHeltall). Deretter kalles subrutinen lineariser(a,start,k) med X, intStartverdi og intStigningstall som parameter. Subrutinen legger verdien start+k*i inn i element a(i). Hele tabell a skal fylles, slik at f.eks. en tre-elements tabell blir
    • { 3, 4, 5 } hvis start=3 og k=1 (stigende)
    • med 3 og -2 blir resultatet { 3, 1, -1 } (synkende)
    • med 4 og 0 (null) blir det { 4, 4, 4 } (alle blir lik)
  • Brukeren ser en knapp for "Randomiser" (btnRandomiser), som hvis trykket, spør bruker (med inputBox og hentHeltall) etter heltallene minV og maxV. Deretter kalles subrutinen randomiser(a, laveste, hoyeste) med X, minV og maxV som argument. Denne subrutinen legger tilfeldige verdier inn i alle plasser (i tabell a), ved hjelp av Math.Random (bak i boka).
  • brukeren ser en knapp "Sorter" (btnSorter), som hvis trykket kaller rutinen sorter(a) med X som argument. Denne tar seg av stigende boblesortering og skriver msgbox som sier "sorter: Gjorde 239 sammenligninger og 200 ombyttinger".
  • Opprett en lstB (til høyre for lstA). Etter at bruker ber om omforming av tabellen skal du først kalle visTabell(a,l) med X og lstB som argument. Slik blir X vist i lstB. Deretter endres tabellen. Etter endringen kalles visTabell(a,l) med X og lstA som argument. Nu kan du sammenligne!

fredag 28. september 2007

Forelesning uke 40

Jeg foreleser videre om tabeller f.k. mandag (1/10, sekvensiell vs. binaer leting, s. 365).

Torsdag er det forelesningsfri (jeg er ute).

Fredag blir det forelesning (flerdimensjonale tabeller, kap. 7.5).

Uka deretter er jeg ute igjen (ingen forelesninger noen av dagene).

Fredag 28/9: Bytting, sortering og reversering

To variabler, element (i og j) i en tabell, bytter innebyrdes verdi med mønsteret (s. 356)
   
  tmp = a(j)
  a(j) = a(i)
  a(i) = tmp
som kan skrives som VB subrutine (som jobber på originalen):
  
   Sub bytt (ByRef a() as Integer, i as Integer, j as Integer)
      Dim tmp as Integer = a(j)
      a(j) = a(i)
      a(i) = tmp
   End Sub
En tabell boblesorteres med prosedyren (der dere i grupper på to fant ut de tre grønne biter av koden):
   
   Sub sorter (ByRef a() As Integer)
      For i As Integer = a.getUpperBound(0)-1 To 0 Step -1
         For j As Integer = 0 to i
            If a(j) > a(j+1) Then
               Bytt (a, j, j+1)
            End If
         Next
      Next
   End Sub
Denne arbeider direkte på original (ByVal), og gjør samme arbeidet som s. 359 (men koden er skrevet noe annerledes). Fordelen med at denne er generell subrutine er (s. 132) at koden skrives ETT STED (blir ekspert) og kan gjenbrukes. De siste 15 minutt arbeidet gruppene med en reverseringsprosedyre, som f.eks. den under:
  
   Sub reverser (ByRef a() as Integer)
      Dim n as Integer = a.GetUpperBound(0)
      For i as Integer = 0 to n/2
         Bytt (a, i, n-i)
      Next
   End Sub

torsdag 27. september 2007

Torsdag 27/9: Tabellanalyse

Arbeid som gjøres med en tabell kan være (boka har flere eksempler):
  • funksjoner som regner ut tabellens sum, snitt, minste og høyeste verdi
  • subrutiner som reverserer innholdet
  • sortering, fletting
I grupper på to laget man funksjonen erStigende som en tenkt klient bruker som følger:
 dim t1() as integer = { 0, 2, 3, 3 }
 dim t2() as integer = { -2, 7, 9, 10 }
 if erStigende (t1) and erStigende (t2) then
   ...
 end if
Rudi og Johans forslag ble antatt (selv om ByVal gir kopiering av tabellen):
 Function erStigende (ByVal a() as Integer) As Boolean
   Dim n as Integer = 0
   Do
     If a(n) > a(n+1) Then
       Return False
     End If
     n += 1
   Loop Until n = a.GetUpperBound(0)
   Return True
 End Function
I labtimene ble gruppene bedt om å jobbe med prosedyren Reverser(a) som snur opp ned på innholdet i tabellen (og jobber på originalen).

mandag 24. september 2007

Mandag 24/9: Rekkefølge, leting og fletting

Tabeller kan være ORDNET (sortert stigende eller synkende), eller ikke-ordnet. Et SØK i en ordnet tabell kan avslutte tidligere enn i ikke-ordnede tabeller, der en ikke kan konkludere før alle elementene er sjekket. Som i oblig 4, der tabellen neppe er ordnet (sortert). To tabeller (A og B) kan slås sammen til en tredje C. Med FLETTING (merging) menes at C blir sortert som A og B. Algoritmen ble gjennomgått (kap. 7.2).

fredag 21. september 2007

Fort i svingene

Opprinnelig innlegg:
En liten påminnelse. Vi har snakket litt imellom oss i klassen og vi fant ut at det er "mange" som synes det vi holder på med i oppgavene er for vanskelig i forhold til det vi lærer ut ifra boka og i timene. Det er mange som synes du går litt fort frem. Jeg vil ønske for min del og for andre som har det samme problemet som meg, at du slakker ned litt til vi skjønner konseptet ved å programmere på forskjellige nivå. Kanskje dette kan gjøres ved å forklare litt om hver enkelt del av programmeringsspråket. Forenkle oppgavene hadde også vert lurt. En annen ide ville ha vert å gå igjennom boka, lese høyt og la oss lese høyt fra boka i klassen, for så å gå og programmere på lab'en etterpå. Noen av oss liker jo selvfølgelig den måten det er lagt opp på i dag, men jeg henviser virkelig til de ordene fra elevene dine til meg som tilsier at ting og tang går litt fort i svingene. Dette er ikke for å rakke ned på eller få noen til å føle seg dum eller for smart. Jeg sier det bare fordi jeg er glad i mine medelever, og ønsker dem den beste studietiden de kan få. Jeg kan ikke være en talsmann for de andre, men takk for at du forstår,
Til dette spurte jeg ibe150:
Jeg videresender en problembeskrivelse jeg fikk i posten fra en av ibe150-deltakerne og vil gjerne vite hva andre mener - slik at jeg kan finne ut hvor stor del av klassen dette gjelder (omfanget av problemet - hva betyr "mange"?).
Svar #1:
Jeg er enig i at det går litt for fort i svingene. Føler at jeg ikke får med meg alt jeg egentlig burde få med meg. Men ideen om at vi leser høyt ifra boka og går i lab etterpå hørest ut som en fin løsning, siden vi da får lært alt trinn for trinn.
Svar #2:
Jeg har ikke snakket med noen om dette, men jeg kan likevel si meg delvis enig i problembeskrivelsen. Jeg synes at fristen for obligene har vært en uke for tidlig. Jeg må ha hatt hjelp til å skrive kodene uten at jeg forstår godt nok hvorfor kodene skrives slik de skrives. Alternativet har vært å levere etter fristen, noe som medfører at jeg kommer i "bakleksa". Et godt eksempel er innleveringen til i morgen. Her må en ta i bruk både Array og Structure på en gang, uten at denne delen av pensum har fått synke skikkelig inn. Jeg tror at denne innleveringen burdfe hatt frist til fredag 28 september. Går det an å utsette rekkene av obliger en uke? Om progresjonen i forelesningene er for rask er litt vanskelig å svare på. Det er viktig at pensum er blitt gjennomgått minst 3-4 uker før eksamen, slik at en får anledning til å repetere og gjennomgå de deler av pensum en ikke har fått med seg. Etter 5 uker har vi kommet halveis i boken. Det betyr vel at pensum er gjennomgått i begynnelsen av november? Da har vi en måned igjen til eksamen, og såpass god tid bør vi nok ha til å repetere og gjennomgå de deler av pensum som en har problemer med.
Svar #3:
Sånn jeg oppfattet dette kurset er at det krever ganske mye selvstudie. Jeg liker å "ligge et skritt forran" det som blir gjennomgått i timene og derfor gjør jeg en del hjemme. Jeg setter av noen timer hver dag for å prøve og feile på nye ting. For meg personlig er det ikke tempoet noe problem, men det forutsetter at jeg gjør en del ekstra hjemmearbeid.
Svar #4:
Jeg må innrømme at jeg er ganske enig med det her. Jeg syns at programmering er kjempe spennende men isteden for å lære mer om det gjør jeg øvingsrelaterte ting for å rekke å levere alt i tide. Jeg vil gjerne havne på et nivå der jeg vet svaret ut fra å se på oppgaven isteden for å prøve meg fram, noe som tar veldig mye tid.

Fredag 21/9: Gruppearbeid med tabeller

Frist med oblig 4 utsettes en uke. Vi koste oss med oppgavene bak i kap. 7.1.: Nr. 1 (s. 316) belyste initialisering, redimensjonering og preservering av tabeller! I grupper ble der laget prognoser for rett svar til oppgave nr. 1-12 (s. 317-19), samt funnet feil i nr. 13-14 (s. 319-20), herunder syntaksfeil, runtimefeil og problemer med typeblanding og manglende initialisering. Endel oppgaver fant vi fasit til.

torsdag 20. september 2007

Forelesningsfri i Oktober

Torsdag 4/10 avlyses forelesningen (grunnet seminar). Neste uke deretter (8/10, 11/10 og 12/10) blir det heller ikke forelesning (ferieavvikling). Det blir likevel oblig for innlevering, fredager i begge disse ukene.

Torsdag 20/9: Godkjenning av brukere

Vi fortsetter fra mandagens problemer. Brukerne er derfor lest inn og ligger som "Bruker"-strukturer i array "brukere", og "antBrukere" er korrekt opptelt. Vi tok i dag HIPOens "Sjekk navn og passord". Det som er nytt av i dag ble:
Dim innlogget as Boolean = False

Sub OK_click () Handles OK.click
   If godkjent (txtNavn.Text, txtPassord.Text) Then
      innlogget = True
      lblMelding.Text = "Godkjent - du er innlogget!"
   Else
      lblMelding.Text = "Ikke godkjent - du er ikke innlogget!"
   End If
End Sub

Function godkjent (n, p) As Boolean
   Dim i as Integer = 0
   Do While brukere(i).navn <> n And i < antBrukere 
      i++
   Loop
   If i < antBrukere Then
      If brukere(i).passord = p Then
         Return True
      End If
   End If
   Return False
End Function

tirsdag 18. september 2007

Forelesningene flyttes EN time

Fra nu og ut semesteret vil forelesningene starte en time senere, altså 0915-1100. Det blir rom B135 (mandag), rom A202 (mandag og torsdag) og A285 (fredag).

mandag 17. september 2007

Kodekopiering

Kode kan kopieres meget enkelt. En gir da en referanser til hvor en har hentet koden (les hva skolen sier om "plagiering").

Mandag 17/9: Tabell og datastruktur

Med kap. 2's hierarisk input-processing-output (HIPO) lagde dere i grupper:
  • Reisevelger
    • Oppstart
      • Les inn brukere
    • Innlogging
      • Les inn navn og passord
      • Sjekk navn og passord
      • Gi svar
    • Velg reise
      • Les inn reisemål og priser
      • Ta imot valgt reisemål
      • Vis pris
Etter pausen laget vi et design for "Reisevelger:Oppstart:Less inn brukere". Først måtte datagrunnlaget designes (forslaget om database ble forkastet, det kommer senere!). Vi antar en tekstfil med en bruker per linje - hver linje har brukerens navn (pos 0-19), passord (20-39) og max. antall forsøk (resten). Logikken ble (nå, når datagrunnlaget er bestemt) uttrykt i et flytkart (kap. 2) med a) åpn fil, b) er det mer igjen så les neste bruker og husk denne, evt. c) hvis ingen flere, steng filen. Derpå brukte vi kap. 6's gjentakelser (med adaptive Do, for vi vet jo ikke hvor mange brukere som ligger i filen!) og fikk kap. 2's pseudokode:
f = åpne opp fil
Do While not f.endofstream()
 s = f.readline()
 b = lagbruker(s)
 huskbruker(b)
Loop
og brukte kap. 7's "Structure" til å lage Bruker og "Array" til å lage tabell av brukere.
Structure Bruker
  Dim navn as String
  Dim passord as String
  Dim maxAntallForsok as Integer
End Structure

Dim brukere(99) as Bruker
Dim antBrukere as Integer=0

Function lagBruker (ByVal s as String) As Bruker
Dim ny as Bruker
  ny.navn = s.substring (0,20).trim()
  ny.passord = s.substring (20,20).trim()
  ny.maxAntallForsok = CInt (s.substring(40).trim() )
 Return ny
End Function

Sub huskBruker (ByVal b as Bruker)
  brukere(antBrukere) = b
  antBrukere++
End Sub
Ingen kode ble skrevet inn (i VS). Det er plass til 100 brukere i tabellen, så prosessen vil krasje (runtime-feil) idet den 101. forsøkes innlagt.

fredag 14. september 2007

Leting etter valuta

Et tips til de som vil lage mer adaptive valutafinnere. Lag en stykk leter globalt (da det tar noe tid å lage et slikt objekt):
    Dim valutaMoenster As String = "^(?<valutakode>\w{3})\s+(?<kurs>\d*,?\d*)"
    Dim valutaLeter As Regex = New Regex(valutaMoenster)
    Dim treff As Match
Bruk leteren hver gang du er i tvil:
  Do While Not fil.EndOfStream()
      Dim s As String = fil.ReadLine()
      treff = valutaLeter.Match(s.Trim()) ' fjerner innledende blanke
      If treff.Success Then
          s = treff.Result("${valutakode} ${kurs}")
          cboValutakursMeny.Items.Add(s)
      End If
  Loop
Mønsteret består av:
  • "^": (ett tegn) markerer strengens start
  • "(?<valutakode>\w{3})": tre alfanumeriske (navngitt "valutakode")
  • "\s+": minst en blank
  • "(?<kurs>\d*,?\d*)": et desimaltall (navngitt "kurs"), som i "0,33", ",79" eller "3,88".
      "\d*": null eller flere siffer
    • ",?": ingen eller ett komma
    • "\d*": null eller flere siffer
Det blir ingen suksess med valutakurser som "EUR 4.2" (ikke komma), eller bare "EUR " (intet desimaltall).

Fredag 14/9: Valuta A til Z

Kap 2 omhandler metodikk. I dag laget vi analyse og design for oblig 3, del 3 (faktura) og del 4 (valuta). Valuta (del 4) mer spesifikt: I. Analyse: 1) kursene leses inn, slik at 2) de kan vises frem til bruker. Deretter kan 3) bruker velge en av disse kurs og 4) et beløp, fulgt av 5) output: Omregnet (beløp/valutakurs). II. UI-Design: UI har et INN-område (beløp, valutakursmeny og OK-knapp), samt et UT-område med omregnet beløp vist. III. Algoritmisk design (pseudokode, litt VB, litt "snakk"): To viktige hendelser: OK.click (bruker vil ha omregning) og Form.load (kursene skal leses inn).
  • OK.click() beregner omregnetBelop = hentbelop() * hentkursvalgt() og legger dette i UT-området.
  • hentbelop() returnerer et tall (Double) ved: Return Cdbl(innbelop.text).
  • hentkursvalgt() returnerer en double ved: Return Cdbl(valutaer.text.substring(4)).
  • Form.load() leser inn valutakursene. Filen åpnes, fulgt av en Do While Not fil.endofstream(): valutaer.items.add(fil.readline()) Loop.
Dette fungerte fint (laget valutafilen med notepad). IV. Koden ble:
Imports System.io

Public Class Form1

Private Sub btnOK_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles btnOK.Click
   Dim B As Double = hentBelop()
   Dim K As Double = hentkursvalgt()
   Dim O As Double = B / K
   lblUtbelop.Text = CStr(O)
End Sub
Function hentBelop() As Double
   Dim s As String = txtBelop.Text
   Dim t As Double = CDbl(s)
   Return t
End Function
Function hentkursvalgt() As Double
   Dim s As String = cboValutakursMeny.Text
   Dim s2 As String = s.Substring(4) ' satser ALT
   Dim t As Double = CDbl(s2)
   Return t
End Function

Private Sub Form1_Load(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles MyBase.Load
   Dim filnavn As String = "m:\valutaer.txt"
   Dim fil As streamreader = file.opentext(filnavn)
   Do While Not fil.EndOfStream()
       Dim s As String = fil.ReadLine()
       cboValutakursMeny.Items.Add(s)
   Loop
   fil.Close()
End Sub
End Class
Vi foretok lite V. testing, og antar at endel feil kan skje (brukerfeil i input, filens plassering). Endelig skinner solen! Men: Vil dette under virke? Hva er eventuelt problematisk?

Public Class Form1
    Private Sub btnOK_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles btnOK.Click
        lblUtbelop.Text = CStr(
              CDbl(txtBelop.Text) /
              CDbl(cboValutakursMeny.Text.substring(4)))
    End Sub
    Private Sub Form1_Load(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles MyBase.Load
        Dim fil As streamreader = System.IO.file.opentext("m:\valutaer.txt")
        Do While Not fil.EndOfStream()
            cboValutakursMeny.Items.Add(fil.readLine())
        Loop
        fil.Close()
    End Sub
End Class

torsdag 13. september 2007

Torsdag 13/9: Gjenta lekser

Do lar oss gjenta noe vi ikke vet hvor ofte skal gjentas, mens For er bra hvis vi kjenner antallet (kap. 6). På boolsk vil det lettleselige EndOfStream() si om vi er ferdig (der boka foretrekker 80-tallets Peek). Evig gjentakelse fikk vi ikke med "For i = 11 to 5 Step 1" men med "Do While 0 < 5". Min temperaturhenter ble adaptiv (tilpasningsdyktig) med Do, men feiler (runtime "krasj") hvis temperaturene ikke fins.
 Sub Private hentTemperaturer()
   Dim readerTemp As StreamReader = File.OpenText("c:\temperaturer.txt")
   Do While Not readerTemp.endOfStream()
     strInn = readerTemp.readline() ' henter neste
   Loop
   readerTemp.close()
 End Sub

mandag 10. september 2007

Oblig 4

OBS: Frist utsatt en uke til 28/9. Oppgave 1: Strøm betales flere ganger i året. Lag et program som beregner strømkostnad (siden siste betaling), basert på prisliste (leses fra fil), samt forbruk (kWh) basert på forrige og nyeste måleravlesning (oppgis av bruker, som også må oppgi type abonnement, "flytende" eller "fastpris"). Bruker skal betale for nettleie og forbruk. Nettleien (for alle) er V0 øre/kWh og F0 kr/år. Forbruket koster V1 øre/kwH og F1 kr/år (for "fastpris") eller V2 øre/kwH og F2 kr/år (for "flytende"). Antallet regninger per år angis i første linje på fil, og fastpris fordeles på disse regningene.

Oppgave 2: Lag et program som a) krever brukernavn og passord (avvises etter et max antall forsøk), og hvis OK, b) lar brukeren velge reisemål og se prisen. Reisemål og pris ligger på tekstfil A (leses bare hvis innlogging gikk greit). Godkjente brukere (med passord og max. antall forsøk) leses fra fil B ved oppstart. Da listen over reisemål og -pris endres stadig må listen holdes (automagisk) oppdatert. Frekvensen ligger som første linje i fil A.

Krav til svaret: Sterk typesjekking, bruk av løkke, forståelige variabelnavn og korrekte prefiks, minst en subprosedyre og en funksjon, korrekt utregning. Frist: Fredag 2128/9.

Mandag 10/9: Lesing fra fil

Temperaturer lages (med Notepad). Oppdaterte temperaturer trengs fra tre "steder" i koden, så filen (med temperaturene) leses fra ny prosedyre HentTemperaturer() som jeg lager SELV.
  Imports System.IO
  ...
  Sub Private hentTemperaturer()
    Dim readerTemp As StreamReader = File.OpenText("c:\temperaturer.txt")
      ' filen har tre linjer
    Dim strInn as String
    strInn = readerTemp.readline() ' henter linje 1 "Molde 8"
    strInn = readerTemp.readline() ' henter linje 2 "Tingvoll 12"
    strInn = readerTemp.readline() ' henter linje 3 "Vigra 9"
    strInn = readerTemp.readline() ' gir "Nothing" 
    readerTemp.close()
  End Sub
OpenText() av ukjent fil gir RUNTIME-feil (programmereren kan ikke oppdage dette!). ReadLine() gir "Nothing" (ikke runtimefeil) hvis det ikke er mer å lese. Prosedyren kalles ved hendelsene form.Load (programmet starter), button1.click (bruker vil ha oppdaterte temperaturer) og timer1.tick (som vi satte til hvert 1000de millisekund).

Samtidighetsproblematikk: Hvis mitt program har filen åpen (for lesing) bør ikke andre (notepad) åpne den for skriving. Likens: Hvis andre har åpnet filen (for skriving), bør ikke mitt program få åpne filen (for lesing). Slik blokkering gir feilmelding, men er vanlig, for å sikre at leserne ikke er forvirret hva angår det EGENTLIGE innholdet i filen. For å redusere sjansen for blokkering må lesere og skrivere av delte filer åpne bare hvis absolutt nødvendig (en MÅ ha siste versjon), samt minimalisere tiden filen holdes åpen. Merk: Det er greit at flere lesere har samme fil åpen samtidig!

fredag 7. september 2007

Hente temperatur fra web

En liten demo på streng behandling av data fra web. Tallet som returneres blir ofte lavt.
  Imports System, System.Net, System.Text.RegularExpressions
    ...
    Function hentTempFraWeb() As Integer
        Dim url As String =  "http://www.yr.no/place/Norway/M%C3%B8re_og_Romsdal/Molde/Molde/"
        'http://met.no/more_og_romsdal/molde.html?steder"
        Dim req As WebRequest = WebRequest.Create(url)
        Dim resp As WebResponse = req.GetResponse()

        Dim inndata As IO.StreamReader = New IO.StreamReader(resp.GetResponseStream())
        Dim innString = inndata.ReadToEnd()

        Dim monster As String = "\d+.deg;"
        Dim minLeter As Regex = New Regex(monster)
        Dim treff As Match
        treff = minLeter.Match(innString)
        Dim funn As String = treff.ToString().Substring(0, 2)
        Return CInt(funn)
    End Function

Klassehierarki

Klassebibliotek i .NET er hierarkisk, med ei rot og forgreninger (som et tre, s. 582, pensumboka. Klassene like under "System" blir automatisk importert; alt annet importeres eksplisitt (som i "Imports System.Text.RegularExpressions"). Klassen Object er erkeklassen (rota i treet). Det har metodene equals(), finalize(), gethashcode() og tostring(), omtrent som i Java. Under Object kommer:
  • System (automatisk importert).
    • Integer
      • maxValue, minValue
    • Double
    • String
      • indexOf(), subString(),
    • Math
      • sqrt(), round(), ...
    • IO
      • File (s. 108 og kap. 8)
        • OpenText()
        • CreateText(), AppendText(),
      • StreamReader (s. 108)
      • StreamWriter (s. 412)
    • Text
      • RegularExpressions (se forel. 7/9, ikke i boka)
        • RegEx -- for å lete etter funn
        • Match -- for å lagre funn
  • Microsoft -- ikke studert enda
  • OppgaveN -- vår egen havner ofte her
Hierarkiet vises godt med "Object browser" som kan startes fra Alt/View.

torsdag 6. september 2007

Fredag 7/9: Leting etter tall

Data kommer ofte som tekst (String), hvorfra en henter ut (filtrerer) etter behov. En leter da etter mønster (pattern) i teksten, f.eks. en akseptabel temperatur. Vi kan bruke IndexOf() og SubString() som i boken, men det kraftigste og mest brukte redskap er regulære uttrykk (regular expressions), noe boken ikke tar opp. For heltall er letemønstret "\d+" noe som tilsvarer "[0123456789]+" eller, noe enklere skrevet, "[0-9]+". Plusstegnet er en KVANTIFIKATOR som angir at en vil ha minst ett av tegnene foran. Kodeeksempel:
  Imports System.Text.RegularExpressions 

  Function finn_IkkeNegativtHeltall (ByVal strInn As String) As Integer
    Dim strMoenster as String = "\d+"
    Dim tallLeter as RegEx = new RegEx (strMoenster)
    Dim treff as Match
    Dim strTall as String

    treff = tallLeter.Match( strInn )
    strTall = treff.ToString ()
    If IsNumeric ( strTall ) Then
      Return CInt ( strTall )
    Else
      Return -1
    End If
  End Function
For å hente alle tallene brukes en løkke (noe vi ikke har lært om enda) som går gjennom en treffliste, som under. "Ut" viser tallene atskilt med blank:
  Dim alletreff as MatchCollection
  alletreff = tallLeter.Matches ( strInn )
  For Each treff In alletreff
    Ut.Text = Ut.Text & treff.ToString() & " "
  Next
For å tillate negative tall setter en inn "-?" foran: "?" betyr at en vil ha null eller ett av foregående tegn ("-"). Hele mønsteret blir da "-?\d+". Hvis en bare vil akseptere heltall etterfulgt av "c", som i "-13c" blir mønsteret "-?\d+c". Tre kvantifikatorer er: "+" (1 eller flere), "?" (ingen eller 1) og "*" (0 eller flere).

Torsdag 6/9: Validering av inndata

Konstant sjekking av temperatur (korrekt og sannsynlig) er mulig som i koden under (finn en syntaksfeil!):
  Option Strict On
  Dim minTemp As Integer = -80, maxTemp As integer = 50

  Sub validerTemp (...) Handles txtboxTemp.TextChanged
    Dim innString as String = txtboxTemp.Text 
    Dim innTemp = 0  
    If IsNumeric ( innString ) Then
      innTemp = CInt ( innString ) ' sikring mot runtimefeil
      If IsTemp ( innTemp ) Then    
        temp = innTemp             ' sikring mot tulletemperatur
      Else
        MsgBox ( "Saerlig! " )
      End If
    Else
      MsgBox ( "Bare siffer godtas!" )
    End If
  End Sub

  Function IsTemp (ByVal temp as Integer) As Boolean
    Return temp >= minTemp And temp <= maxTemp
  End Function
CInt(x) gir feil ved runtime (under kjøring) hvis det forekommer annet enn tall og komma i "x" -- og: CInt(" 3 21 , 65 7") gir selvsagt "322". IsNumeric() forkaster minustegn, og fra salen ble det anbefalt at validering avventes inntil knapp var tastet!

mandag 3. september 2007

Mandag 3/9: Turdilemma

"Skal vi på tur" var eksempel, med beskrivelse (ord), analyse (flytskjema), design (UI) og kode (VB) - se kap. 2. Det ble et beslutningsstøtteverktøy med overtidskode:
  Private Sub btnBeregn_Click () Handles btnBeregn.Click
    v = finnutVaeret()
    krav = finnBrukersKrav()
    If ( (v.temp < krav.temp ) And
         (v.vind < krav.vind ) And
         (v.sol = krav.sol) And
         (v.nedbor = krav.nedbor) ) Then
      lblSvar.Text = "Ja!"
    Else
      lblSvar.Text = "Nei!"
    End If
  End Sub
Her er krav til sol og nedbør boolsk i seg selv, mens krav til temperatur og vind er maksimumskrav. "And" angir at alt må stemme (de fire delkrav evaluert til True) for at turen skal anbefales!