[x^2 for x in lst]

Pinsam bugg i matteappen

2014-12-02

Buggen fanns i den Activity som visar upp resultatet av en avklarad övningsomgång. Problemet var att den från onCreate() (via ett antal lager) sparade ner resultatet av övningsomgången i databasen.

Vad är problemet med det då? Så kan det väl fungera? Visst. Inget fel med det. Det är bara det att onCreate() även anropas när man roterar devicet (ren svenska för apparaten som kör Android) så att den orienterar om sig från portrait till landscape eller tvärt om. Detta innebar att om man hade klarat en övningsomgång kunde man bara rotera devicet ett kvarts varv och vänta till den orienterat om sig. Sen hade appen registrerat ytterligare en lyckad övningsomgång. Ville man kunna man fortsätta rotera gång efter annan tills man erhållit den finaste medaljen.

Snacka om pinsam bugg. Tur att jag inte kommit så långt att jag laddat upp appen på Play-butiken än.

Var tvungen att fixa buggen snabbt så att jag inte skulle tappa all trovärdhet hos min äldsta dotter. Fick bli till att låsa skärmorienteringen till portrait. Får se till att fixa en bättre, mer permanent lösning så snart jag får tid. När det nu blir...

Nyheter i Java 8 - del 7 - Lösa trådar och uppsummering

2014-12-18

Efter ett längre uppehåll är det nu dags för den sjunde och sista delen i miniserien om nyheterna i Java 8. Förra delen handlade om nyheter i klassen Arrays. Den här delen listar lite av de nyheter i Java 8 som inte tidigare tagits upp i serien samt summerar mina intryck av Java 8 och hur det har varit att skriva den här serien av blogginlägg.

Fler nyheter i Java 8

Vi har ju gått igenom en massa nyheter i Java 8. Streams, lambdauttryck med mera. Vad finns det då ytterligare för nyheter i Java 8? Om man läser på Oracles "officiella" sida What's New in JDK 8 så ser man att det är en hel del nyhter som vi inte tagit upp (det är dock roligt att se att det är rätt mycket som vi har tagit upp också). En del av de saker vi inte tagit upp är följande:

  • Förändringar i annoteringsramverket.
  • Förbättringar när det gäller säkerhetsrelaterade saker.
  • Förbättringar av JavaFX.
  • Nya verktyg (jjs) tillagda och förbättringar är gjorda på redan befintliga.
  • Nya Date - Time-paket
  • Ny JavaScript-motor: Nashorn
  • JDBC 4.2

Flera av sakerna ovan låter intressanta att kolla på. Speciellt Nashorn borde man ju ta sig en närmare titt på. Får bli nästa år. Så mycket att göra och så lite tid... ;)

Litet Java 8-nyheter-letar-program

För skojs skull gjorde jag ett litet Java-program som kravlar igenom API-dokumentationen för Java 8 och letar efter alla klasser som innehåller "since 1.8" (se nedan) och skriver ut namnen på dessa (egentligen den fulla path:en till javadoc-html-filen) på std out. Det hittade över 300 klasser. Det är alltså en hel del klasser som är nya eller har fått nya metoder/fält i 1.8.

Angående programmet så kompliceras det lite grand av att "Since" och "1.8" inte finns på samma rad i API-dokumentationen. Programmet måste därför undersöka två rader i taget tills det antingen får en träff eller kommer till slutet på filen. I övrigt är det ett rätt okomplicerat program som startar i en startkatalog, undersöker html-filerna i den katalogen och sedan fortsätter att undesöka filerna i dess underkataloger rekursivt. Jag har inte försökt optimera programmet på något sätt, så det finns (som vanligt ;) säkert rum för förbättringar.

Programmet använder som ni set Java 8-specifika features som strömmar och lambdauttryck, vilket gör att de delar som innehåller "affärslogiken" blir ganska korta och koncisa. För att jämföra skrev jag ett motsvarande program som inte använder Java 8-features. Det blev ca 15 rader längre. Inte så stor skillnad kanske, men om man ser på programmen så är de delar som verkligen gör något avsevärt kortare i Java 8-varianten. Detta främst på grund av den trevliga metoden Stream.filter() som vi ju pratat om tidigare.

package since18Finder;

import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.Paths;

import java.io.File;
import java.io.FileFilter;
import java.io.Reader;
import java.io.BufferedReader;
import java.io.FileReader;
import java.io.FileNotFoundException;
import java.io.IOException;

import java.util.List;
import java.util.ArrayList;
import java.util.Arrays;

public class Since18Crawler
{
  public final static String START_DIR = "/home/lars/text/docs/java/1.8/docs/api/java/";
  public final static String SINCE_1_8_ROW_1 = "Since:";
  public final static String SINCE_1_8_ROW_2 = "1.8";

  public static void main(String[] args) throws IOException
  {
    visitDirectory(Paths.get(START_DIR));
  } 

  private static void visitDirectory(Path path)
  {
    try {      
      checkFilesInDirectory(path);
      visitSubDirectories(path);
    } catch(IOException ioe) {
      ioe.printStackTrace();
    }
  }

  private static void visitSubDirectories(Path path) throws IOException {
    Files.list(path).filter(Files::isDirectory).forEach(f -> visitDirectory(f));
  }
  
  private static void checkFilesInDirectory(Path path) throws IOException {
    Files.list(path).
     filter(p -> Since18Crawler.isFileToLookIn(p)).
     filter(p -> Since18Crawler.containsString(p, SINCE_1_8_ROW_1, SINCE_1_8_ROW_2)).
     forEach(p -> System.out.println(p.toFile().getAbsolutePath()));    
  }

  private static boolean isFileToLookIn(Path path) {
    File f = path.toFile();
    return f.isFile() && f.getName().endsWith(".html") && Character.isUpperCase(f.getName().charAt(0));
  }

  private static boolean containsString(final Path pathToFileToExamine, final String stringToLookForInRow1, 
                                        final String stringToLookForInRow2) {
    try {
      File fileToExamine = pathToFileToExamine.toFile();
      try(final BufferedReader reader = new BufferedReader(new FileReader(fileToExamine))) {
          String line;
          while ((line = reader.readLine()) != null) {
            if (line.contains(stringToLookForInRow1)) {
              if ((line = reader.readLine()) != null && line.contains(stringToLookForInRow2)) {
                return true;
              }
            }
          }          
        }
    } catch (IOException e) {
      e.printStackTrace();
    }
    
    return false;          
  }
}

Sammanfattning av serien

Det har varit mycket lärorikt att skriva ihop den här lilla miniserien. Jag har verkligen lärt mig jättemycket, och jag tror även att jag kommer att komma ihåg sakerna bättre nu när jag skrivit om dem.

Angående själva innehållet i Java 8 så är jag imponerad av de delar som jag undersökt. Statiska- och defaultmetoder gör att det är lättare att utöka interface än vad det varit förrut. Tidigare har jag reflexmässigt nästan alltid skapat en abstrakt klass som implementerat ett interface och lagt denna mellan interfacet och den konkreta implementation. Detta behov minskar nu när man kan lägga till defaultmetoder både då interfacet skapas men även i efterhand.

De nya funktionella konstruktionerna i Java 8 är givetvis den största förändringen. Tycker att Oracle-folket fått till en riktig trevlig implementation av lambdas och closures. Det känns som om det hänger ihop på ett logiskt och bra sätt. Är det något man är osäker på syntaxtmässigt så kan man gissa "hur det borde vara" och ha en ganska hög sannolikhet att det man chansat på är rätt, vilket är ett bra betyg tycker jag.

Det känns även som om man fått in de funktionella förändringarna på alla ställen i JDK:n där de passar in; givetvis i collections-ramverket och Arrays men även i de klasser och paket som hanterar I/O (exempelvis i Files, se koden ovan). Det finns inget ställe som det är uppenbart att de missat att lägga till det funktionella stuffet.

Sammanfattningsvis har jag tyckt att det varit väldigt roligt att skriva den här lilla serien. Ser fram emot att skriva en liknande om Java 9 när nu den kommer ut. Hoppas det inte dröjer för länge!

Tidigare delar i serien

Del 1: Interface
Del 2: Streams och lambda expressions
Del 3: Metoder i Stream, metod- och konstruktorreferenser
Del 4: Metoder klassen Collectors
Del 5: Parallella strömmar
Del 6: Nyheter i Arrays

Referenser

[1] What's New in JDK 8

Bloggen i år och planer inför nästa år

2014-12-23

Året som gått

Det har varit ett roligt första bloggår för mig. Har skrivit ca 30 inlägg om varierande ämnen, som har det gemensamt att alla är datanördiga på något sätt. En del inlägg som till exempel mini-serien om Java 8, har varit planerade och andra mer oplanerade. Exempel på de senare är de inlägg jag gjort i kategorin Dagens lärdom. Tycker själv att det blivit en ganska bra mix. Retar mig lite på att bokrecensionerna har klumpat ihop sig lite. Får försöka att sprida ut dessa lite mer nästa år.

Just när det gäller böckerna har det varit ett bra år. Jag har läst ut 7 böcker (programmeringsrelaterade böcker alltså, det är ju bara de som räknas ;). Det är fler än jag mäktat med något annat år sedan dess jag blev pappa (och fick radikalt mycket mindre tid att disponera på läsning). Tycker att det fungerat väldigt bra att skriva en liten recension om varje bok. Föreställer mig att jag kommer ihåg innehållet lite bättre och har dessutom något att gå tillbaka till för en snabb repetition.

Rörande hobbyprojekten har det också gått ganska bra. Jag har kommit igång dels med bloggapplikationen och dels med matteappen. Får säga att jag är jättenöjt med att ha startat upp de två småprojekten. Speciellt roligt är att de, till skillnad från många av mina tidigare hobbyprojekt, verkligen används (om än inte av så många). Superkul!

Jag har någon liten halvhjärtad idé om att bredda mig lite när det gäller vilka programspråk jag kan då jag tycker att jag är lite för smal på den punkten. Kodar mest Java och Python, men vill gärna lära mig fler språk. I år gjorde jag en ansats att lära mig Groovy. Läste en bok och kodade lite små exempelprogram. Kan dock inte säga att jag kan Groovy speciellt bra. Får fortsätta med Groovy:andet nästa år. Har dessutom vissa planer på att lära mig fler språk. Se nedan...

Året som kommer

Vad har jag då för planer nästa år? Ja, angående utseendet på bloggen skall jag försöka hotta till det lite. När en kollega fick syn på bloggen första gången utbrast han något i stil med "Du har inte funderat på det här med färger?". He, he. Det är ju bara att hålla med. Så mycket färger finns det ju inte på den. Får se om jag får tummen ur och färgsätter den lite mer. Lite snyggare skall jag försöka göra den i alla fall.

En annan ändring jag har tänkt mig att göra är att börja skriva på engelska. Anledningen till det är att jag vill kunna nå ut till fler. Inte säkert det gör någon större skillnad, men man kan ju alltid prova.

Angående ämnen för blogginläggen då? Vad tänkter jag när det gäller dem? Jag har köpt böckerna Seven Languages in Seven Weeks och Seven More Languages in Seven Weeks. Dessa tänkte jag beta av under det första halvåret. Blir med andra ord "14 språk på 26 veckor" om den planen går i lås. Har tänkt skriva ett blogginlägg om varje språk; vad jag tycker om det, vilka egenheter det verkar ha, vilka utvecklingsmiljöer jag har provat och så vidare. Det blir nog ganska intensivt, men det borde också kunna bli roligt och lärorikt.

Jag har också köpt boken The Coding Dojo Handbook. I den finns en katalog med kodkata, vilka jag tänkte mig att pröva på att implementera i några av de språk som beskrivs i Seven LanguagesWeeks-böckerna. Tänkte börja med att skriva en grafisk klient som kan visa upp "världen" i Game of Life. Tanken är att skriva ett litet REST-interface till den med vilket man kan ange vilket tillstånd världen skall ha. På så sätt skulle jag kunna skriva program som "spelar" game of life och visar upp sitt tillstånd mha den grafiska klienten. Får se om jag hinner med det. Det vore roligt i alla fall.

Almas matteapp tänker jag fortsätta koda på i alla fall. Vi använder det flera gånger varje vecka för att träna matte. Nu har Alice börjat använda den så smått också, vilket är roligt. Just nu är det så att jag nästan inte hinner med att göra nya uppgifter i den takt som Alma gör klart de gamla (av de som är relevanta. Hon är inte riktigt på 12:ans gångertabell än...). Näst i pipen nu är divisionsuppgifter. Funderar även på att göra en digitalklocka så det går att göra uppgifter för att träna på den. Sen hade det varit kul att får tummen ur och göra appen tillräckligt färdig föra att kunna laddas upp på Play-butiken också. Tror dock att det är en del jobb med det. Speciellt jobbigt kan det nog vara att få appen att se OK ut i alla olika upplösningar. Vi får se om jag orkar med det eller inte.

Så, det var en liten genomgång av vad jag åstadkommit på hobbykodar-/blogg-fronten i år och vad jag har för planer inför nästa år. Om ett år år vi se hur väl de planerna slog in. Känner jag mig själv rätt kommer det säkert bli en del ändringar i dem. Det brukar ju aldrig gå som man har tänkt...

God Jul och Gott Nytt År!