środa, czerwca 23, 2010

O przydatność tabletu

OK, pisałem o czymś innym, ale nie skończyłem jeszcze, a już późno ;-)

No to teraz lista powodów dla których w moim przypadku tablet może się nie sprawdzić ;-)

Jednym z zastosowań tabletu jest czytanie, ja często czytam w 2 miejscach gdzie tablet nie ma racji bytu, w tramwaju [z racji małej ilości miejsca gdy się siedzi, tego że nie zawsze ma się siedzenie, jakieś tam obawy o to, że ktoś może się połaszczyć], w wannie [z racji wody ;-)]. Czyli na dzień dobry od 30 do może i 50% miejsc gdzie czytam książki odpada.
Kolejnym zastosowaniem jest granie, które mnie nie dotyczy bo po prostu nie gram :-)
Oglądanie filmów, nawet gdy pominiemy kłopotliwe pytanie skąd filmy, to jak już o wiele przyjemniej się ogląda film z DVD [który dla tabletu musiałby być zripowany i zakodowany] na telewizorze niż czymś takim.
Przeglądanie internetu, tak, tutaj jest miejsce. Tzn. chyba. Teraz z racji tego, że laptopa mam przypiętego milionem kabli USB i podobnych jest on raczej mało mobilny, Asus EEE jest bardziej mobilny, ale trzeba go włączyć, znaleźć miejsce na jego ułożenie i ogólnie jest kłopotliwy. Tak, tu tablet się może sprawdzić. Inna sprawa jak często bym go używał w takim ustawieniu? Raczej nie miałby niezależnego dostępu do sieci więc i tak musiałbym mieć laptopa włączonego [jako router] lub chociaż mieć router WiFi w pobliżu.

Na 4 możliwe miejsca zastosowania pasuje mi od 0.7 do 0.5 jednego [raczej 0.5 bo nawet jak w wannie i tramwaju czytam tylko przez 30% czasu czytania książek to i tak znaczyłoby to, że musiałbym czytać w danym momencie najmniej 2 książki, jedną wanniano-tramwajową drugą tabletową. Z przeglądania internetu myślę, że koło 70% przeglądania mógłbym robić na tablecie.

Czyli łącznie mam 1/4 punktu przydatności :-)

Co nie zmienia faktu, że jak będą w dobrych cenach tablety z Androidem to sobie pewnie kupię :-) [o iPadzie myślałem, ale jakoś za Apple nie przepadam i jak na razie jestem na nie, choć to się może zmienić]

Podobne postybeta
Nowa choroba ;-)
Nie rozumiem Microsoftu
A może by wrócić do używania Google Drive do przesyłania komunikatów między przeglądarkami?
Raport z emigracji ;-)
Historia +1

poniedziałek, czerwca 21, 2010

JRockit - początki dotykania się z ;-)

Nie wiem jak było wcześniej, ale teraz Oracle wydaje się oferować na swoich stronach już nie tylko standardową maszynę wirtualną Java'y czyli Sun HotSpot, ale również JRockit'a, czyli maszynę stworzoną przez BEA [albo kogoś kogo kupiła BEA] [OK, wcześniej sprzedawali BEA WebLogic, który używał JRockita, ale teraz wydaje się, że JRockita rozdają za darmo].JRockit jest podobno pozbawiony pewnych wad HotSpot'a, np. ma się w nim nie zdarzać ukochany przez wielu ;-) problem z PermGen'em, bywa też szybszy.Przychodzi też z zestawem pewnych dodatkowych dobrodziejstw.Skąd wiem? Jeden z kolegów z pracy [ale tych z USA] opisał na firmowym wiki JRockita :-) Praca miewa swoje plusy ;-)Ciekawie się integruje z systemem, "podpina" się pod normalną Java'ę i dodaje nowy przełącznik -jrockit [oraz podmienia funkcjonalność przełącznika -server, który staje się równoważny przełącznikowi -jrockit].


Podobne postybeta
Bea i miganie
HDMI-DVI - chyba nie widzę różnicy
Darmowy hosting JSP
Nieznane skarby JDK - JConsole :-)
OpenOffice.org i inne produkty Open Source - ofiary kryzysu? ;-)

niedziela, czerwca 20, 2010

Mniej wredne Google Docs ;-) - zabawy z OCRem część 2

Z dobrych wieści, już wiem czemu nie działało mi wrzucanie obrazków do OCRa w Google Docs :-)
Używałem złego mime type, zamiast poprawnego image/jpeg używałem image/jpg.
Co najlepsze rozważałem taki powód problemów, ale odrzuciłem go bo nie pasował mi komunikat otrzymywany od Google Docs. Kolejny już raz widać, że jak się ma wątpliwości to trzeba testować wszystkie dostępne opcje ;-)

I to by było tyle dobrego.

Eksperymenty polegające na tym, że robię zdjęcie moim G1, i wrzucam je do OCRa w Google Docs kończą się czymś co trudno nazwać sukcesem ;-)
List z Aurum który dostałem [znowu! pewnie znów im ich kryzysowy algorytm kazał wysłać list gdzie się da, a nóż ktoś się zgodzi płacić 16 złotych miesięcznie za konto ;-)] został rozpoznany jako dwie linijki tekstu [złego, ale tu wydaje się, że winą był język] jednego z nagłówków i cała reszta została zamieniona na czystą stronę ;-)
Znów pierwsza strona pierwszego rozdziału The Wisdom of Crowds została przerobiona na coś takiego [wklejam obrazek bo lepiej pokazuje ;-)]


oryginalny tekst na stronie wyglądał tak [z tym, że tutaj daję obrazek zmniejszony do rozmiarów 350x467, oryginał miał wymiary 1536x2048, gdzie pojedyncza wielka litera A miała ponad 50 punktów wysokości..... Google radzi OCRować teksty mające najmniej po 10 punktów na znak]:



Rezultaty nie są zbyt zadowalające :-)


Podobne postybeta
Wredne Google Docs
Rama... coś nie działa ;-)
Android + Google Docs OCR = zestaw dla szpiega? ;-)
Kryzysowy, pokręcony algorytm? ;-)
Android + OCR, to zaczyna działać ;-)

czwartek, czerwca 17, 2010

Wredne Google Docs

Próbuję powołać do życia zabawkę, która pozwoli robić zdjęcia telefonem Androidowym jakiemuś tekstowi, wrzucać to do Google Docs, OCRować przez Google Docs i zwracać do telefonu jako tekst.

Wg. teorii przedstawionej w dokumentacji Google Docs List API to powinien być pikuś.
Trzeba się zalogować, później zaś użyć adresu:

https://docs.google.com/feeds/default/private/full?ocr=true

do zuploadowania pliku z obrazkiem i voila! wszystko powinno działać.

Ale nie działa. Dostaję od serwera błąd 403, z wyjaśnieniem, że nie mam prawa do korzystania z danego zasobu. Ale gdy korzystam z Google'owego przykładu, który działa jako aplikacja webowa to OCR działa dla każdego z moich kont.

Czyżby chodziło więc o to, że moja aplikacja używa autoryzacji ClientLogin?

Nie wiem. Z Google Docs List API jest taki problem, że to jest nadal beta (dokładniej jest w laboratorium] i nie zawsze wszystko działa tak jak powinno, dlatego nie mogę być pewny tego, że np. za chwilę wszystko jednak nie zacznie działać.
Np. okazuje się, że od momentu wprowadzenia nowego edytora do Google Docs nie działa eksport plików przez API. Ktoś w Google nad tym pracuje, ale jak na razie nie ma rozwiązania, a patrząc na wątki na forum i w bug trackerze to można momentami mieć wrażenie, że nie wiadomo do końca właściwie czemu to nie działa ;-)

Tak jakby kogoś interesowało to tutaj łopatologiczny i niezbyt ładny, ale działający sposób na logowanie do Google Docs [części związanej z dokumentami tekstowymi i prezentacjami, czyli do writely, z informacją, że logująca się aplikacja zowie się RMK-OCRDroid-0.01]:
URL url = new URL("https://www.google.com/accounts/ClientLogin");
HttpURLConnection connection = (HttpURLConnection) url.openConnection();
connection.setRequestMethod("POST");
connection.setAllowUserInteraction(true);
connection.setRequestProperty("Content-type", "application/x-www-form-urlencoded");
connection.setDoOutput(true);
connection.connect();
OutputStream os = connection.getOutputStream();
BufferedWriter bw = new BufferedWriter(new OutputStreamWriter(os));
bw.write("\r\naccountType=HOSTED_OR_GOOGLE&Email="+email+"&Passwd="+password+"&service=writely&source=RMK-OCRDroid-0.01\r\n");
bw.flush();
InputStream is = connection.getInputStream();
BufferedReader br = new BufferedReader(new InputStreamReader(is));
String line = "";
String auth = "";
while ((line=br.readLine())!=null) {
System.out.println(line);
if (line.startsWith("Auth=")) {
auth = line.replace("Auth=", "");
System.out.println("!"+auth);
}
}

To co wyżej zwykle lepiej zrobić przy pomocy bibliotek dostarczonych przez Google, ale ponieważ dla mnie okazało się prostszym i szybszym napisanie własnego kodu do kontaktów z Google Docs List API niż zrozumienie jak działa wersja bibliotek dla Androida, to przedstawiam jak zrobić to logowanie ręcznie :-)

Upload obrazka do OCRa robię w taki sposób [zakładam, że obrazek jest w lokalizacji E:\Projects\BLOG\OCRTest.jpg]:
String uploadUrlStr = "https://docs.google.com/feeds/default/private/full?ocr=true";

URL uploadUrl = new URL(uploadUrlStr);

HttpURLConnection conn = (HttpURLConnection)uploadUrl.openConnection();

conn.setRequestMethod("POST");
conn.setRequestProperty("Authorization", "GoogleLogin auth="+auth);
conn.setRequestProperty("GData-Version", "3.0");
conn.setRequestProperty("Content-Type", "image/jpg");
conn.setRequestProperty("Slug", "OCRd Doc");
String sourceFileName = "e:\\projects\\blog\\OCRtest.jpg";
FileInputStream fis = new FileInputStream(sourceFileName);
ByteArrayOutputStream baos = new ByteArrayOutputStream();

long contentLength = getStream(fis,baos);
conn.setRequestProperty("Content-Length", ""+contentLength);

conn.setDoOutput(true);
conn.connect();

conn.getOutputStream().write(baos.toByteArray());
conn.getOutputStream().flush();
conn.getOutputStream().close();

BufferedReader br2 = new BufferedReader(new InputStreamReader(conn.getInputStream()));
String line2 = "";
while ((line2=br2.readLine())!=null) {
System.out.println(line2);
}

gdzie metoda int getStream(InputStream,OutputStream) jest podejrzanie podobna do tej :-)
I na koniec dostaję info o błędzie 403 :-(


Podobne postybeta
Toperz ;-) czyli OCR + Android odsłona 2 albo któraś tam
Programowanie trudne ;-)
PROPFIND, czyli jak przechytrzyć HttpURLConnection
Wysyłamy pliki do Google Docs przy pomocy Go :-)
Chrome OS, Chrome2Chrome i w ogóle Chrome ;-)

wtorek, czerwca 15, 2010

No i mamy wyrok

Wiele osób cieszy się z wyroku Trybunału w Strasburgu, który uznał, że Polska łamie prawa człowieka nie zapewniając lekcji etyki uczniom, którzy byliby nimi zainteresowani.Ja mam mieszane uczucia.Już w tamtym roku minister Hall przebąkiwała [chyba zresztą w związku ze sprawą w której był dzisiejszy wyrok, oraz w związku z wliczaniem religii do średniej], że docelowo chce by religia lub etyka były przedmiotami obowiązkowymi.Ktoś może zakrzyknąć "hurra!", ale takie rozwiązanie ma dwie wady.Problem pierwszy to brak nauczycieli, prawie ich nie ma, problem można rozwiązać albo przez spędzanie różnych uczniów zainteresowanych etyką z kilku szkół w jedno miejsce, albo przez obejście minimalnej liczby uczniów i prowadzenie dla nich lekcji w każdej szkole, oczywiście w takiej porze by uczniowie z kilku klas mogli tam pójść, co oznacza zapewne okienka albo podobne udogodnienia. Ale to jeszcze nie jest takie straszne, choć niejeden uczeń mając do wyboru takie uroki, a pójście na religię i udawanie, że go to interesuje wybierze to drugie rozwiązanie [jego prawo, jak tak chce to niech tak robi], poważniejszym problemem jest to, że może dojść do sytuacji, że uczeń niewierzący lub innowierca będzie mieć lekcje etyki z katechetą. Do uczenia etyki "wystarczy" ktoś kto skończył filozofię, a że będzie to filozofia katolicka? Szczegół, papier jest papier, podkładka będzie. O uczniów ateistów się nie obawiam, przeżyją coś takiego, bardziej obawiam się o uczniów innowierców, którzy mogą dostawać sprzeczne sygnały. No i potencjalnie będzie to też kolejny kanał drenażu budżetu, katecheci już są finansowani z budżetu, teraz będą mogli dostać dodatki za bycie jeszcze nauczycielami etyki.Abstrahując od tego wszystkiego co wyżej o sposobie organizacji etyki, pozostaje pytanie po co w ogóle lekcje etyki w szkole?Że nauczy uczniów etycznego podejścia do życia? To ilu etyków pamięta który kraj na świecie jest największym producentem boksytów na świecie, co to są te boksyty, i np. pamięta co to jest siła Coriolisa? I ilu z nich potrafi tą wiedzę zastosować w życiu?Zgaduję, że niewielu. Skąd więc wiara, że nauka etyki w szkole coś zmieni?Raczej będzie to przechowalnia dla tych absolwentów filozofii, którzy nie mieli zdolności by znaleźć jakąś inną pracę.


Podobne postybeta
Ateizm to nie nihilizm i jak sprawić by prymas był apostatą ;-)
Bio"etyka"
Skąd się biorą źli i dobrzy nauczyciele? - Przemkowa teoria ;-)
Nie dla etyki czy religii.
Trybunał zdecydował.

wtorek, czerwca 08, 2010

Opowieść o małym n ;-)

Wielu się może nie zgodzić, ale powszechna prawda w programowaniu mówi "proste algorytmy działają dobrze dla małych n, a zwykle mamy do czynienia z małymi n". Wniosek jest taki, że w 80 czy nawet 90% (a nawet 99%) przypadków najbardziej prosty i banalny algorytm działa całkowicie znośnie.Problemy zaczynają się gdy wchodzimy w ten obszar, w którym n bywa już większe.Szczęście w nieszczęściu jest takie, że większość programistów nigdy dużych n nie widzi. Co czasem może boleć ;-)Można się o tym przekonać bawiąc się w rozwiązywanie zadań z Google Code Jam ;-)Mają po 2 zestawy danych, mały i duży. Na małym zestawie danych naiwne algorytmy działają praktycznie zawsze, na dużym do czasu ;-)W TopCoder zwykle naiwny algorytm wystarcza.Dlatego czasem przydałoby się kilka prostych tricków w języku ;-)Np. mamy taki kod:
 static long factorial(long l) {  return (l>1)?l*factorial(l-1):1; }
Czyż nie byłoby miło gdyby dało się powiedzieć Java'ie "jeżeli ta funkcja wołana była już z danym parametrem to po prostu zwróć jej obliczoną wcześniej wartość".Np. definicja takiej funkcji mogłaby wyglądać tak:
 static cached long factorial(long l) {  return (l>1)?l*factorial(l-1):1; }
albo jakoś podobnie ;-)Wtedy powyższy kod mógłby zostać zamieniony w coś takiego:
 static Map factorial = new HashMap();  static long factorial(long l) {    Long result = factorial.get(l);  if (result==null) {   result=(l>1)?l*factorial(l-1):1;   factorial.put(l, result);  }  return result; }
Zawsze by to choć trochę prościej było ;-)Chociaż z drugiej strony takie coś miałoby też swoje wady. Java ma tą miłą właściwość, że język nie próbuje być mądrzejszy od developera w tym sensie, że nie generuje sobie na boku żadnego ogólnie dostępnego kodu [OK, generuje np. metody do trzymania związku między klasą wewnętrzną, a zewnętrzną, ale to co innego]. Nie ma np. właściwości więc developer pisząc obiekt.pole=10 wie, że po prostu pisze do jakiegoś pola [i popełnia grzech śmiertelny, ale to akurat szczegół ;-)], ale nie woła żadnego kodu w Java'ie.To powoduje, że mniej jest magicznych zależności, a to też ułatwia ;-)Ale mimo wszystko, przydałyby się czasem takie czary ;-)O! albo dodatkowy konstruktor dla wszystkich typów implementujących Map, dla takiej HashMap'y mógłby wyglądać tak new HashMap("toster"), który inicializowałby nową HashMap'ę, która dla get(key) w momencie gdy dany klucz nie miałby wartości zwracałaby tą domyślną wartość przekazaną w konstruktorze :-)Albo chociaż dodatkową metodę get(key,defaultValue) :-)Chociaż tu by mieli problem podobny do tego co się dzieje z JDBC w Java 6. Zmienili interface i nie wystarczy przekompilować starego kodu przy pomocy nowej Java'y :-(To może nowy interface MapWithDefaultValue z jedną metodą get(key,defaultValue), którą implementowałyby wszystkie domyślne mapy? ;-)Dodanie takich cosiów [tak naprawdę głównie tego pierwszego] pewnie by o trochę problem dużych n troszkę odsuwało ;-)

Podobne postybeta
Algorytmy Genetyczne szukają Symbolu Newtona ;-)
Prawdziwy narodowo-katolicki patriota i prawdziwy żydokomunista - opis wzorców
Jak z metody size() w List w Java'ie dostać ujemną liczbę? ;-)
Modale nie takie dobre dla Androida ;-)
Refleksje i serializacja w Java'ie - podstawy i obalanie mitów ;-)

poniedziałek, czerwca 07, 2010

O tym dlaczemu Java'owcy powinni kochać Androida :-)

TIOBE nadal pokazuje, że Java jest najpopularniejszym językiem świata [choć wg. mnie przecenia też C i nie docenia C# i JavaScript], ale tendencja jest taka, że Java'ie ubywa.I tu wchodzi Android. Dla którego Java jest podstawowym językiem pisania aplikacji :-)Co prawda nie jest to ani Java ME, ani Java SE, a nawet środowiskiem uruchomieniowym nie jest Java jako taka, a maszyn Dalvika.Ale nadal językiem jest Java.A, że Android jest obecnie 2 lub 3 pod względem popularności systemem operacyjnym na komórki to daje to Java'ie potężnego kopa. Już wkrótce powinniśmy zostać zalani hordami tabletów na Androidzie, a to otworzy kolejne możliwe pola wykorzystania Java'y :-)Jedynym minusem jest konieczność przestawienia się na Androidowy sposób patrzenia na świat, z czym można mieć problemy ;-) [sam mam].Ale równanie jest proste, im więcej Androida na komórkach i tabletach, im są one popularniejsze tym Java dostaje większy udział w rynku :-)Dlatego Java'owcze i Java'owczyni, jeśli chcesz by Java rosła w siłę pomyśl o tym by Twoja następna komórka miała Androida :-)I to by było na tyle ;-)


Podobne postybeta
JIT i Apps2SD, dwie rzeczy które mogłyby rewitalizować G1
Sarkania na C++
Zaskakujący killer feature....
Chciałbym Chromebooka
4 małpki z trojgiem rodziców :-)

sobota, czerwca 05, 2010

ETA - liczymy szacowany czas zakończenia [przybycia ;-)]

Bardzo prosta sztuczka programistyczna, prawdę mówiąc nawet nie sztuczka. Każdy z nas wie jak to liczyć, ale nie zawsze wie to "od strzału".Mamy jakieś obliczenia do wykonania, jakieś czasochłonne operacje, cokolwiek. Jeżeli wiemy ile tych operacji musimy wykonać możemy pokusić się o podanie użytkownikowi szacowanego czasu zakończenia.To proste. Mamy N operacji do wykonania, wykonaliśmy jak na razie count operacji, co zajęło nam time czasu.Wtedy cały czas zadania to około:
T=N/count*time
wyrażone w jednostkach czasu.Czyli jeżeli mamy wykonać 530 operacji, z czego 128 zajęło nam 67 sekund to wiemy, że cały proces powinien zająć około 261 sekund = 4 minuty i 21 sekund.Możemy więc użytkownikowi napisać, że zadanie zostanie zakończone za około T sekund, minut, whatever. Lub, że szacowany czas zakończenia operacji to:
Tzakończenia=Taktualny+(N/count-1)*time
Na koniec informacja jak tego użyć w Java'ie ;-) N to wartość liczba wszystkich iteracji, count to numer aktualnej iteracji.
long start = System.currentTimeMillis(); // czas rozpoczęcia[...]double t = (double)N/count*(System.currentTimeMillis()-start);Calendar cal = Calendar.getInstance();cal.add(Calendar.SECOND, (int)(t/1000));System.out.println(cal.getTime()+" "+t);
Na koniec jeszcze uwaga, że gdy mamy naprawdę dużo operacji to bez sensu jest za każdym razem wszystko wyliczać, wtedy można co 10, 100, 1000 czy dowolną inną liczbę iteracji zrobić wyliczenia. Można też je robić co zadany interwał.


Podobne postybeta
SleepAdvisor - komórka pomaga w wyspaniu się ;-)
Chyba najtrudniejszy komponent UI - pasek postępu ;-)
Google App Engine i DatastoreTimeoutException
Kiedy skończyć pracę...
Plus dla Scala, minus dla Groovy ;-)

czwartek, czerwca 03, 2010

Liczymy książki ;-)

Ha! Mam od 15 do 18.5% z wszystkich książek w moim domu :-) Tzn. moje książki tyle stanowią z całości :-)Tych moich jest tak koło 600 sztuk [w moim pokoju w domu naliczyłem jakieś 450-500, w Krakowie też mam koło 100-150, a jeszcze w domu w innych pokojach się moje książki ukrywają wśród "rodzinnych"]. Wszystkich książek jest tak wg. szacunków od 3200 do 4000 sztuk. Trochę mnie zaskoczyło, że w jednej półce, tej widocznej na zdjęciu jest ponad 100 książek...... jakby miał oceniać bez liczenia to bym powiedział, że o połowę mniej.W tematyce książek jestem dość jednostajny. Głównie SF lub Pratchett, czasem fantasy, do tego trochę popularnonaukowych, masa niestety komputerowych [z czego najstarsza jest o C64 :-)], Pana Samochodzika też liczę jako moje książki :-) Chmielewska jest w zasobie książek wspólnych.Co mnie tak wzięło na liczenie? Po prostu jakiś czas temu rozmawiałem o tym z koleżanką i tak chciałem sprawdzić ile tych książek mam. Myślałem, że ciut mniej. Ale teraz rozumiem czemu nie mam gdzie kłaść książek ;-)Aż strach pomyśleć co mają ludzie, którzy mają naprawdę dużo książek.Co do stopnia przeczytania moich książek, to najmniej przeczytane są książki o komputerach, mało którą przeczytałem od deski do deski. Niestety taki urok tego typu wydawnictw. Najbardziej "wyczytane" są książki Clarke'a i Pratchett'a :-) No po prostu je lubię.

Podobne postybeta
clone() i Cloneable się mszczą ;-)
Żyjemy w trzecim świecie...
Allegro to jest banda amatorów.
Galileoskopy w Polsce
Statystyki Android Marketu mijają się ciut z prawdą ;-)

Książeczki :-)

Kolejna dostawa ;-)Zwróćcie uwagę na dwie książki z prawej strony, ta u góry to wersja angielska [której zdjęcie i krótki opis już kiedyś przedstawiłem ;-)], a dolna to polskie wydanie. Cieszy to, że Prószyński zdecydował się zrobić jak w przypadku oryginału, i mamy do wyboru 2 okładki, czarną i białą. Ponieważ oryginał mam biały to polskie tłumaczenie kupiłem czarne :-)Co do jakości tłumaczenie to trudno się wypowiadać, czytając oryginał można mieć wrażenie, że Pullman stara się trzymać gdy to możliwe stylu ewangelii [ale trzeba brać poprawkę, że nie czytałem ich po angielsku [po polsku tylko liznąłem] i po prostu mogę źle to interpretować], a tłumaczenie też się stara, ale jakby mniej skutecznie.Ale sama idea opowieści, czyli Jezus i Chrystus jako bracia bliźniacy [z których "tylko" Chrystus jest mesjaszem i wbrew tytułowi to on też wydaje się być milszy] jest ważna :-)W ogóle co do Pullmana to mam wrażenie, że pisze jakoś tak, że tłumacze mają problem ze złapaniem prawidłowego stylu. Podobnie było w Mrocznych materiach, oryginał jakby lepiej "wchodził" i "mniej szarpał".


Podobne postybeta
Now książki "na kolejce"
Książki, książeczki, książunie ;-)
Czemu oglądam filmy i seriale po angielsku z napisami po angielsku
Oko czasu
Dzień Darwina