PROGRAMMERING I MAPLE Trygve Eftestøl Rev. 15.07.200, Tom Ryen BID10 Datateknikk, høsten 200 Høgskolen i Stavanger, Teknisk- og naturvitenskaplig fakultet Innledning Hensikten med dette dokumentet er først og fremst å gi en kortfattet innføring i programmering med Maple8 som skal gi studenten et grunnlag for å kunne jobbe på datamaskinen med begreper som omhandles i programvaredelen av pensum. Algoritmer I læreboken (av Brookshear) benyttes et pseudokodespråk som et verktøy en kan bruke til å beskrive algoritmer. De mest grunnleggende algoritmestrukturene som blir behandlet er: Tilordning av verdier til variabler (herunder også datatyper og indeksering). Prosedyrer med lokale og globale variabler. Betingelsestyring av aktiviteter med kontrollstrukturen if. Betingelsestyrt gjentakelse av aktiviteter med kontrollstrukturen while. I det følgende gis en nærmere beskrivelse av hvordan disse strukturene arter seg i Maple. Tilordning av verdier til variabler I læreboken står det at en ofte ønsker å referere til verdier ved deskriptive navn. I læreboken uttrykkes dette navn <- uttrykk hvor navn er det deskriptive navnet og uttrykk beskriver verdien som skal assosieres med navnet. I Maple vil en uttrykke dette på følgende måte: > navn:=uttrykk; Legg merke til bruken av := Noen eksempler: navn := uttrykk > x:=100;
y:=2; x := 100 y := 2 Noen datatyper og indeksering Maple skiller mellom ulike måter å organisere data på. Vi skal kort gå inn på de mest sentrale av disse. I de eksemplene vi hittil har sett på har vi operert på et enkelt tall. Når en skal utvikle mer avanserte algoritmer har en ofte bruk for å håndtere mer kompliserte data-samlinger. Vi skal se nærmere på noen av de grunnleggende Maple-strukturene vi får mest bruk for. En liste kan lages ved å sette et antall kommaseparerte objekter i klammeparanteser. Et objekt i listen, x, kan aksesseres ut fra dets posisjon j i listen som x[j]. I eksemplet nedenfor lager vi en liste og aksesserer det. elementet i listen. > data_list:=[1,,,5]; data_list[]; data_list := [ 15,,, ] En streng kan lages ved å sette symboler sammen innenfor " ". > "Dette er en streng 1 2 "; "Dette er en streng 1 2 " Det kanvære nyttig å sette sammen to strenger med kommandoen cat. > streng1:="udeouh "; streng2:="ijhp-ø"; cat(streng1,streng2); streng1 := "udeouh " streng2 := "ijhp-ø" "udeouh ijhp-ø" En kan også lage en liste av strenger > string_list:=['ola','lise','per']; string_list := [ Ola, Lise, Per ] Ved indeksering aksesserer vi verdier ut fra posisjonen i listen ved hjelp av indeksvariabler. Vi kan la i være indeksvariabel. Ved å la i variere, har vi en metode som lar oss lese/skrive til posisjoner i listen på en fleksibel måte. Istedet for å lese verdien i posisjon med direkte posisjonsangivelse, kan vi gjøre dette med bruk av indeksvariabelen i på følgende måte: > i:=; data_list[i]; i := Tilsvarende kan vi indeksere strenglisten vår: > string_list[i]; Per Dette er svært nyttig når vi bruker while-strukturer.
Prosedyrer Noen ganger trenger man samme programkoden flere ganger i arbeidet med å løse ulike problemstillinger. Da kan det være nyttig å skrive en prosedyre som en kan kalle ved navn når en har bruk for et bestemt sett med programkode. I læreboken omtales dette som at prosedyren er et abstrakt verktøy som kan brukes i andre sammenhenger. Prosedyren gis et navn som en kan referere til seinere. I denne sammenhengen kan det være nyttig å tenke seg en nivådeling av arbeidsområdet. Øverste nivå (nivå 1) vil være arbeidsdokumentet. En kan gå inn i et lavere nivå (nivå 2) ved å kalle en prosedyre fra nivå 1. Mens en er inni denne prosedyren er en i nivå 2, og når prosedyren er ferdig utført vender en tilbake til nivå 1. En kan også tenke seg at en ny prosedyre kalles innenfra den første prosedyren slik at en går over i nivå. La oss opprette en enkel prosedyre som har som oppgave å oppgi en tilnærming av verdien et halvert tall. Vi ønsker å kalle prosedyren halver. Prosedyren skal kunne kalles fra et annet program seinere med variablen, x, som inngangsparameter og gi ut den tilnærmede verdien til x/2. I læreboken ville dette uttrykkes som procedure halver(x) skriv ut tilnærming av x/2; I maple uttrykkes dette som følger: > halver:=proc(x) evalf(x/2); halver := proc( x ) evalf( 1 / 2 x ) Nå er prosedyren definert. En kan da kalle prosedyren fra arbeidsdokumentet som i følgende eksempler. (Prosedyren kan også kalles innenifra andre prosedyrer). > x:=2; y:=halver(2.5); halver(0.5); x := 2 y := 1.250000000 0.2670000000 Dersom du ønsker å studere innholdet i en prosedyre kan dette gjøres ved hjelp av kommandoen eval. > eval(halver); proc( x ) evalf( 1 / 2 x ) Parametere En bruker parametere for å sende variabelverdier inn og ut av prosedyrer. Her er et eksempel hvor verdien til variabelen X sendes inn i prosedyren doble, via parameteren x. Resultatet sendes ut av prosedyren til variabelen Y via parameteren y.
> doble:=proc(x,y) y:=2*x; X:=2; Y:='Y'; doble(x,y): Y; doble := proc( x, y ) y := 2 x X := 2 Y:= Y Legg merke til tilordningen Y:='Y'. Dette er fordi utgangsverdien bare kan tilordnes et navn. Hvis en prøver å sende inn en verdi, som vist i eksemplet under, vil man få feil. > X:=2; Y:=; doble(x,y): Y; X := 2 Y := Error, (in doble) illegal use of a formal parameter En kan ha flere parametre. I eksemplet under brukes to utgangsparametere, y og z. > doble2:=proc(x,y,z) y:=2*x; z:=2*y; X:=2; Y:='Y'; Z:='Z'; doble(x,y,z): Y; Z; doble2 := proc( x, y, z ) y := 2 x ; z := 2 y X := 2 Y:= Y Z:= Z Z Lokale og globale variabler
Som en regel er variabler deklarert innenfor en prosedyre lokale, hvilket betyr at de kun kan refereres til inni prosedyren. Noen ganger ønsker en at en variabel skal kunne refereres til fra alle nivåer. Disse variablene er globale. Eksempelvis kan vi se på to nesten identiske prosedyrer, g og h. g bruker b som lokal variabel, mens h bruker b som global variabel. Vi tilordner først en verdi til b, og så definerer vi prosedyrene. > b:=2; g:=proc() local b; b:=10299/102; evalf(b/2); h:=proc() global b; b:=10299/102; evalf(b/2); b; b := 2 g := proc() local b ; b := 1 / 110 ; evalf( 1 / 2 b ) h := proc() global b ; b := 1 / 110 ; evalf ( b / 2) 2 Deklareringen av prosedyrene har ingen effekt på variablen b, den beholder verdien 2. Hvis vi utfører prosedyren g, har det heller ingen effekt på verdien til b. > g(); b; 1.55569199 2 Utførelse av h derimot, vil påvirke verdien til b, ettersom b i denne prosedyren er deklarert som en global variabel. > h(); b; 1.55569199 1 110 Betingelsesstyring av aktiviteter med kontrollstrukturen if Den ene av de to viktige kontrollstrukturene er if. I beskrivelse av algoritmer har en ofte behov for å kunne velge mellom en av to ulike aktiviteter avhengig av om en gitt betingelse er sann eller usann. I læreboken uttrykkes dette generelt som
if (betingelse) then (aktivitet1) else (aktivitet2) Dersom betingelsen er sann så utføres aktivitet1, ellers utføres aktivitet2. I Maple uttrykkes dette > if betingelse then aktivitet1; else aktivitet2; end if; Et eksempel kan være at en ønsker å lage en prosedyre, ABS, som beregner absoluttverdien x til tallet x. ( x =x når x er positivt og x =-x ellers.) > ABS:=proc(x) if x<0 then -x; else x; end if; ABS := proc( x) if x < 0 then x else x end if > ABS();ABS(-); Betingelsesstyrt aktivitetsgjentakelse med kontrollstrukturen while Den andre av de to viktige kontrollstrukturene er while. Denne gir anledning til å gjenta utførelsen av en aktivitet så lenge en gitt betingelse er oppfylt. Sammen med betingelsestyring av aktiviteter, gir dette mulighet til å beskrive algoritmer på en kraftfull måte. I læreboken uttrykkes dette generelt som while (betingelse) do (aktivitet) Så lenge betingelsen er sann utfør aktivitet. Returner og kontroller betingelsen igjen. Når betingelsen viser seg å være falsk, avsluttes sløyfen og programutførelsen fortsetter med første instruksjon etter while-strukturen. I maple uttrykkes dette > while betingelse do aktivitet; end do; Et eksempel kan være at en ønsker å lage en prosedyre, dividermed2, som dividerer et heltall n med 2 så mange ganger som mulig. Kommandoene iquo og irem beregner henholdsvis kvotient og rest ved hjelp av heltallsdivisjon. > dividermed2:=proc(n::posint) local q; q:=n; while irem(q,2)=0 do q:=iquo(q,2); end do; q;
dividermed2 := proc( n:: posint) local q; q:= n; while irem ( q, 2) = 0 do q := iquo ( q, 2) end do; q > dividermed2(2); dividermed2(); 1 > Som vi ser er q en lokal variabel som endrer seg og inngår i betingelsen som testes. Dette er vesentlig ved while-strukturens kontrolldel som består av komponentene Initialisering: q settes lik heltallet som skal deles med 2. Test: Det testes om q er delelig med 2. Modifisering: q endres til neste kvotient som skal forsøkes deles med 2. Modifiseringen besørger at avslutningsbetingelsen til slutt inntreffer. Henvisninger til nyttig informasjon Et startkurs Under hjemmesidene til Maple, kan en finne kurs og informasjon som omhandler programmeringi Maple. Dette kan lastes ned gratis fra http://www.mapleapps.com/powertools/programming/programming.shtml