wtorek, listopada 16, 2010

Wszystkiemu winne są szybkie komputery ;-)

Tak mi właśnie wyszło, że posiadanie komputera z szybkim kompilatorem przeszkadza w zostaniu dobrym programistą ;-)

Dlaczego? :-)

Bo prowadzi do tego, że człowiek zaczyna pisać przez przybliżenia.

Szybko pisze pierwszą wersję kodu, która nie działa tak jak powinna, bo np. przekształcając dwie tablice int[] z początkami i końcami pewnych odcinków w listę "fragmentów" napisze się coś takiego:

public int method(int[] start, int[] end) {
class Fragment { int s; int e; }
List<Fragment> list = new ArrayList<Fragment>();
for (int i=0; i<start.length; i++) {
Fragment f = new Fragment();
f.s = start[i];
f.e = end[i];
}


Gdzie później się używa tej listy list... i kod nie działa ;-)

Czemu? :-)

Bo oczywiście zapomniało się o tak nieistotnym działaniu jak dodanie tego nowego Fragmentu f do listy :-)

Kod zmienić trzeba w:

public int method(int[] start, int[] end) {
class Fragment { int s; int e; }
List<Fragment> list = new ArrayList<Fragment>();
for (int i=0; i<start.length; i++) {
Fragment f = new Fragment();
f.s = start[i];
f.e = end[i];
list.add(f); /// TUTAJ!!!!
}


Oczywiście za skarby świata nie wpada się na to od razu, za to najpierw dodaje się gdzieś debuga, kompiluje kod, odpala i dopiero jak nic nie widać w debugu to zaczyna się patrzeć wcześniej... i często jeszcze przed zauważeniem tej sprawy z list.add(f) wypisuje się wielkość listy :-)

Chociaż jest tu pewien paradoks. Bo można było napisać na początku kod tak:

public int method(int[] start, int[] end) {
class Fragment { int s; int e; }
List<Fragment> list = new ArrayList<Fragment>();
for (int i=0; i<start.length; i++) {
Fragment f = new Fragment();
f.s = start[i];
f.e = end[i];
//list.add(f); /// bez tej linii :-)
}
System.out.println(list.size());


Uruchomić i od razu byłoby widać, że zapominamy dodawać ef do listy.

Ale jakoś nie zawsze się zdarza akurat w tym momencie odpalić. (a czasem nie można, bo akurat to wyżej to z mojego rozwiązania zadania z TopCoder, zresztą o tyle ciekawego, że był tam też inny błąd, a przeszło wszystkie testy ;-))

Pamiętam jeszcze z czasów Pascala, a jeszcze wcześniej Basica na C64 [btw. czasem się zastanawiam jak wtedy mogłem coś pisać... przecież teraz Eclipse od razu podkreśla wszystkie błędy syntaktyczne, a kiedyś trzeba było pisać wszystko z palca i dopiero kompilacja wskazywała, że w linii takiej i takiej jest błąd, a w Basicu na C64 było jeszcze gorzej, bo błąd pojawiał się z tego co pamiętam dopiero gdy interpreter dotarł do tej linii :-)], że zwykle takie głupie błędy się nie zdarzały.
Bo trzeba było program skompilować, wtedy mogły polecieć błędy i dopiero później testować, a to wszystko zabierało czas więc się chyba bardziej uważało :-)
A teraz jak w Eclipse'ie kompilacja odbywa się z tyłu tak, że o tym nawet nie wiemy, wszystkie błędy syntaktyczne są podkreślane w locie, a uruchomienie programu to błysk ciupagi to się testuje czy program robi to co powinien, a dopiero jak nie robi to się patrzy na kod.

Tak btw. mogliby w Java'ie "zjednoczyć" listy i tablice bo cholery można dostać przy konwersji. Niby są metody toArray() i asList(), ale jakoś zwykle i tak trzeba robić konwersję ręcznie bo np. mamy taki kaprys by modyfikować listę, albo zmieniać wartości gdy chcemy zachować oryginalne w oryginalnej strukturze. Albo jakieś takie milsze konstruktory.


Podobne postybeta
Zdradliwa Java i 8 królowych ;-)
Zrównoleglamy ;-)
Niecne wykorzystanie refleksji... czyli jak poszukać tekstu w drzewie obiektów? ;-)
Java 8 nadchodzi....
Spectre powinno działać nawet w Java'ie ;-)

2 komentarze:

  1. Jest jeszcze jedno rozwiązanie, nawet lepsze od Sysout na końcu kodu.

    napisać test do tego kodu, najlepiej jeszcze zanim zaczniesz pisać implementację. TDD zwłaszcza przy problemach 'algorytmicznych' to świetny sposób na zapewnienie poprawności działania.

    OdpowiedzUsuń
  2. @Tomasz - jak masz czas ;-) i możliwości.
    W TopCoder masz edytor do pisania kodu i powinno się w nim pisać, a każde uruchomienie czy nawet kompilacja wydają się wpływać na Twoją ocenę.
    Do tego pisanie testu zabiera czas. No i test przetestuje Ci cały program, a ten błąd tutaj był jeszcze przed podejściem do rozwiązywania problemu, tu chodziło tylko o przekształcenie danych do bardziej wygodnego formatu.

    OdpowiedzUsuń