JAVA - ROTFL
wtorek, 30 czerwiec 2009 | Etykiety: Java, Rozrywka | 5 komentarze »
Jedne języki są bardziej intuicyjne, inne mniej. Przykładem takiego nieintuicyjnego zachowania jest porównywanie operatorem == C-stringów. Ten przykład znają wszyscy, a na forach raz w miesiącu jest o tym wątek ;-)
Przyszło mi do głowy, żeby napisać taki Javovy "rozbrajacz". Oto co wykombinowałem:
O co chodzi pozostawiam do własnej analizy (raczej proste).
Hint 1: Używamy Integer, a nie int (to dość istotne).
Hint 2: Czym różni się operator == od metody equals?
Przyszło mi do głowy, żeby napisać taki Javovy "rozbrajacz". Oto co wykombinowałem:
Integer a = 1000;Zapytasz: "i co?". Odpowiadam: Z dużym prawdopodobieństwem (optymalizacje wg VM mogą wszystko zepsuć :-/) pierwszy test zwróci false, a drugi true (to akurat jest pewne).
Integer b = 1000;
System.out.println("a == b (1000 == 1000): " + (a == b));
Integer aa = 100;
Integer bb = 100;
System.out.println("aa == bb (100 == 100): " + (aa == bb));
O co chodzi pozostawiam do własnej analizy (raczej proste).
Hint 1: Używamy Integer, a nie int (to dość istotne).
Hint 2: Czym różni się operator == od metody equals?
Jak pisać elastyczny soft "by example"
poniedziałek, 8 czerwiec 2009 | Etykiety: GNU/Emacs | 0 komentarze »
W internecie można znaleźć wiele ciekawych porad na temat tego jak programować, aby "było dobrze" i w "słuszny" sposób. Większość to bełkot, ale znajdą się też perełki. Moim zdaniem do takich należy ten film...
http://www.vimeo.com/1013263
Jest na przykładzie GNU/Emacsa - konkretnie modułu ido-mode. Sam moduł nie jest tu najważniejszy, ale pewna "dobra praktyka", którą autor próbuje przekazać - IMO skutecznie. Nie należy spodziewać się czegoś bardzo odkrywczego. Prosta prawda, którą łatwo odkryć, a prawie nikt jej nie stosuje (przynajmniej patrząc na ograniczenia współczesnych aplikacji).
ido-mode - początkowo ciężko się przyzwyczaić (godzina/dwie). Po miesiącu nie wyobrażałem sobie wyłączenia go (i nadal tak jest). Eksperymenty z nowymi narzędziami to podstawa... . A filmik znalazłem szukając w necie ciekawych zastosowań ido.
http://www.vimeo.com/1013263
Jest na przykładzie GNU/Emacsa - konkretnie modułu ido-mode. Sam moduł nie jest tu najważniejszy, ale pewna "dobra praktyka", którą autor próbuje przekazać - IMO skutecznie. Nie należy spodziewać się czegoś bardzo odkrywczego. Prosta prawda, którą łatwo odkryć, a prawie nikt jej nie stosuje (przynajmniej patrząc na ograniczenia współczesnych aplikacji).
ido-mode - początkowo ciężko się przyzwyczaić (godzina/dwie). Po miesiącu nie wyobrażałem sobie wyłączenia go (i nadal tak jest). Eksperymenty z nowymi narzędziami to podstawa... . A filmik znalazłem szukając w necie ciekawych zastosowań ido.
A czy Ty masz moc super krowy?
poniedziałek, 1 czerwiec 2009 | Etykiety: Linuks, Rozrywka | 1 komentarze »
Instalacja programów przez konsolowego zarządcę pakietów ma wiele zalet - jedną z nich jest to, że można się czasami pośmiać. Zawsze podobał mi się napis "Ten aptitude nie posiada Mocy Super Krowy" gdy omyłkowo wpisałem błędny parametr do aptitude. Ale dlaczego akurat taki tekst?
Aby się dowiedzieć trzeba wrócić do źródeł. Aptitude to program, który jest następnikiem apt-get. Gdy przeczytamy dokumentację apt-get (apt-get --help) zobaczymy "Ten APT ma moce Super Krowy". Ładny easter egg pojawia się gdy wpiszemy apt-get moo. Widać wtedy ASCII-krowę ;-) Poniżej niej jest napis "Have you mooed today?".
Ta sztuczka działa też z aptitude - tyle, że jest wtedy informacja, że w aptitude nie ma easter eggs.
Jak się właśnie przekonałem - nie warto wierzyć twórcom aptitude. W aptitude jest easter egg ;-D Jaki? Znalezienie go pozostawiam jako proste ćwiczenie (przez google się nie liczy ;-P)
Aby się dowiedzieć trzeba wrócić do źródeł. Aptitude to program, który jest następnikiem apt-get. Gdy przeczytamy dokumentację apt-get (apt-get --help) zobaczymy "Ten APT ma moce Super Krowy". Ładny easter egg pojawia się gdy wpiszemy apt-get moo. Widać wtedy ASCII-krowę ;-) Poniżej niej jest napis "Have you mooed today?".
Ta sztuczka działa też z aptitude - tyle, że jest wtedy informacja, że w aptitude nie ma easter eggs.
Jak się właśnie przekonałem - nie warto wierzyć twórcom aptitude. W aptitude jest easter egg ;-D Jaki? Znalezienie go pozostawiam jako proste ćwiczenie (przez google się nie liczy ;-P)
Rekursywne przeglądanie katalogów
piątek, 29 maj 2009 | Etykiety: C++, QuickTips | 0 komentarze »
Konieczność przeglądania katalogów w C++ zdarza się raczej rzadko. Zazwyczaj programy, które muszą robić coś tego typu są skryptami ułatwiającymi pracę, czy tworzącymi masowe zmiany w plikach. Sam wolę w takim wypadku użyć jakiegoś języka skryptowego - np. Perla. Tym razem okazało się, że potrzebuję rekursywnie przeszukać katalog w C++ i...
Ku mojemu zdziwieniu okazało się to dziecinnie proste. Od razu planowałem użyć boost::filesystem, aby uniknąć problemów z różnicami w systemach plików (zapewnić sobie przynajmniej minimalną portowalność rozwiązania). Byłem przekonany, że bez rekursji się nie obejdzie. Nic bardziej mylnego. Biblioteka boost::filesystem wykonała całą pracę za mnie! Jest w niej zdefiniowany iterator, który przegląda katalog rekursywnie. Interfejs nie odbiega od iteratorów, które są obecne w STL (np. std::istream_iterator).
Dość gadania. Aby przeszukać katalog tmp w poszukiwaniu plików wystarczy napisać:
Wynik jest równoważny wykonaniu polecenia
Ku mojemu zdziwieniu okazało się to dziecinnie proste. Od razu planowałem użyć boost::filesystem, aby uniknąć problemów z różnicami w systemach plików (zapewnić sobie przynajmniej minimalną portowalność rozwiązania). Byłem przekonany, że bez rekursji się nie obejdzie. Nic bardziej mylnego. Biblioteka boost::filesystem wykonała całą pracę za mnie! Jest w niej zdefiniowany iterator, który przegląda katalog rekursywnie. Interfejs nie odbiega od iteratorów, które są obecne w STL (np. std::istream_iterator).
Dość gadania. Aby przeszukać katalog tmp w poszukiwaniu plików wystarczy napisać:
Jak widać nic prostszego. Używamy dwóch konstruktorów recursive_directory_iterator. Pierwszy przyjmuje jako argument ścieżkę - tam zaczniemy szukać. Drugi nie przyjmuje argumentów i oznacza element "zaostatni" - zgodnie z konwencją STLa. Potem prosta pętelka wypisująca nazwy plików.
#include <string>
#include <iostream>
#include <boost/filesystem.hpp>
int main() {
namespace fs = boost::filesystem;
fs::path path("/tmp");
fs::recursive_directory_iterator it(path);
fs::recursive_directory_iterator end;
for ( ; it != end; ++it) {
if (fs::is_regular(it->status()))
std::cout << it->path() << "\n";
}
}
Wynik jest równoważny wykonaniu polecenia
find /tmp -type fNie rozumiem tylko, dlaczego w dokumentacji jest przykład, który pokazuje jak to zrobić używając rekurencji jawnie.
Wygodne wyszukiwanie
środa, 20 maj 2009 | Etykiety: GNU/Emacs, Narzędzia, QuickTips | 0 komentarze »
W przypadku wielu edytorów używa się opcji szukania gdy chce się znaleźć jakiś fragment. W GNU/Emacsie jest jeszcze jedno zastosowanie - poruszanie się po tekście. Często o wiele szybciej jest użyć opcji szukaj niż przejechać kursorem w odpowiednie miejsce (o przesuwaniu ręki na gryzonia, machaniu nim i kilkaniu w odpowiednim miejscu już nie wspominając). Od dłuższego czasu mocno wykorzustuję isearch, ale ostatnio przeczytałem pomoc do isearch i poznałem parę nowych sztuczek. Te nowe i większość starszych zastosowań postanowiłem opisać.
Incremental search
isearch zawsze wydawało mi się potężnym narzędziem - tak naprawdę jest to tylko mechanizm wyszukiwania. Jest podobny do tego we współczesnych przeglądarkach, to znaczy że tekst jest wyszukiwany już w czasie pisania zapytania (kawałek, który się da znaleźć). W GNU/Emacsie można szukać w przód (C-s) lub w tył (C-r). Aby przejść do drugiego dopasowania wystarczy powtórzyć C-s lub C-r, przy czym w trakcie wyszukiwania w przód można uzyć C-r aby wyszukać w tył i odwrotnie.
Podstawy isearch
Napisałem już jak zacząć wyszukiwać, ale co dalej? Gdy już kursor znajdzie się w odpowiednim miejscu wystarczy nacisnąć enter (RET) aby zakończyć wyszukiwanie. Jeżeli natomiast wyniki nas nie satysfakcjonują (lub chcieliśmy tylko sprawdzić czy fraza występuje) to używamy C-g (jak zawsze do kasowania aktualnej akcji) aby powrócić do miejsca, z którego zaczęliśmy.
Modyfikacja wyszukiwanej frazy
Jedną z bardziej przydatnych opcji jest * znana z vim-a. Załóżmy, że stoimy kursorem przed pewnym słowem i chcemy poszukać tego słowa w tekście. Oczywiście nie musimy go kopiować (ani przepisywać). Wystarczy C-s (włącz isearch), a następnie C-w (dodaj następne słowo do wyszukiwania). Użycie C-w kilka razy spowoduje dodawanie kolejnych słów. Podbnie jest z C-y, tyle, że tu dodajemy całą linię od miejsca, w którym jest kursor. W tej grupie jest jeszcze M-y, które dodaje do isearch ostatnio usunięty (wycięty) tekst, ale to raczej mało przydatne. Najlepsze jest to, że w każdej chwili możemy wyedytować ręcznie wyszukiwany tekst, bo M-e przenosi nas do edycji szukanej frazy.
Dopasowanie niestandardowych znaków
Bardzo pomocne jest dopasowanie końca linii przy pomocy C-j. Nieco rzadziej potrzebujemy wyszukać np. ^M (to nie są dwa znaki, tylko jeden - zapisany w ten sposób. GNU/Emacs pokoloruje taką sekwencję, aby ją odróżnić od tekstu). Aby to uczynić można wykorzystać C-q, które robi "quote" na następnym znaku - w naszym przypadku potrzebujemy C-qC-m
Historia
Do "wspomagaczy" można także zaliczyć historię z autouzupełnianiem. Możemy iść w tył M-p, w przód M-n i dopełniać TABem. Jeżeli z jakiegoś powodu przerwiemy wyszukiwanie to możemy je wznowić. Wystarczy C-s - wtedy wyszukujemy pustego ciągu, powtórzenie C-s spowoduje wyszukanie ostatnio wyszukanego ciągu (czyli zatwierdzonego, usunięte przez C-g wyszukiwania nie są brane pod uwagę).
Wielkość liter
Domyślne zachowanie GNU/Emacsa jest bardzo ciekawe. Jeżeli wpisujemy tylko małe litery to wyszukiwanie jest BEZ rozróżniania wielkości liter. W przypadku napisania przynajmniej jednej wielkiej litery przechodzimy w tryb, w którym wielkość liter ma znaczenie. Aby w trakcie wyszukiwania przełączyć znaczenie wielkości liter można użyć M-c.
Wyrażenia regularne
Nic szczególnego, ale warto o tym wspomnieć. M-r przełącza między trybem zwykłego wyszukiwania i wyszukiwania przy pomocy wyrażeń regularnych (który można też włączyć od razu C-M-s lub C-M-r). Czasami się przydaje, ale zazwyczaj wiemy wcześniej czy będzie potrzebne wyrażenie regularne czy nie.
Podmiana
Do opcji "znajdź" często w pakiecie jest też "zamień" (jeżeli nie ma tego w Twoim edytorze, to go szybko zmień). W GNU/Emacsie przełączenie się na "zamień" jest proste - M-% lub C-M-%, jeżeli potrzebujemy wyrażeń regularnych.
Wszechobecna pomoc
Oczywiście nie musisz tego wszystkiego pamiętać. Warto jest wykorzystywać tylko te opcje, które są potrzebne. Gdy je opanujesz możesz dodać następną do swojego "portfela". W bardzo przystępnej (i krótkiej) formie opcje isearch są opisane w systemie pomocy GNU/Emacsa C-hkC-s - polecam, bo nie opisałem tu wszystkich.
Incremental search
isearch zawsze wydawało mi się potężnym narzędziem - tak naprawdę jest to tylko mechanizm wyszukiwania. Jest podobny do tego we współczesnych przeglądarkach, to znaczy że tekst jest wyszukiwany już w czasie pisania zapytania (kawałek, który się da znaleźć). W GNU/Emacsie można szukać w przód (C-s) lub w tył (C-r). Aby przejść do drugiego dopasowania wystarczy powtórzyć C-s lub C-r, przy czym w trakcie wyszukiwania w przód można uzyć C-r aby wyszukać w tył i odwrotnie.
Podstawy isearch
Napisałem już jak zacząć wyszukiwać, ale co dalej? Gdy już kursor znajdzie się w odpowiednim miejscu wystarczy nacisnąć enter (RET) aby zakończyć wyszukiwanie. Jeżeli natomiast wyniki nas nie satysfakcjonują (lub chcieliśmy tylko sprawdzić czy fraza występuje) to używamy C-g (jak zawsze do kasowania aktualnej akcji) aby powrócić do miejsca, z którego zaczęliśmy.
Modyfikacja wyszukiwanej frazy
Jedną z bardziej przydatnych opcji jest * znana z vim-a. Załóżmy, że stoimy kursorem przed pewnym słowem i chcemy poszukać tego słowa w tekście. Oczywiście nie musimy go kopiować (ani przepisywać). Wystarczy C-s (włącz isearch), a następnie C-w (dodaj następne słowo do wyszukiwania). Użycie C-w kilka razy spowoduje dodawanie kolejnych słów. Podbnie jest z C-y, tyle, że tu dodajemy całą linię od miejsca, w którym jest kursor. W tej grupie jest jeszcze M-y, które dodaje do isearch ostatnio usunięty (wycięty) tekst, ale to raczej mało przydatne. Najlepsze jest to, że w każdej chwili możemy wyedytować ręcznie wyszukiwany tekst, bo M-e przenosi nas do edycji szukanej frazy.
Dopasowanie niestandardowych znaków
Bardzo pomocne jest dopasowanie końca linii przy pomocy C-j. Nieco rzadziej potrzebujemy wyszukać np. ^M (to nie są dwa znaki, tylko jeden - zapisany w ten sposób. GNU/Emacs pokoloruje taką sekwencję, aby ją odróżnić od tekstu). Aby to uczynić można wykorzystać C-q, które robi "quote" na następnym znaku - w naszym przypadku potrzebujemy C-qC-m
Historia
Do "wspomagaczy" można także zaliczyć historię z autouzupełnianiem. Możemy iść w tył M-p, w przód M-n i dopełniać TABem. Jeżeli z jakiegoś powodu przerwiemy wyszukiwanie to możemy je wznowić. Wystarczy C-s - wtedy wyszukujemy pustego ciągu, powtórzenie C-s spowoduje wyszukanie ostatnio wyszukanego ciągu (czyli zatwierdzonego, usunięte przez C-g wyszukiwania nie są brane pod uwagę).
Wielkość liter
Domyślne zachowanie GNU/Emacsa jest bardzo ciekawe. Jeżeli wpisujemy tylko małe litery to wyszukiwanie jest BEZ rozróżniania wielkości liter. W przypadku napisania przynajmniej jednej wielkiej litery przechodzimy w tryb, w którym wielkość liter ma znaczenie. Aby w trakcie wyszukiwania przełączyć znaczenie wielkości liter można użyć M-c.
Wyrażenia regularne
Nic szczególnego, ale warto o tym wspomnieć. M-r przełącza między trybem zwykłego wyszukiwania i wyszukiwania przy pomocy wyrażeń regularnych (który można też włączyć od razu C-M-s lub C-M-r). Czasami się przydaje, ale zazwyczaj wiemy wcześniej czy będzie potrzebne wyrażenie regularne czy nie.
Podmiana
Do opcji "znajdź" często w pakiecie jest też "zamień" (jeżeli nie ma tego w Twoim edytorze, to go szybko zmień). W GNU/Emacsie przełączenie się na "zamień" jest proste - M-% lub C-M-%, jeżeli potrzebujemy wyrażeń regularnych.
Wszechobecna pomoc
Oczywiście nie musisz tego wszystkiego pamiętać. Warto jest wykorzystywać tylko te opcje, które są potrzebne. Gdy je opanujesz możesz dodać następną do swojego "portfela". W bardzo przystępnej (i krótkiej) formie opcje isearch są opisane w systemie pomocy GNU/Emacsa C-hkC-s - polecam, bo nie opisałem tu wszystkich.
Zabawy z translate.pl
czwartek, 14 maj 2009 | Etykiety: Perl, Rozrywka | 0 komentarze »
Czasem jest tak, że potrzebujemy dobrego translatora. Jak znaleźć odpowiedni? Właśnie o tym NIE będę pisał. Translatory mogą służyć do tłumaczenia tekstów, ale maję też inne zastosowanie - wprowadzają trochę uśmiechu w nasze życie.
Niedawno na www.bash.org.pl był taki cytat:
Niedawno na www.bash.org.pl był taki cytat:
Ponoć ciekawe efekty można uzyskać prosząc o przetłumaczenie frazy na wybrany język, a następnie spowrotem na język wyjściowy. Zrobiłem coś takiego na http://www.translate.pl/pl.php4. Tłumaczyłem z angielskiego na angielski poprzez polski. Odpowiedni skrypt wygląda tak (perl):
peszku: google tłumacz rządzi :D
zobo: co tym razem?
peszku: "babcia piekła ciasteczka" przetłumaczył na "grandmother hell cookies"
zobo: ;|
Od strony kodu nic ciekawego, ale można się chwilę pobawić. Niestety dla bashowego cytatu dostajemy mało ciekawy wynik. Ciekawsze przypadki:
#!/usr/bin/perl
use warnings;
use strict;
use LWP::UserAgent;
my $phrase = shift || die "Please specify phrase as an argument";
my $ua = LWP::UserAgent->new();
my $url = "http://www.translate.pl/pl.php4";
# translate to pl
my $response = $ua->post($url, { d => "1", inbuf => "$phrase" } );
$response->content =~ m{<font class="translate">(.*?)</font>}ms;
my $translation_pl = $1;
# translate to en
$response = $ua->post($url, { d => "2", inbuf => $translation_pl } );
$response->content =~ m{<font class="translate">(.*?)</font>}ms;
my $translation_en = $1;
print "pl: $translation_pl\nen: $translation_en\n";
Ciekawe jest, że trudno wybrać takie zdanie, które uda się przetłumaczyć aby było choć trochę "zabawnie". W większości przypadków translator robi coś naprawdę głupiego, czego nie da się sensownie przeczytać. Wyzwaniem jest znalezienie zdania (powyżej 3 słów), którego translator nie zniszczy.
what's up --> That is
go --> They manage
I was born in California.
Which part?
All of me
-->
It was born < give birth (be born) > in california.
Divides what?
I all
What's the use of having a train schedule if the trains are always late.
-->
That is use of existence of schedule of train ( train ) if trains are always late ( train ) ( last; late ).
How would we know they were late, if we didn't have a schedule?
-->
As there would be late learn last be (; late ), have did not we if?
Braki w C++
wtorek, 5 maj 2009 | Etykiety: C++ | 3 komentarze »
Jak każdy porządny język tak i C++ ma swoje braki. Jednym z nich jest brak typu, który pozwalałby przechowywać dowolną funkcję (albo chociaż wskaźnik do funkcji dowolnego typu). Nie jest to może bardzo uciążliwe, ale potrafi "wyjść" w odpowiednim momencie.
Większość pomyśli pewnie od razu o void*. Pewnie możnaby się kłócić na temat "elegancji" takiego rozwiązania gdyby... było ono poprawne. Okazuje się, że jest niezgodne ze standardem, a tylko przypadkiem (?) kompilator przepuszcza je jako poprawne odgrażając się jedynie przy użyciu ostrzeżeń.
Zgodnie ze standardem C++ na void* można rzutować obiekty (dane) - jest to zmiana w stosunku do C. Funkcja czy wskaźnik na funkcję oczywiście obiektem nie jest.
Ostatnio coraz bardziej zastanawia mnie dlaczego standard C++ próbuje być kompatybilny z C, skoro jednocześnie wprowadza tyle różnic, że programy z C niekoniecznie muszą kompilować się w C++. Szkoda, że usunięto wskaźnik na dowolną funkcję, ale jednocześnie zostawiono niejawne konwersje między typami - IMO to drugie jest znacznie bardziej błędogenne.
Większość pomyśli pewnie od razu o void*. Pewnie możnaby się kłócić na temat "elegancji" takiego rozwiązania gdyby... było ono poprawne. Okazuje się, że jest niezgodne ze standardem, a tylko przypadkiem (?) kompilator przepuszcza je jako poprawne odgrażając się jedynie przy użyciu ostrzeżeń.
Zgodnie ze standardem C++ na void* można rzutować obiekty (dane) - jest to zmiana w stosunku do C. Funkcja czy wskaźnik na funkcję oczywiście obiektem nie jest.
Ostatnio coraz bardziej zastanawia mnie dlaczego standard C++ próbuje być kompatybilny z C, skoro jednocześnie wprowadza tyle różnic, że programy z C niekoniecznie muszą kompilować się w C++. Szkoda, że usunięto wskaźnik na dowolną funkcję, ale jednocześnie zostawiono niejawne konwersje między typami - IMO to drugie jest znacznie bardziej błędogenne.
Subskrybuj:
Posty (Atom)

