F6: Debriefing OU2, OU3 Hashtabeller, användargränssnitt, interaktivitet och grafik. Carl Nettelblad

Relevanta dokument
F7: Användargränssnitt, interaktivitet och grafik. Carl Nettelblad

F5: Debriefing OU2, repetition av listor, träd och hashtabeller. Carl Nettelblad

Programmeringsteknik II - HT18. Föreläsning 6: Grafik och händelsestyrda program med användargränssnitt (och Java-interface) Johan Öfverstedt

F7: Rekursiv till iterativ, sammanfattning, genomgång av omtentan Carl Nettelblad

Obligatorisk uppgift 5

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.

Lägg uppgifterna i ordning. Skriv uppgiftsnummer och din anmälningskod ö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.

F4: Mer om OU1, OU2, listor och träd. Carl Nettelblad

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

Föreläsnings 11 - GUI, Händelsestyrda program, MVC

Föreläsning 3: Händelsestyrda program och användargränssnitt

if (n==null) { return null; } else { return new Node(n.data, copy(n.next));

Frivillig Java-swing-Graphics-lab Programmeringsteknik MN1 vt02

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

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

Två designmönster, MVC och Observer/Observable. Objektorienterad programvaruutveckling GU (DIT011)

Obligatorisk uppgift 5: Symbolisk kalkylator

Observera. Tentamen Programmeringsteknik II Skrivtid:

Subklasser och arv Inledning till grafik (JFrame och JPanel). Något om interface. Objektorienterad programvaruutveckling GU (DIT011) Subklasser

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

Detta dokument är ett exempel, cirka andra hälften av en tentamen för TDA545 Objektorienterad programvaruutveckling

Länkade strukturer, parametriserade typer och undantag

Obligatorisk uppgift: Symbolisk kalkylator

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

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

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.

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

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

TDDC30 Programmering i Java, Datastrukturer och Algoritmer Lektion 3

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.

Föreläsning 9 Datastrukturer (DAT037)

Tentamen Programmeringsteknik II Inledning. Anmälningskod:

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

Swing. MER Java Foundation Classes (JFC) Hur lära sig? Vad är farorna. LayoutManagers. Exempel på några av komponenterna

DI-institutionen Sid 1 av 6 Hans-Edy Mårtensson Sten Sundin

Föreläsning 4 Innehåll. Abstrakta datatypen lista. Implementering av listor. Abstrakt datatypen lista. Abstrakt datatyp

Swing. MER Java Foundation Classes (JFC) Vad är farorna. Hur lära sig? LayoutManagers. Exempel på några av komponenterna

ITK:P1 Lektion 4. Lektion 4. Lektion 4. Att implementera en spelidé i Java. DSV Peter Mozelius

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

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

TDDE10 m.fl. Objektorienterad programmering i Java Föreläsning 7 Erik Nilsson, Institutionen för Datavetenskap, LiU

Föreläsning Datastrukturer (DAT036)

Linjärt minne. Sammanhängande minne är ej flexibelt. Effektivt

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

Objektorienterad Programmering DAT043. Föreläsning 9 12/2-18 Moa Johansson (delvis baserat på Fredrik Lindblads material)

DAT043 - föreläsning 8

TDDC30 Programmering i Java, Datastrukturer och Algoritmer Lektion 3

Obligatorisk uppgift 5: Symbolisk kalkylator

Föreläsning 14 Innehåll

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

Föreläsning 9 Innehåll

Sökning och sortering

Föreläsning 9 Innehåll

Objektorienterad Programmering DAT043. Föreläsning 5 29/1-18 Moa Johansson (delvis baserat på Fredrik Lindblads material)

Föreläsning 10. ADT:er och datastrukturer

Kort om klasser och objekt En introduktion till GUI-programmering i Java

Föreläsning 10 Datastrukturer (DAT037)

Föreläsning 4 Innehåll

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

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

ITK:P1 Föreläsning 4. Grafiska gränssnitt i Java. AWT-komponenter

TDDC30. Objektorienterad programmering i Java, datastrukturer och algoritmer. Föreläsning 3 Jonas Lindgren, Institutionen för Datavetenskap, LiU

Programmering för språkteknologer II, HT2014. Rum

Mer om grafiska komponenter. Händelsestyrda program

Inlämningsuppgiften. Föreläsning 9 Innehåll. Träd. Datastrukturer i kursen

Lektion Händelsehanterare

Denna vecka. Idag. Grafiskt användarsnitt. Vi kommer att se

Datastrukturer i kursen. Föreläsning 8 Innehåll. Träd rekursiv definition. Träd

Föreläsning 12. Föreläsning 12. Rörliga figurer Klassen Timer Undantag Något om applets. Rörliga appletsfigurer Klassen Timer Undantag

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

Grundläggande programmering, STS 1, VT Sven Sandberg. Föreläsning 18

Objektorienterad Programkonstruktion. Föreläsning 3 7 nov 2016

Föreläsning 5 Datastrukturer (DAT037)

Lab5 för prgmedcl04 Grafik

DAT043 - Föreläsning 7

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

Hitta k största bland n element. Föreläsning 13 Innehåll. Histogramproblemet

Föreläsning 4 Datastrukturer (DAT037)

Abstrakta datatyper. Primitiva vektorer. Deklarera en vektor

Lösningsförslag till tentamen

Föreläsning 13. Träd

TDDC30. Objektorienterad programmering i Java, datastrukturer och algoritmer. Föreläsning 3 Jonas Lindgren, Institutionen för Datavetenskap, LiU

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

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

Kungliga Tekniska Högskolan Ämneskod 2D4134 Nada Tentamensdag maj - 19 Tentamen i Objektorientering och Java Skrivtid 5 h

Föreläsning 3: Abstrakta datastrukturer, kö, stack, lista

Klasshierarkier - repetition

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

Tentamen i Algoritmer & Datastrukturer i Java

Trädstrukturer och grafer

Föreläsning 14: Grafik & mera händelsehantering

Föreläsning 7. Träd och binära sökträd

Diskutera. Hashfunktion

Lösningsförslag till tentamen Datastrukturer, DAT037,

Tentamen Datastrukturer, DAT037 (DAT036)

Tentamen för kursen Objektorienterad programvaruutveckling GU (DIT010)

Föreläsning 3 Datastrukturer (DAT037)

F12 - Collections. ID1004 Objektorienterad programmering Fredrik Kilander

Transkript:

F6: Debriefing OU2, OU3 Hashtabeller, användargränssnitt, interaktivitet och grafik Carl Nettelblad 2018-05-07

Recursive descent Gå från vänster till höger Titta bara på nästa token Rekursera ned olika djupt Var upptäcks de flesta fel? Längst ut Metoderna returnerar innan hela uttrycket är tolkat Längst in Primary fastnar på något den inte förstår

Hur hantera fel? (T.ex.) primary vet precis vad som gått fel Vet inte hur man kom dit Rapportera precis vad felet Med egna undantagsklasser Syntaxfel Ett viss uttryck är alltid felaktigt Evalueringsfel Att faktiskt beräkna uttrycket, just nu, går inte

Fånga felen Fånga undantag har två syften Rapportera felet I vårt fall, ta med info om aktuellt token i rapporten Hantera felet Vad gör vi nu? Hela programmet ska inte avslutas, ska fortsätta fungera normalt Exempel: Läsa till slutet av raden» Kunde vara stänga filer, starta om en bana, nollställa en beräkning, parkera en styrd utrustning i ett säkert läge, logga ut användaren

Kompilatorfel eller oväntade resultat vid körning Sätt att hantera fel Oväntat resultat/krasch Rapporterat undantag Hitta fel i förberedda tester Hitta fel i kompilering

Primary public double primary() { double result = 99999; if (tokenizer.isnumber()) { result = tokenizer.getnumber(); tokenizer.nexttoken(); } else return result; } Vad händer om vi missar att sätta result i ett fall? Får 99999 vid körning

Kompilatorfel eller oväntade resultat vid körning Sätt att hantera fel Oväntat resultat/krasch Rapporterat undantag Hitta fel i förberedda tester Hitta fel i kompilering

Primary public double primary() { double result = 99999; if (tokenizer.isnumber()) { result = tokenizer.getnumber(); tokenizer.nexttoken(); } else } else { throw new SyntaxException("unhandled case in primary"); } return result; } Vad händer om vi missar ett fall?

Kompilatorfel eller oväntade resultat vid körning Sätt att hantera fel Oväntat resultat/krasch Rapporterat undantag Hitta fel i förberedda tester Hitta fel i kompilering

Primary public double primary() { double result; if (tokenizer.isnumber()) { result = tokenizer.getnumber(); tokenizer.nexttoken(); } else return result; } Vad händer om vi missar att sätta result i ett fall? Kompileringsfel! Otilldelad variabel

Kompilatorfel eller oväntade resultat vid körning Sätt att hantera fel Oväntat resultat/krasch Rapporterat undantag Hitta fel i förberedda tester Hitta fel i kompilering

functionhelper private double functionhelper(string name, double val) { if (name.equals("cos")) { return Math.cos(val); } else if (name.equals("sin")) { return Math.sin(val); } } else { return Math.log(val); } } Vad händer om name inte är något av de godkända namnen?

Kompilatorfel eller oväntade resultat vid körning Sätt att hantera fel Oväntat resultat/krasch Rapporterat undantag Hitta fel i förberedda tester Hitta fel i kompilering

functionhelper private double functionhelper(string name, double val) { if (name.equals("cos")) { return Math.cos(val); } else if (name.equals("sin")) { } return Math.sin(val); } else if (name.equals("log")) { return Math.log(val); } else { throw new SyntaxException("Function " + name + " not supported."); } }

Kompilatorfel eller oväntade resultat vid körning Sätt att hantera fel Oväntat resultat/krasch Rapporterat undantag Hitta fel i förberedda tester Hitta fel i kompilering

samecontents Kan implementeras i linjär tid och linjärt extra minne med toarraylist Använd färdig equals i ArrayList Men inte så effektivt om träden är väldigt olika Om this.smallest() och t.smallest() är olika borde vi kunna upptäcka det direkt Pratar om ett annat sätt i slutet av föreläsningen eller sista gången

Länkade listor Låt varje element peka på sin efterföljare Precis som ArrayList finns LinkedList i Java I många fall är ArrayList bäst Men inte om man vill lägga till/ta bort element någon annanstans än nära slutet

Fler varianter Dubbellänkad, cirkulär lista Lättare att nå sista elementet, lättare att röra sig bakåt i listan Men alla algoritmer krångligare

Hjälpmetoder Publika metoder finns för att ge ett tydligt kontrakt till omvärlden Så här använder du den här klassen Hjälpmetoderna finns för att ge dig en tydlig struktur inne i klassen Kan göra saker som är förbjudna utifrån Kan ta andra parametrar och returnera andra värden än de publika metoderna Klassmetoder (static) om all information finns i parametrarna och returvärdet

tostring public String tostring() { return tostring(root); } private static String tostring(node r) { if (r==null) { return ""; } else { return tostring(r.left) + " " + r.value + " " + tostring(r.right); } } Vilken typ av traversering är detta? Preorder, postorder, inorder?

Egenskaper hos binära träd Ett binärt träd med k fyllda nivåer innehåller n noder n = 1 + 2 + 4 + + 2 k 1 = 2 k -1 k = log 2 (n + 1) log 2 n I ett sådant träd blir arbetet för Sökning O log n Inlägg O log n Uttag O log n

Sämsta möjliga träd I ett sådant träd blir arbetet för Sökning O n Inlägg O n Uttag O n Trädet en linjär lista Algoritmerna blir i praktiken som algoritmerna för enkellänkad

Intern väglängd Intern väglängd (ipl, eller bara i) kan definieras som summan av nivån för alla noder Roten har nivå 1, rotens barn nivå 2, Exempel: i = 1 + 2 * 2 + 4 * 3 + 4 * 4 = 33 Att hitta en lagrad nyckel tar då i genomsnitt i n = 33 11 = 3 steg

Extern väglängd Extern väglängd (EPL, eller bara E) tar med externa noder dessutom Den externa väglängden definieras som summan av de externa nodernas nivåer (4 * 4 + 8 * 5 = 56 för exemplets 12 externa noder) Varje sökning efter en nyckel som inte finns slutar i en extern nod. Eftersom antalet externa noder är n + 1 blir det genomsnittliga antalet försök för misslyckad sökning E/(n + 1)

Iläggningsordning Hur ett binärt träd växer beror på i vilken ordning noderna läggs i Praktiska implementationer kan ibland också balansera om trädet AVL-träd, rödsvarta träd En definition på hur bra trädet är blir hur välordnat det blir i medeltal över alla möjliga iläggningsordningar Den interna väglängden för alla träd som bildas om man lägger in alla n! permutationer av n nycklar blir 1,38 n log 2 n + O n I ett slumpmässigt träd tar då sökning O(log n) operationer

Binära sökträd i Java TreeSet<E>, TreeMap<K,V> är sådana ombalanserande binära träd. De garanterar O(log n) för inlägg, sökning och urtag för varje specifikt träd.

Alla binära träd är inte sökträd

Alla binära träd är inte sökträd Aritmetiska uttrycket 1 * (2 3) + (4 + 5)/6 Trädet styr evalueringsordning, inga parenteser Värdet beräknas genom att rekursivt: Beräkna värdet av vänster träd Beräkna värdet av höger träd Utföra operationen på de två beräknade värdena

Hashtabeller Vi har sett att man kan göra sökträd Oftast i en struktur är det viktiga att kunna lägga in, söka och ta bort Inte traversera i viss ordning Tidskomplexitet Lägg in Sök Ta bort Sorterad array Θ(n) Θ(log n) Θ(n) Länkad lista Θ(n) Θ(n) Θ(n) Binärt sökträd Θ(log n) Θ(log n) Θ(log n) Går det att göra bättre? Inte om vi bara kan jämföra enskilda element

Hashtabeller Vi kanske kan använda mer information än bara en sorterings-/jämförelseregel. Arrayer är snabba. Lagra alla element i en array, välj index utifrån en hashfunktion. Samma objekt leder alltid till samma hashvärde. Blir värdena alltid unika? Oftast inte. Hur gör man då? Leta efter en annan plats i arrayen. eller Använd en länkad lista för alla element som kolliderar. Vi tittar på alternativet med en länkad lista.

Heltal som element Tänk att vi har en liten tabell med 7 platser och hashfunktionen h(k) = k mod 7 (rest vid heltalsdivision) som hashfunktion. k 27 4 7 42 3 14 81 26 13 8 h(k) 6 4 0 0 3 0 4 5 6 1 Väljer att hålla listorna sorterade eftersom man vid inlägg ändå måste kontrollera att elementet inte redan är inlagt.

Tidskomplexitet Antag att vi vill lagra n nycklar i en array med m platser Den genomsnittliga listlängden blir då α = n m fyllnadsgraden som kallas Om α 1 och om hashfunktionen sprider elementen någorlunda jämnt över arrayen blir strukturen effektiv för inlägg, sökning och urtag. Misslyckad sökning: 1 + α försök Lyckad sökning: 1 + α 2 försök Fördjupad analys i separat dokument

Tidskomplexitet Om tabellstorleken ungefär motsvara antalet element och hashfunktionen ger bra spridning tar sökning, inlägg och urtag O(1) tid Nära på lika snabbt som vanlig array Trädstrukturer är O(log n) Dessutom är varje operation ofta dyrare

Skapa hashfunktioner Enormt viktiga att hashvärdet är någorlunda unikt Även när man tar modulo något mindre tal För heltal: h(k) = k Blir k mod m i praktiken för hashtabell storlek m Teckensträngar Konstruera ett heltal utifrån teckenkoderna, se mer i länkat dokument Ofta viktigt att samma teckenföljd i annan ordning inte får samma kod

Hashstrukturer i Java HashSet<E> HashMap<K, V> Ofta bättre (snabbare) än TreeSet, TreeMap Samma metoder Olika implementationer av gränssnitten (interface) Set och Map Går att skriva kod som ska ta en Map och sedan ge den antingen en TreeMap eller en HashMap

Basklass och interface Basklassen har metoder och klassvariabler Om den inte är abstrakt kan man skapa en instans av den En subklass kan ärva från högst en basklass Om ingen basklass anges ärver man från Object Klassen Y ärver från klassen X, varje Y är en X Interface har metoder Utan implementation, som om alla metoder är abstrakta Man kan inte skapa en instans av ett interface Klassen Y implementerar interface X, varje Y kan ses som en X Varje HashMap kan ses som en Map

Hashfunktioner i Java Java har inbyggda hashfunktioner Metoden int hashcode() finns i klassen Object Precis som tostring och equals Standardversionen beräknar hash utifrån referenslikhet D.v.s. om a == b har de också samma hashvärde I standardklasser som ersätter equals ersätts också hashcode Samma objekt bör inte byta hashvärde under sin livstid Tänk om du stoppar in ett objekt i en HashSet och sedan förändrar det så att det byter hashvärde En egen klass bör alltid ha en egen tostring Om du har en egen hashcode bör du ha en egen equals, och vice versa

Sammanfattning Listor och träd är flexibla datastrukturer Grund för att komma fram till egna representationer Oerhört kraftfullt att ha objekt som refererar till objekt av samma typ Som Node Om du bara behöver en lista, använd ändå ArrayList Om du bara behöver en länkad lista, använd LinkedList HashMap och HashSet är bra grundval för att skapa avbildningar och lagra mängder Kräver korrekt implementation av hashcode och equals om referenslikhet inte räcker

Händelsestyrd programmering Hur fungerar den numeriska kalkylatorn? En slinga som läser kommandon Anropar metoder för att hantera kommandon Varje kommando hanteras fort Utför arbete, kommer tillbaka till huvudslingan Motsats Ett program som ställer upprepade frågor till användaren i samma metod Ett menysystem där varje meny är en egen metod som ber användaren välja alternativ

Händelsestyrda program Många datorprogram är händelsestyrda på det här viset Definition: Händelsestyrd programmering är ett paradigm där programmets flöde bestäms av händelser som användarhandlingar (musklick, knapptryck), sensorutmatning eller meddelanden från andra program/trådar. Händelsestyrd programmering är det dominerande paradigmet i program med grafiska användargränssnitt och andra tillämpningar. (Omskrivet och översatt från https://en.wikipedia.org/wiki/event-driven_programming )

Struktur Vänta på händelse (Börja) hantera händelse Bör gå fort, annars kan senare händelser inte hanteras Komponenten som väntar på händelser generell Färdig i det bibliotek man använder Eller egen men sällan i behov att ändras Händelseslinga/ event loop Kan startas genom ett metodanrop eller indirekt i en konstruktor

Grafiska användargränssnitt Jämfört med kalkylatorn är mängder av händelser möjliga i ett grafiskt program, som: Ändra storlek på fönster Flytta på fönster Animera gränssnittet för att visa vad som är markerat och De riktiga funktionerna hos programmet

Vårt första program import javax.swing.*; import java.awt.*; import java.awt.event.*; public class WindowApp1 extends JFrame { public WindowApp1() { super("an event driven program"); setresizable(false); getcontentpane().setpreferredsize(new Dimension(400, 400)); setdefaultcloseoperation(jframe.dispose_on_close); pack(); setvisible(true); } } public static void main(string[] args) { WindowApp1 app = new WindowApp1(); }

Vad gör koden? Vi ärver från JFrame Representerar ett fönster Konstruktorn gör anpassningar Fönstrets titel Storlek och att den inte får ändras Vad som händer när fönstret stängs Men ingen metod för det Vi tar inte själva hand om den händelsen Att fönstret ska visas Obs! Glöm inte denna!

Händelsedrivet Vår main gör ingenting Skapar bara ett objekt Programmet gör inte heller någonting Mäta processoranvändning Men vi har ingen kod för att hantera händelser Lägg till en knapp!

Fyra steg Markera att vi kan lyssna på händelser Lägg till knappen Säg att vi vill lyssna på knappens händelser Implementera knappmetoden

Lyssna på händelser public class WindowApp2 extends JFrame implements ActionListener { public WindowApp2() { ActionListener är ett interface som ingår Javaramverket för grafiska gränssnitt (awt/swing) En enda metod actionperformed Anropas för alla händelser vi väljer att lyssna på

Lägg till knappen och registrera lyssnare setdefaultcloseoperation(jframe.dispose_on_close); JPanel panel = new JPanel(); getcontentpane().add(panel); JButton button = new JButton("Whatever you do, do not push this button!"); panel.add(button); button.addactionlistener(this); pack(); Knappen ligger i en panel Det räcker inte med att skapa knappen Knappen vet inte att den ska ligga i panelen i fönstret Eller vart den ska skicka sina händelser

Implementera metoden public void actionperformed(actionevent e) { JOptionPane.showMessageDialog(null, "I told you not to push the button...", "Event captured", JOptionPane.INFORMATION_MESSAGE); } Det här är vår lyssningsmetod. Enkelt i det här fallet, bara en möjlig händelse (som vi vet om). Alltid klokt att kontrollera att det är rätt sorts händelse om flera är möjliga. Jämför functionhelper i OU2, olämpligt att ha ett sistafall på en kedja med if-else som antar att tillståndet är giltigt.

Lyssnare/händelsehanterare Lyssnaren är ett objekt som informeras om vissa händelser efter att ha registrerat sig. Ett vanligt designmönster Frikoppling mellan källan till händelsen och mottagaren. ActionListener med metoden actionperformed bara ett exempel på mönstret.

Lyssnare och källor Samma källa kan ha flera lyssnare Samma lyssnare kan ha flera källor När metoden anropas måste det framgå Varifrån händelsen kommer Vilken händelse det är Annan information

Hitta källan public void actionperformed(actionevent e) { if (e.getsource() == obj1) { // Åtgärd för objekt 1 } else if (e.getsource() == obj2) { // Åtgärd för objekt 2 } else { // throw new RuntimeException här??? } }

Timers Hur gör vi om något ska hända hela tiden Ett sätt while-loop Kanske med anrop Thread.sleep Pausar i ett antal ms Stör händelseflödet Händelseinriktat sätt Be om att få timerhändelser!

Exempel på timer timer = new Timer(5000, this); timer.start(); Skickar händelser till objektet Spara Timer-objektet i en instansvariabel

Om grafiska gränssnitt Fällor Förvirrande layout Lång tid i händelsehanterare Kom ihåg, programmet svarar inte medan händelsen hanteras Användargränssnittskod som även sköter logiken Model view controller Försöka skilja på klasser som beskriver världen, klasser som beskriver användargränssnittet och klasser som utför åtgärder

Layout i Swing Man vill inte tala om exakta koordinater för varje del i gränssnittet I stället användas layoutklasser, två exempel: FlowLayout visa komponenterna i den ordning de läggs till GridLayout visa komponenterna i ett fast rutnät

Layout GridLayout FlowLayout

Välja layout På befintligt objekt (som hela contentpane): Container contentpane = getcontentpane(); contentpane.setlayout(new FlowLayout()); På en ny panel JPanel panel = new JPanel(new GridLayout(2, 2));

Grafik på datorer Vad finns på skärmen? Skärmen minns inte Bilden ritas om många gånger per sekund Ett minne i datorn lagrar skärmbilden Som en stor array Men vad händer om man vill ändra något?

Kvadraten och cirkeln Vi vill att cirkeln ska röra sig över kvadraten

Hur? Tänk två metoder drawcircle(x,y) drawsquare(x,y) Vi vill flytta på cirkeln Många drawcircle?

Kvadraten och cirkeln Vi ritar en massa cirklar Men de gamla cirklarna vi ritade finns kvar För att få cirkeln att röra sig måste vi städa upp Rita vitt Rita ut kvadraten igen

Alternativet Representera grafik som objekt Objektens jobb att rita upp sig Jämför paddorna i Programmeringsteknik I

Två paradigm Omedelbart läge (immediate mode) Kommandon om vad som skall ritas, när det skall ritas Behöver svara på händelse när något behöver ritas upp på nytt Delegerat läge (retained mode) Berätta hur världen ser ut Paddor, paneler i Swing, objekt i en spelvärld Någon annan ser till att det hålls uppritat

Koordinatsystem för grafik Matematik Datorgrafik X Y Y X (Ofta) Kanske ett arv från koordinater för text, rad och kolumn Övre vänstra hörnet (0,0)

Koordinatsystem för grafik De mest naturliga koordinaterna för datorn är pixlar Heltal Ganska trubbigt, avrundningsfel En del system har olika typer av stöd för subpixelrendering /anti-alias

Grafik i kod Det finns olika ramverk för grafik OpenGL, Direct3D, GDI, Canvas, Vi fortsätter använda Java Swing Vi utökar JPanel i en egen klass Ersätter metoden paintcomponent Den ritar upp innehållet när det behövs Om vi gör någon ändring får vi be den rita upp igen manuellt (metod repaint)

Exempelklass public class GraphicsExample extends JPanel { public GraphicsExample() { super(); super.setpreferredsize( new Dimension(400, 400)); super.setbackground(color.white); } @Override public void paintcomponent(graphics g) { super.paintcomponent(g); //void setcolor(color color) g.setcolor(color.red);

Exempelklass //void fillrect( // int x, int y, // int width, int height) g.fillrect(100, 100, 200, 200); g.setcolor(color.black); //void filloval( // int x, int y, // int width, int height) g.filloval(100, 100, 200, 200); //void drawline( // int x1, int y1, int x2, int y2) g.drawline(0, 0, 100, 100); } }

Resultat

Immediate mode i Swing Uppritning sker mot ett Graphics-objekt Ofta som var på uppritningshändelse Finns också Graphics2D-objekt Titta i koden för paddorna från färska omgångar av Programmeringsteknik I Kommandonas ordning spelar stor roll Sist ritat är det som syns Färginställning med setcolor gäller tills man byter Kan vara svårt att felsöka i debugger Ett halvt uppritat fönster ser inte alltid ut som man tänker sig

Sammanfattning, klass för klass JFrame fönster, som ofta också kan implementera ActionListener, lägger till fler delar i fönstret i konstruktorn JPanel allmän yta, ersätt metoden PaintComponent i subklass om man vill rita grafik JLabel statisk etikett (text) JTextField textfält för inmatning JButton klickbar knapp GridLayout strukturera komponenter i rutnät FlowLayout strukturera komponenter i följd Timer källa för timerhändelser

OU4 Studsande bollar Skapa först ett fönster och en egen JPanel (med arv). Testa att rita en enda boll. Skapa en egen bollklass som kan flytta på sig, kollidera med kanter, rita upp sig själv. Skapa flera bollar och låt dem vandra med en timer. Lägg till kollisionshantering. Skapa ett separat användargränssnitt för att styra programmet.

OU5 Vi gjorde en numerisk kalkylator Tolkade (parsade) och utvärderade uttrycken genom samma rekursiva anrop Returnerade double, uppdaterade variabeldefinitioner i assignment Nu ska vi i stället tolka uttrycken Tolkade uttryck kan sedan utvärderas senare Ger möjlighet till symbolhantering Används i uppgiften för derivering och kvotering (aktivt skjuta upp utvärdering)

Exempel Input : 2*(-3-1+6)/0.5 + 0.5 Result: 8.5 Input : log(exp(ans)) Result: 8.5 Input : "(exp(2*x) + x) = y Result: exp(2.0*x)+x Input : y Result: exp(2.0*x)+x Input : ans Result: exp(2.0*x)+x Input : "y Result: y

Kvotering I exemplet ovan blev värdet för variabeln y ett uttryck, inte ett tal Markeras med citationstecken " Allt som inte kvoteras utvärderas direkt

Derivering Deriveringsoperator med ' Vänsterled som ska deriveras, med avseende på variabeln i högerled Felhantering: Vad händer om högerledet inte är en variabel? Ändrar inte på regeln icke-kvoterade uttryck utvärderas direkt så Input : exp(x*x+1)'x Result: 0.0 Input : "exp(x*x +1)'x Result: 2.0*x*exp(x*x+1.0)

Evalueringsoperatorn Om " används för att kvotera, skjuta upp utvärdering Så har vi &, evalueringsoperatorn, för att framtvinga evaluering Input : "(x*x+a*x) = y Result: x*x+a*x Input : 2 = a Result: 2.0 Input : 3 = x Result: 3.0 Input : y Result: x*x+a*x Input : &y Result: 15.0

Syntaxdiagram Väldigt snarlika den numeriska kalkylatorn Derivering införd i factor Unär operator (kvotering/evaluering förutom unärt minus) i primary

Trädrepresentation I stället för att returnera double ska våra parsingmetoder returnera instanser av Sexpr (symbolic expressions) Sexpr är en abstrakt basklass

Trädrepresentation Varje del av ett uttryck måste representeras som en Sexpr eller ett träd av flera Sexpr Exempel: 3 + 5 blir två konstanter som är vänster och höger delträd till en additionsoperationer Parenteser har inga egna klasser, de styr bara trädstrukturen

Klasshierarki Tre huvudtyper av Sexpr Atom löv i trädet, konstanter och tal Unary har ett underträd, unära operatorer och funktioner Binary vänster och höger delträd för vanliga binära operatorer (+ - * / = ')

Utgångspunkt Utgå från kodskelett för uppgiften Alla dotterklasser finns nämnda i PDF-filen för uppgiften Utnyttja arv Många av lövklasserna blir rätt korta när basklasserna är rätt gjorda och hjälpklassen Symbolic Varje klass har en metod eval för evaluering och en metod diff för derivering Symbolic gör jobbet

Exempel: sinus I klassen Sin: public Sexpr eval(map<string,sexpr> map){ return Symbolic.sin(operand.eval(map)); } public Sexpr diff(sexpr x){ return Symbolic.mul(operand.diff(x), new Cos(operand)); } I klassen Symbolic: public static Sexpr sin(sexpr arg){ if (arg.isconstant()) return new Constant(Math.sin(arg.getValue())); else return new Sin(arg); } Mönster: Räkna ut direkt OM det är en konstant, skapa annars bara symbolisk representation.

Förenkling och parenteser Evaluering av x + x om x har ett värde bör bli ett tal, inte ett uttryck Evaluering av "(x * x)'x bör bli 2.0*x Nödvändigt att förenkla uttryck Ett träd för (a + b) * c får inte komma att representeras som a + b * c Nödvändigt att sätta in parenteser på rätt ställen Hellre för många än för få

Tänk på Undvik duplicering av kod Följ kodstandard Läslighet, dokumentation Parsern ska alltid bara parsa Hantera syntaxfel, skapa trädet Evaluering ska vara generell Anropa basklassernas metoder, inte instanceof, inte typomvandlingar Titta gärna igen på exemplen här och i uppgiften på kvotering, evaluering och derivering Lätt att missa vad de faktiskt ska innebära

Iterera i ett träd Träd passar väldigt bra för rekursion Vi kan vilja gå igenom ett träd iterativt Kanske för att det är del av en större rekursion samecontents ett exempel

Stack Rekursion bygger på en stack Anropsstacken Variabelvärden och var i metoden vi står lagras automatiskt i Java Push metodanrop Pop metod returnerar Kasta undantag kan leda till flera pop i följd Anropsstacken visas i felutskriften Men aldrig börja titta mitt i stacken

Göra rekursiv algoritm iterativ Skriv egen kod för stacken Styr när vi gör push och pop Kan behöva lagra både parametrar och tillstånd I vårt fall Node och int 0 vänster delträd, 1 höger delträd Antag att vi har en klass TraversalStack med metoder push, pop, getnode, getstate, isempty

Tankegång Vi väljer att gå igenom trädet in-order Upplägg: Se om det finns ett Node-objekt på stacken Läs av nod och lägestal Poppa Om status är 0 Lägg tillbaka samma nod med status 1 Lägg in vänster delträd med status 0 Om status är 1 Utför operationen för nyckeln Lägg in höger delträd med status 0

Pseudokod void traverse(node start) { Stack s = new Stack(); s.push(start, 0); while (!s.isempty()) { Node now = s.getnode(); int state = s.getstate(); s.pop(); if (now == null) continue;

Pseudokod switch (state) { case 0: // First visit to node s.push(node, 1); s.push(node.getleft(), 0); case 1: // Second visit to node System.out.println(node.getKey()); s.push(node.getright(), 0); default: throw new RuntimeException("Invalid state."); } } }

Kommentar Nullkontroll när vi läser från stacken Lite ineffektivt Annars hade vi behövt kontrollera null på tre ställen För noden själv i början För vänster delträd i state 0 För höger delträd i state 1 Objektet som ska besökas sist läggs på stacken först Störst nytta med en sådan här lösning om arbetet i state 1 vore mer komplext

Sen då? Hur skriver vi om den här till preorder? Postorder? Kan vi stryka state lätt i något fall? Bara Node-objekt på stacken Kan vilja skriva om som metod som ger nästa Node

Pseudokod Node getnodeinorder(stack s) { while (!s.isempty()) { Node now = s.getnode(); int state = s.getstate(); s.pop(); if (now == null) continue;

switch (state) { case 0: // First visit to node s.push(node, 1); s.push(node.getleft(), 0); case 1: // Second visit to node s.push(node.getright(), 0); return node; default: throw new RuntimeException( ); } } return null; } Pseudokod