Obligatorisk uppgift 5: Symbolisk kalkylator

Relevanta dokument
Obligatorisk uppgift 5: Symbolisk kalkylator

Obligatorisk uppgift 5

Obligatorisk uppgift: Symbolisk kalkylator

List.java. List.java. Printed by Tom Smedsaas

Obligatorisk uppgift: Numerisk kalkylator

public boolean containskey(string key) { return search(key, head)!= null; }

Observera. Tentamen Programmeringsteknik II Skrivtid:

Lägg uppgifterna i ordning. Skriv uppgiftsnummer och din kod överst i högra hörnet på alla papper.

Parsing med Recursive Descent, Avbildningsklasser. Syntaxdiagram. Syntaxdiagram och kodning expression. Betrakta följande uttryck

List.java. List.java. Printed by Tom Smedsaas

Det är principer och idéer som är viktiga. Skriv så att du övertygar rättaren om att du har förstått dessa även om detaljer kan vara felaktiga.

Obligatorisk uppgift: Numerisk kalkylator

Obligatorisk uppgift: Numerisk kalkylator

Det är principer och idéer som är viktiga. Skriv så att du övertygar rättaren att du har förstått dessa även om detaljer kan vara felaktiga.

TDDC77 Objektorienterad Programmering

Tentamen Programmeringsteknik II Skrivtid: Hjälpmedel: Java-bok (vilken som helst) Skriv läsligt! Använd inte rödpenna!

Inlämningsuppgift MiniPlotter

Lägg uppgifterna i ordning. Skriv uppgiftsnummer och din anmälningskod överst i högra hörnet på alla papper.

Tentamen Programmeringsteknik II för STS Skrivtid: Inga hjälpmedel.

Klassdeklaration. Metoddeklaration. Parameteröverföring

Klassen BST som definierar binära sökträd med tal som nycklar och enda data. Varje nyckel är unik dvs förekommer endast en

F3: Recursive descent, tokenisering, avbildningar och undantag. Carl Nettelblad

Tentamen Programmeringsteknik II Skrivtid: Hjälpmedel: Java-bok (vilken som helst) Skriv läsligt! Använd inte rödpenna!

Tentamen Programmeringsteknik II och NV2 (alla varianter) Skriv bara på framsidan av varje papper.

Konstruktion av klasser med klasser

Programmering A. Johan Eliasson

Lägg uppgifterna i ordning. Skriv uppgiftsnummer och din kod överst i högra hörnet på alla papper.

Tentamen Programmeringsteknik 2 och MN Skrivtid: Inga hjälpmedel.

Lägg uppgifterna i ordning. Skriv uppgiftsnummer och din kod överst i högra hörnet på alla papper.

Föreläsning 3: Booleans, if, switch

kl Tentaupplägg

Kompilering och exekvering. Föreläsning 1 Objektorienterad programmering DD1332. En kompilerbar och körbar java-kod. Kompilering och exekvering

Grafik, grafiska användargränssnitt och rörliga bilder

Objektorienterad programmering i Java I. Uppgifter: 2 Beräknad tid: 5-8 timmar (OBS! Endast ett labbtillfälle) Att läsa: kapitel 5 6

Klasshierarkier - repetition

Föreläsning 8 - del 2: Objektorienterad programmering - avancerat

F2 Datatyper och variabler. ID1004 Objektorienterad programmering Fredrik Kilander

Föreläsning 5-6 Innehåll. Exempel på program med objekt. Exempel: kvadratobjekt. Objekt. Skapa och använda objekt Skriva egna klasser

Klasshierarkier. Klasser kan byggas på redan definierade klasser

Föreläsning 5-6 Innehåll

Anmälningskod: Lägg uppgifterna i ordning. Skriv uppgiftsnummer (gäller B-delen) och din kod överst i högra hörnet på alla papper

Lägg uppgifterna i ordning. Skriv uppgiftsnummer och din anmälningskod överst i högra hörnet på alla papper.

Introduktion till programmering SMD180. Föreläsning 2: Variabler, uttryck och satser

LÖSNINGSFÖRSLAG Programmeringsteknik För Ing. - Java, 5p

EDAA20 Programmering och databaser. Mål komprimerat se kursplanen för detaljer. Checklista. Föreläsning 1-2 Innehåll. Programmering.

Lite om felhantering och Exceptions Mer om variabler och parametrar Fält (eng array) och klassen ArrayList.

Lösningar till Tentamen i Programmeringsteknik II och MN

Arv. Fundamental objekt-orienterad teknik. arv i Java modifieraren protected Lägga till och modifiera metoder med hjälp av arv Klass hierarkier

Programmering med Java. Grunderna. Programspråket Java. Programmering med Java. Källkodsexempel. Java API-exempel In- och utmatning.

OMTENTAMEN I PROGRAMSPRÅK -- DVG C kl. 08:15-13: 15

Datatyper och kontrollstrukturer. Skansholm: Kapitel 2) De åtta primitiva typerna. Typ Innehåll Defaultvärde Storlek

Det finns en referensbok (Java) hos vakten som du får gå fram och läsa men inte ta tillbaka till bänken.

Objektorienterad Programmering (TDDC77)

UML. Klassdiagr. Abstraktion. Relationer. Överskugg. Överlagr. Aktivitetsdiagram Typomv. Typomv. Klassdiagr. Abstraktion. Relationer.

Grundkurs i programmering, 6 hp (725G61) Dugga 2 tillfälle 2

Command line argumenter. Objektorienterad Programmering (TDDC77) Vad blir resultatet? Nu då? Ahmed Rezine. Hösttermin 2016

Lägg uppgifterna i ordning. Skriv uppgiftsnummer och din kod överst i högra hörnet på alla papper.

F4. programmeringsteknik och Matlab

Parameteröverföring. Exempel. Exempel. Metodkropp

Föreläsning 7. Nyckelord I Java. Uttryck. Uttryck, Operatorer Och Kontrollflöden

Abstrakt klass. DD2385 Programutvecklingsteknik Några bilder till föreläsning 4 31/ Exempel: Implementation av Schackpjäser.

1 Datorn som miniräknare. 1.1 Räkneoperationer. 1.2 Variabler

EDAA20 Programmering och databaser. Mål komprimerat se kursplanen för detaljer. Om att lära sig programmera. Föreläsning 1-2 Innehåll.

Föreläsning 3-4 Innehåll

Användning av stack: evaluera uttryck i RPN

Uppgift: Algoritm för att beräkna kontrollsiffran i ett personnummer givet de 9 första siffrorna. Torrsimning av algoritm för personnummer

2I1049 Föreläsning 5. Objektorientering. Objektorientering. Klasserna ordnas i en hierarki som motsvarar deras inbördes ordning

Idag. Javas datatyper, arrayer, referenssemantik. Arv, polymorfi, typregler, typkonvertering. Tänker inte säga nåt om det som är likadant som i C.

Tentamen OOP

Tentamen Programmeringsteknik II Inledning. Anmälningskod:

Föreläsning 3-4 Innehåll. Diskutera. Metod. Programexempel med metod

TENTAMEN: Algoritmer och datastrukturer. Läs detta! Uppgifterna är inte avsiktligt ordnade efter svårighetsgrad.

Det finns en referensbok (Java) hos vakten som du får gå fram och läsa men inte ta tillbaka till bänken.

TENTAMEN I PROGRAMSPRÅK -- DVG C kl. 08:15-13:15

Föreläsning 14. Filhantering

Föreläsning 1 & 2 INTRODUKTION

TDDC77 Objektorienterad Programmering

Programstruktur och terminologi. Programmet producerar följande utskrift i terminalfönstret: Ett Javaprogram består av en eller flera klasser

DD2310. Javaprogrammering för Pythonprogrammerare. Johan Boye

Att skriva till och läsa från terminalfönstret

Hej Då, Karel! Programmering. Vårt första Javaprogram. hh.se/db2004. Java. Grundtyper, variabler och arrayer

Abstrakt klass. DD2385 Programutvecklingsteknik Några bilder till föreläsning 4 7/ Exempel: Implementation av Schackpjäser.

Anmälningskod: Lägg uppgifterna i ordning. Skriv uppgiftsnummer (gäller B-delen) och din kod överst i högra hörnet på alla papper

Föreläsning 9 Innehåll

E02 "The Review" Föreläsning 2, HT2013 Grunderna, repetition. Johan Leitet. Kurs: 1dv403 Webbteknik I

Föreläsning 3. Iteration while-satsen

Static vs Dynamic binding Override vs Overload. Objekt-orienterad programmering och design Alex Gerdes och Sólrún Halla Einarsdóttir, 2018

Tentamen i Programmering

Arv: Fordonsexempel. Arv. Arv: fordonsexempel (forts) Arv: Ett exempel. En klassdefinition class A extends B {... }

TDDC74 Programmering: Abstraktion och modellering Datortenta , kl 14-18

OOP Objekt-orienterad programmering

Föreläsning 2 sept 05 (Onsdag v 36). DD Chapter 2.

Tentamen ID1004 Objektorienterad programmering May 29, 2012

Dagens föreläsning. Repetition. Repetition - Programmering i C. Repetition - Vad C består av. Repetition Ett första C-program

Det finns en referensbok (Java) hos tentavakten som du får gå fram och läsa men inte ta tillbaka till bänken.

Classes och Interfaces, Objects och References, Initialization

Föreläsning 5&6 LOGISKA VARIABLER; IMPLEMENTERA KLASSER; MER ALGORITMER

Tentamen, EDAA10 Programmering i Java

Allmänt om Mathematica

Transkript:

Informationsteknologi Tobias Wrigstad IOOP HT10 Obligatorisk uppgift 5: Symbolisk kalkylator Moment: Objektorientering med klasshierarkier, arv och dynamisk bindning samt dynamiska strukturer, undantag, samlingar och recursive descent. Start: Tisdagen den den 7:e december. Slutlig redovisning: Senast fredagen den 17:e december. I mån av behov kan ett extra redovisningstillfälle läggas in mellan 21/12 eller 22/12. Uppgift Ni skall skriva ett program som läser in och beräknar uttryck. Programfunktion Först exemplifierar vi den rent numeriska aritmetiken: $ calc Welcome to the symbolic calculator!? 2*(5-2) Alla numeriska beräkningar i flyttalsaritmetik (double). 6.0? 1/(2+8) = a Spara värden i variabler. Tilldelningen går åt höger. Värdet av en tilldelning är det tilldelade värdet. 0.1? 2 = x = y Multipla tilldelningar 2.0? (x+y=z) - (z-1)*(1=x) Tilldelningar i uttryck. Evaluering från vänster till höger. 1.0? -sin(exp(a*a*10)) Elementära funktioner -0.8935409432921488? ans En fördefinierad variabel som alltid innehåller värdet av senast beräknade uttryck -0.8935409432921488? -ans+2 Variabeln ans kan användas i uttryck som andra variabler 2.8935409432921488? - - -x -1.0 1

? vars Kommando för att se vilka variabler som finns {ans=1.0, a=0.1, x=1.0, y=2.0, z=4.0? 3**5 ++ x Felhantering *** Syntax Error: Unexpected: *? foo(x+y) *** Syntax Error: Unexpected: (? 1/0 Vissa fel kan överlåtas åt Java för hantering Infinity? Symboliska operationer Som nämnts skall kalkylatorn kunna hantera uttryck symboliskt. Exempel: $ calc Welcome to the symbolic calculator? b Odefinierade variabler har sig själva som värde b? 1 = a 1.? a + b En beräkning resulterar i ett uttryck 1. + b? b + a = c Värden kan vara uttryck b + 1.? 2 = b Även om b tilldelas ett värde så påverkar detta 2. inte uttryck innehållande b som redan definierats.? c Evaluering görs endast en gång värdet evalueras inte! b + 1.? exp(2*x) = y exp(2.*x) 2

Ytterligare exempel Indata Värde Kommentar 3=x 3 Värdet av tilldelningen är 3. x+y 3 + y Om en symbol tilldelats ett värde så används värdet vid evalueringen. z+2=y z + 2 3=z 3 y z + 2 Symboler evalueras bara en gång (annars skulle värdet bli 5). y=f z + 2 Som sagt, endast en gång. f+z*2 z + 2 + 6 Symbolerna evalueras EN gång men... f+z*2 z + 8...skulle kanske kunna göra en bättre förenkling! Dock svårt! z + x = g 6 g får värdet 6 g 6...men man kanske ville ha värdet z + x! f z + 2 Definierat ovan. z 3 (f + z*z) z + 2 + 9 3

Syntaxdiagram Indata till programmet beståer av satser (statement) skrivna en per rad. Syntaxen definieras av nedanstående diagram. statement command command eol quit assignment vars assignment expression = identifier expression term + term factor */ unary (unärt minus) primary primary exp ( unary assignment ) log number sin identifier cos 4

Programdesign Intern representation av uttryck Programmet skall läsa uttrycken och bygga upp en internrepresentation som lämpar sig för evaluering. Ni skall använda en trädstruktur där operatorer och funktioner lagras i de interna noderna och konstanter och variabler i löven. Det matematisk uttrycket sin x + 5a 3(u + 1) = z = t = skall alltså reprenteras av vidstående träd. = z t (När uttrycket skrivs som indata till programmet måste multiplikationstecknet vara med) + * sin * 3 + x 5 a u 1 Gemensamt för alla noder är (bl.a.) att de skall kunna evalueras men evaluering gör olika beroende på vad det är för typ av nod (konstant, variabel, addition,... ). Eftersom noderna ska kunna vara av olika typer (operatorer, funktioner, variabler, konstanter,... ) är det lämpligt att implementera dem i en klasshierarki med en generell basklass som skulle kunna kallas SymbolicExpression. Av layout-skäl kan det dock vara bra att använda ett kortare namn som Sexpr eftersom detta namn kommer att vara oerhört frekvent i koden. Gör egna klasser för varje operation och funktion (Assignment, Addition, Subtraction, Sin,... ) samt en klass för variabler och en för konstanter. Det finns tre tydligt urskiljbara grupper av noder: de med två operander (binära operatorer), de med en en operand (funktioner, unärt minus) och de utan operander (konstanter, variabler). Det är inte bara antalet operander som är gemensamt för varje grupp utan även vissa metoder. Sålunda kan bl.a. tostring-metoderna skrivas på samma sätt t.ex. för alla binära operatorer. Således skall man samla binära operatorer under klassen Binary och unära operatorer (inklusive funktioner) under klassen Unary. Av symmetriskäl är det lämpligt att samla konstanter och variabler under klassen Atom även om det nog inte finns så mycket som kan utnyttjas gemensamt mellan dessa två grupper. Det leder till följande design (ytterligare metoder kommer behöva tillföras): 5

Sexpr String getname() double getvalue() int priority() boolean isconstant()... Command Atom Unary Binary String tostring() Sexpr argument String tostring() int priority() Sexpr left Sexpr right String tostring() Vars Quit Variable String ident String getname() Constant Sin Cos Exp Log Negation Addition Subtraction Multiplication Division Assignment double value String getname() double getvalue() boolean isconstant() String getname() String getname() int priority() Obs: Konstruktorer finns är inte angivna. Det är lämpligt att placera Sexpr och dess subklasser ett eget paket (symbolic). Basklassen Sexpr bör således ha följande utseende. package symbolic; import java.util.*; public class Sexpr{ public Sexpr() {... 6

Ett exempel på en klass på mellannivån i hierarkin är Unary: package symbolic; public class Unary extends Sexpr { Sexpr argument; public Unary(Sexpr a){ argument = a; public String tostring() {... public priority() {... Hur bygger man internstrukturen? Uttryck byggs av den parser för recursive descent som presenterats på en föreläsning. Den modifieras så att varje metod som förut returnerade ett tal (en double) nu returnerar en referens till en skapad nod. Exempel: Parsermetoden expression får följande uteseende (med en StreamTokenizer st): public Sexpr expression() { Sexpr sum = term(); while (st.ttype== + st.ttype== - ) { int operation = st.ttype; st.nexttoken(); if (operation== + ) sum = new Addition(sum, term()); else sum = new Subtraction(sum, term()); return sum; Där man tidigare utförde en addition eller en subtraktion skapar man nu en additionsnod respektive en subtraktionsnod. Hur gör programmet för att skriva ut uttryck? Som vanligt använder man tostring()-metoder för att skapa en textrepresentation av de lagrade uttrycken. Dessa metoder gör i princip en inordertraversering av trädet. Ett problem är att i trädet är evalueringsordningen given av strukturen men i den externa bestäms den av prioriteter och parenteser. Således måste tostring()-metoderna, vid behov, sätta ut parenteser för att uttrycken skall bli korrekta. Man kan göra det lätt för sig genom att alltid sätta ut parenteser men det blir inte så vackert. Eftersom parenteshanteringen kan göras på samma sätt för alla unära respektive alla binära operatorer så placeras tostring-metoderna i klasserna Unary respektive Binary. Själva operatornamnet erhålles av getname() 7

Så här ser klassen Unary ut med en naiv implementation (d.v.s. en som sätter ut parenteser var sig det behövs eller ej) av tostring(): public class Unary extends Sexpr { Sexpr argument; public String tostring() { return getname() + "(" + argument.tostring() + ")";... Variabellistan Eftersom värden nu är symboliska och inte numeriska måste värdetypen i variabellistan (hashtabellen) vara av Sexpr: Map<String,Sexpr> variables = new HashMap<String,Sexpr>(); Observera att variabellistan inte alls skall användas i parsern utan evalueringsmetoderna! Huvuditeration Följande struktur i main (eller annan drivmetod) är lämplig Parser p = new Parser(); Map<String,Sexpr> variables = new HashMap<String,Sexpr>; while (true) try { System.out.print("? "); Sexpr e = p.statement(); System.out.println("Inläst uttryck: " + e) System.out.println(e.eval(variables)); catch (...) {... // För kontroll (Kräver lite eftertanke om vad kommandonas tostring- och eval-metoder skall returnera) Symbolisk evaluering Som synes ovan evalueras ett lagrat uttryck genom att eval-metoden för dess rotnod anropas. Beroende på rotnodens typ kan eventuella operanders eval-metoder anropas. Dessa metoder utför helt enkelt en postordertraversering av trädet. En nods eval-metod avgör först vad som skall göras med operanderna. De flesta operatorers operander skall evalueras. Ett undantag finns dock: tilldelningsoperatorn evaluerar sin vänstra men inte sin högra operand (1+2 = a tilldelar värdet av 1+2 dvs 3 till variabeln a inte till värdet av variabel a) Till evalueringsmetodernas hjälp skall ni skriva en klass Symbolic som har ett antal statiska metoder som utför olika symboliska operationer: symbolisk addition, subtraktion,.... Dessa metoder utför numeriska operationer när det går och gör förenklingar när det går men returnerar alltid ett uttryck av typ Sexpr 8

Exempel: Sinusklassens evalueringsmetod ser typiskt ut så här: public Sexpr eval(hashmap<string,sexpr> variables){ return Symbolic.sin(argument.eval(variables)); och metoden sin i klassen Symbolic har följande utseende: public static Sexpr sin(sexpr arg){ if (arg.isconstant()) return new Constant(Math.sin(arg.getValue())); else return new Sin(arg); Observera att metoderna i Symbolic aldrig anropar någon eval-metod! Liknande metoder skrivs för de övriga funktionerna samt för alla operatorer som kan utföra någon form av aritmetisk beräkning. Om det är möjligt att utföra en numerisk beräkning ska det ske, annars får man utföra operationen symboliskt genom att skapa en ny nod av lämplig typ. Observera dock att metoden alltid måste returnera ett Sexpr, även om den lyckats beräkna ett numeriskt värde. Exemplet ovan visar även att det finns ett behov av metoder som isconstant() och getvalue() i klassen Sexpr. Använd inte instanceof och inte heller typkastning utan utnyttja den dynamiska bindningen! När en variabel evalueras söker man efter den i variabellistan. Hittar man den där returnerar man dess värde, annars variabeln själv. Värdet som hämtas ur listan skall inte evalueras. En konstant evalueras alltid till sig själv. Att evaluera en tilldelning innebär att man evaluerar den vänstra operanden och lägger in dess värde i variabellistan som den högra operanden (variabeln). Det är sedan värdet av den evaluerade operanden som returneras. Felhantering I felhanteringen måste man skilja på syntaxfel (som inträffar under inläsningen) och evalueringsfel (som inträffar under evalueringen). Har ett syntaxfel inträffat måste man rensa bort resterna av det misslyckade uttrycket från input-strömmen. Rör det sig däremot om ett evalueringsfel har inläsningen gått bra och det räcker att meddela användaren vad som gick snett. Vid tidsbrist kan du bortse från felhanteringen! Arbetsgång Uppgiften skall lösas stegvis. Se till att varje steg fungerar innan du går vidare! Lämpliga steg: 9

1. Definiera klasshierarkin. Ta endast med konstruktorer och tostring()-metoder och låt dessa sätta ut parenteser ovillkorligt. 2. Modifiera och bygg ut den parser som tidigare delats ut så att den bygger uttryck (utan evaluering). 3. Testa detta genom att skriva ett huvudprogram som läser in uttryck och sedan skriver ut det inlästa uttrycket. 4. Implementera priority()- och modifiera tostring()-metoderna så att de bara sätter ut parenteser vid behov. 5. Implementera klassen Symbolic. Gör bara enkla implementationer av typ om båda operanderna i additionsmetoden är konstanter så skapa en ny konstant som summan av de två, annars skapa en ny additionsnod med samma operander. Implementera eval-metoderna för de nodklasser som skrivits samt de andra metoder som krävs för att evaluering skall kunna utföras. 6. Förbättra metoderna i klassen Symbolic så att de utför triviala förenklingar. 7. Luta dig tillbaka och se fram mot tentan med största lugn! Observera 1. Programmet skall fungera i enlighet med specifikationen! (Radikalt krav, jag vet... ) 2. Koden skall vara läslig (innebär bl a att inga rader får vara längre än 80 tecken) och följa kodkonventionerna. 3. Du skall använda recursive descent såsom den i den tidigare utdelade parsern. 4. Det skall finnas en metod för varje syntaktisk enhet (varje enskilt syntaxdiagram) och metoden skall ha de namn som anges där. 5. Du skall följa den givna klassdesignen i detalj dvs alla klasser skall finnas med de angivna namnen och de angivna metoderna. 6. Det är förbjudet att använda instanceof och typkastningar mellan olika klasser i klasshierarkin. 7. Upprepa inte identisk eller nästan identisk kod i olika klasser en klass skall bara definiera det som är speciellt för den. Tänk särskilt på detta i konstrukturer (utnyttja super!) och tostring-metoder! 10