TDP007 Konstruktion av datorspråk
Seminarie 2: Strukturerad text, reguljära uttryck och XML
Syftet med det andra seminariet är att titta på olika sätt att hantera strukturerad text. I första delen behandlar vi informationen i en vanlig textfil med reguljära uttryck, och i andra delen läser vi in information som lagrats med ett uppmärkningsspråk. Båda dessa tekniker fokuserar i första hand på språk som inte är till för programkod utan för information.
Vad ska man tänka på?
Precis som inför förra seminariet ska ni, förutom lösningar på uppgifter, lämna in enhetstester och utvecklarblogg.
Uppgift 1: Presentera rapporter från textfiler
I filen football.txt finns det data i tabellform från en säsong i engelska Premier League. Er uppgift är att skriva ett Ruby-program som kan presentera rapporter med följande information:
- Ange vilket lag som haft minst skillnad i antal gjorda (F) och insläppta (A) mål.
- Rangordna lagen med avseende på målskillnad, alltså skillnaden mellan (F) och (A).
Tanken är att ni ska utforma ert program så att det kan hantera även andra fotbollsresultattabeller som ser likadana ut, inte bara just den här exempelfilen.
När ni gjort detta ska ni gå vidare och hantera en annan fil weather.txt som innehåller väderdata under en månads tid för en ort. Er uppgift med väderdatat blir även här att presentera olika rapporter.
- Vilken dag innebar minst skillnad mellan lägsta (MnT) och högsta (MxT) dyngstemperaturen?
- Rangordna dagarna med avseende på skillnaden mellan lägsta och högsta dygnstemperatur.
Testa gärna reguljära uttryck på rubular.com.
Utvecklarbloggen:
När ni har löst båda dessa deluppgifter ska ni, som kommentar i programkoden eller i er utvecklarblogg, reflektera över hur mycket av koden från första delen som gick att återanvända inför andra delen av uppgiften. Tänk tillbaka på regeln DRY från TDP001, vad i dessa uppgift gör det lätt/svårt att återanvända kod?
Uppgift 2: Hantering av XML-dokument
Pontus har en förkärlek för figurspel och även om han spelar lite olika spel så är Warhammer 40k ett av spelen som återkommer ofta. I figurspel möts ofta två spelare och utspelar tillsammans ett slag. Innan man utkämpar detta slag så behöver varje spelare förbereda sin armé för drabbningen. Förutom att bygga och måla modellerna ingår här att sätta samman en lista. I 40k så har varje spelare ett visst antal poäng att sätta samman enheter för och varje enhet kostar ett visst antal poäng. På detta sätt kan båda spelarna få med sig en armé till bordet som är någorlunda jämna i hur kraftfulla de är.
Skapandet av dessa listor kan vara lite bökigt att göra med papper och penna, därför har gemenskapen runt spelet skapat verktyg för att underlätta processen för spelarna. En form datan som dessa verktyg använder är xml-filer. Du kan ladda ned filen som visar majoriteten av datan om armén Imperial Knights här - Imperial Knights xml.
Som du kan se är dessa filer relativt stora (även för en armé med få val som denna har) då filen innehåller närmare 9000 rader xml. Filerna är skapade av privatpersoner som är intresserade av spelet men som inte nödvändigtvis är programmerare eller datavetare. Det kan också vara svårt att förstå hur filen är strukturerad om man inte är insatt i spelet (vilket vi inte räknar med att du är). Av den anledningen kommer vi vara noga med att berätta precis var datan du ska hämta finns. Tänk på att det fortfarande är viktigt att utveckla tekniker för att tackla denna typ av dokument.
Uppgift 2.1 - Läsa ut data med SAX-parser
I denna uppgift ska vi med en SAX-parser (ström parser) läsa ut data, du ska använda REXML för detta. Se dokumentationen för REXML::Document och REXML::StreamListener samt relevanta filer och slides från föreläsningen.
- Hitta och spara undan namnet på alla enheter som finns tillgängliga. Dessa finns lagrade i elementet catalogue > entryLinks och vi är bara intresserade av enheter som saknar attributet hidden. Det spelar alltså ingen roll vad attributet är satt till, bara om det existerar eller inte. Exempel på några namn är Knight Paladin, Knight Errant och Knight Gallant, men inte exempelvis Knight Asterius.
- Vi ska sedan hitta vilken kostnad varje enhet har. Förvirrande nog är detta INTE lagrat tillsammans med namnet i entryLinks utan hittas i catalogue > sharedSelectionEntries > selectionEntry > cost. Vi är intresserad av kostnaden som har namnet pts. Vi bör få ut något som ser ut ungefär som:
{
"Canis Rex"=>"415",
"Armiger Warglaive"=>"140",
"Armiger Helverin"=>"140",
"Knight Paladin"=>"375",
"Knight Errant"=>"365",
...
{
Det finns två extra knepiga grejer att ta hänsyn till när man löser denna uppgift:
- I första delen behöver man hålla koll på att entryLinks ligger direkt under catalogue. Denna råkar existera på andra ställen i dokumentet men vi är bara intresserade av den som ligger på precis detta djup.
- I den andra delen så råkar den första enheten (Canis Rex) som representeras av en selectionEntry själv innehåller andra selectionEntries
Kan du inte lösa dessa extra-knepiga problem till seminariet är det okej. Men du behöver minst ha med dig en tydlig idé om hur man kan lößa denna typ av problem till seminariet
Uppgift 2.2 - Läsa ut data med DOM-parser
Lös nu samma problem som du löste i uppgift 2.1. Men denna gång använder vi istället DOM-parsern vi tittat på under föreläsningarna tillsammans med xpaths. Med dessa verktyg bör du inte ha några särskilda problem med de extra-knepiga bitarna från förra uppgiften.Fokus för diskussioner och Utvecklarbloggan
- Hur felsöker man sin SAX-parser på ett systematiskt sätt? (tänk på en tentamiljö där man måste kunna ta sig framåt systematiskt mot en lösning utan hjälp)
- Hur tacklar man på bästa sätt att gräva ned sig och förstå strukturen i en XML-fil som man ska läsa ut data ur?
- Hur testar man denna typ av lösningar? Kan man bara testa hela lösningen eller går det att testa mindre delar?
- Du kommer säkert i framtiden att designa egna dokument där du strukturerar upp data (antingen för xml, regex, eller andra tekniker). Finns det något du kan ta med dig från att ha jobbat med datan i detta seminarie?
Sidansvarig: Pontus Haglund
Senast uppdaterad: 2026-01-21
