Processing
Børre Stenseth
Problemer >Latin

Latinske ordtak

Hva

På en webadresse: https://borres.hiof.no/wep/data/latin/ordtak.txt. ligger det en rekke linjer med latinske ordtak med norsk oversettelse. Vi vil lage en skisse som legger ut et tilfeldig ordtak (latin og norsk) med jevne mellomrom.

Relevante Skisser
latinTest1, latinRandom, latinErrorTest, latin, latinMin 

Strategi

Igjen stiller vi spørsmålet: Kan problemet dekomponeres, er det så fall noen opplagt eller smart rekkefølge, eller kan problemene løses hver for seg ?

Hvis vi analyserer den aktuelle oppgaven så involverer den i hvert fall tre problemer:

  1. Hvordan ser dataene ut, hvordan er de organisert?
  2. Hvordan skal vi kunne lese dem, sikkert og effektivt?
  3. Hvordan skal vi kunne velge et tilfeldig ordtak med jevne mellomrom?

Dataformat

Det første vi gjør er vel naturlig nok å åpne websiden med ordtak i nettleseren. Vi ser da at vi har en rekke linjer, et utdrag:

Acta est fabula, plaudite;Skuespillet er slutt, applauder
Acta non verba;Handling, ikke ord
Acta sanctorum;Helgenenes gjerninger
Ad absurdum;Til grensen av det absurde
Ad astra;Til stjernene
Ad augusta per angusta;Til topps på smale veier
Ad fontes;Til kildene>

Det ser ut til at vi har et ordtak pr linje og at latinen er skilt fra den norske oversettelsen med et semikolon ;. Siden vi ikke har kontroll over dataene må vi imidlertid alltid ta høyde for at det kan være feil i formatet. Hva hvis den som er ansvarlig plutselig legger til noen ordtak og glemmer et semikolon, eller legger ut en tom linje, eller glemmer å skrive inn oversettelsen ?

Hvordan lese data og lagre dem i programmet

Processing kan lese data i mange ulike formater og fra mange ulike kilder. Vi forsøker oss med den løsningen som er mest nærliggende, loadStrings(). En test kan se slik ut:

_latinTest1.pde
// forsøker å lese data fra en webside
void setup(){
  size(100,100);  
  String adresse=
    "https://borres.hiof.no/wep/data/latin/ordtak.txt";
  String ordTak[]=loadStrings(adresse);
  // skriver til console
  if(ordTak==null){
    println("fikk ikke lest data");
  }else{
    println("har lest "+ordTak.length+" linjer"); 
    println("første linje: "+ordTak[0]);
    println("siste linje: "+ordTak[ordTak.length-1]);
  }
}
 
void draw(){
  text("Ferdig",10,10);
  noLoop(); 
}

Hvordan velge tilfeldig

I Processing som i de fleste andre programmeringsverkøy har vi en funksjon som returnerer en tilfeldig verdi, random(). random returnerer et flytetall og vi kan bestemme nedre og øvre grense for tallet, f.eks. random(1.0,2.0) eller random(0,5). Du kan eksperimentere med en slik skisse.

_latinRandom.pde
void setup(){
  size(100,100);  
}
 
void draw(){
  // skriv ut 100 tilfeldige tall 
  // innenfor et intervall
  for(int i=0; i < 100; i++){
    // du kan eksperimentere med
    // parametrne til random   
    // her får vi ut heltallsverdier, 
    // desimalene er kuttet vekk
    print(int(random(0,10))+",");
  }
  noLoop(); 
  }

Hvor mye skal vi kontrollere

Dette er et sentralt spørsmål i mange sammenhenger. Vi må ha en rimelig feil/avviks kontroll og vi må ha en fornuftig reaksjon på feil/avvik. Hvor dypt vi skal gå i dette er selvsagt avhengig av hvilket problem vi skal løse. I dette tilfellet er det vel rimelig nok hvis vi kan gi en forståelig melding hvis det er noe som skjærer seg. Det som kan skjære seg her er vel primært:

  1. Dataene finnes ikke på den oppgitte adressen
  2. Det kan være blanke linjer i fila
  3. Skillet mellom de to delene av en linje kan mangle

Vi har tre altenative strategier for å handtere avvik av typen over.

  1. Vi kan avlutte programmet straks med en feilmelding.
  2. Vi kan går nøye gjennom alle linjene og rette opp de vi tror det er håp for.
  3. vi kan ta linjene som de velges og enten la være å vise dem hvis vi oppdager feil eller vise dem slik de er.

En skisse til en test

_latinErrorTest.pde
// enkel feilhåndtering
String ordTak[];
void setup(){
  size(500,100);
  // testdata
  ordTak=new String[4];
  ordTak[0]="dette er latin 0; dette er norsk 0";
  ordTak[1]="dette er latin 1 dette er norsk 1";
  ordTak[2]="dette er latin 2; dette er norsk 2";
  ordTak[3]=" ";
  fill(0,0,0);
  frameRate(0.5);
}
 
void draw(){
  background(255,255,255);
  // velg tilfeldig linje
  int ix=int(random(0,ordTak.length));
  String linje=ordTak[ix];
  
  // lag løsning ved feil
  if(linje.indexOf(";")==-1){
    if(linje.length() < 2){
      linje="beklager; feil";
    }
    else{
      linje=linje+"; ingen oversettelse";
    }    
  }
    
  linje=linje.replace(";","\n");
  textAlign(CENTER,TOP);
  text(linje,width/2,30); 
}

Hvis vi skruer alt dette sammen kan vi komme ut med en slik løsning;

_latin.pde
// forsøker å lese data fra en webside
String ordTak[];
void lesData(String adresse){
  ordTak=loadStrings(adresse);
  if(ordTak==null){
    println("fikk ikke lest data");
    ordTak=new String[1];
    ordTak[0]="Beklager feil; Fikk ikke lest data";
  }
}
void visOrdtak(){
  String linje=ordTak[int(random(ordTak.length))];
  int deleTegn=linje.indexOf(";");
  // lag løsning ved feil
  if(linje.indexOf(";")==-1){
    if(linje.length() < 2){
      linje="beklager; feil";
    }
    else{
      linje=linje+"; ingen oversettelse";
    }
  }
  linje=linje.replace(";","\n");
  textAlign(CENTER,TOP);
  text(linje,width/2,30); 
}
 
void setup(){
  size(500,100);  
  lesData("https://borres.hiof.no/wep/data/latin/ordtak.txt");
  PFont showFont = createFont("Georgia", 14);
  textFont(showFont);
  fill(0,0,0);
  frameRate(0.2);
}
 
void draw(){
 background(255,255,255);
 visOrdtak();
}

Motsatt resonnement

Hvis vi glemmer sikkerhet, kontroll og layout kan oppgaven løses med følgende skisse::

_latinMin.pde
/* minimumsversjon for visning av ordtak*/
String ordTak[];
  
void setup(){
  size(500,100);
  ordTak=
   loadStrings("https://borres.hiof.no/wep/data/latin/ordtak.txt");
  fill(0,0,0);
}
 
void draw(){
  background(255,255,255);
  String linje=ordTak[int(random(ordTak.length))];
  linje=linje.replace(";","\n");
  textAlign(CENTER,TOP);
  text(linje,width/2,30); 
  frameRate(0.2);
}

Så kan vi fortsette med feilhandtering og utskrift. I dette tilfellet kan dette være en farbar vei. Ulempem med en slik angrepsvinkel er at vi får en vanskeligere feilfinningssituasjon i selve koden, og vi ender fort opp med en del lappverk.

Eller vi kan selvsagt flytte fila med ordtak til samme katalog som programmet og sjekke den manuelt. I så fall trenger vi kanskje ikke noen feilkontroll, men vi går glipp av eventuelle oppdateringer.

Oppgaverforslag

Glosedrill

Lage en skisse som med jevne mellomrom legger ut et ord eller en setning på et fremmed språk, sammen med en norsk oversettelse. Du kan sette det opp slik at enten det norske eller det utenlandske ordet(setningen) kommer først, og så kan det være en kort tenkepause før oversettelsen kommer.

Problemer >Latin