Monthly archive for April, 2011

Funkcja join()

2011-04-29 21:24

Będąc w zgodzie z podzielanym przez siebie poglądem o kluczowej a często niedocenianej roli “małych” algorytmów, dzisiaj wezmę pod lupę funkcję do łączenia napisów, znaną większości jako join. Ta przydatna operacja występuje w wielu językach i bibliotekach, a jej brak w pozostałych jest zwykle wyraźnie odczuwalny (tak, Java, o tobie mówię). Dobrze użyty join – zwłaszcza w połączeniu z pewnymi specyficznymi mechanizmami językowi – potrafi zapobiec pisaniu niepotrzebnych pętli, znacząco redukując code bloat.

Ale po kolei. join to operacja polegająca na złączeniu kolekcji napisów w jeden, odpowiednio sklejony łańcuch. Łączenie polega na tym, że w wyniku pomiędzy elementami kolekcji wstawiony jest pewien określony ciąg (“klej”). Najlepiej widać to na przykładzie:

  1. array = ["Ala", "ma", "kota"]
  2. text = str.join(" ", array)
  3. assert text == "Ala ma kota"

Łatwo zauważyć, że join jest w gruncie rzeczy przeciwieństwem funkcji split, którą nieprzypadkowo kiedyś już opisywałem :)

W czym przejawia się przydatność tej operacji? Przede wszystkim rozwiązuje ona “problem ostatniego przecinka” przy wypisywaniu list. Tradycyjnie obchodzi się go mniej więcej tak:
for (int i = 0; i < (int)strings.length(); ++i) { std::cout << strings[i]; if (i + 1 < (int)strings.length()) std::cout << ", "; }[/cpp] Instrukcja if w tej pętli nie jest oczywiście szczytem elegancji. Gdybyśmy mieli tu funkcję join wszystko byłoby o wiele czytelniejsze:
std::cout << join(", ", strings);[/cpp] Drugą zaletą joina jest jego dobra współpraca z modnymi ostatnio, funkcyjnymi rozszerzeniami wielu języków, pozwalająca w zwięzły sposób przetwarzać kolekcje obiektów. Jeśli na przykład mamy słownik (tudzież mapę/hash), to zamiana go na tekstowy odpowiednik klucz=wartość jest prosta:

  1. import os
  2. def join_dict(d):
  3.      # os.linesep to separator wierszy właściwy dla systemu
  4.     return str.join(os.linesep, map(lambda item: "%s=%s" % item, d.items()))
  5.  
  6. data = { "fullscreen": 1, "width": 800, "height": 600 }
  7. print join_dict(data)
  8. # fullscreen=1
  9. # width=800
  10. # height=600

Oczywiście jest tak wówczas, gdy na widok słowa kluczowego lambda nie uciekamy z krzykiem ;-)

Na koniec tej krótkiej pogadanki wypadałoby jeszcze zaprezentować przykładową implementację omawianej funkcji. Ponieważ – jak napomknąłem wcześniej – doskwierał mi ostatnio jej brak w Javie, więc kod będzie w tym właśnie języku:

  1. public static String join(final Collection<?> s, final String delimiter) {
  2.  
  3.     final StringBuilder builder = new StringBuilder();
  4.     final Iterator<?> iter = s.iterator();
  5.     while (iter.hasNext()) {
  6.         builder.append(iter.next());
  7.         if (!iter.hasNext()) break;
  8.         builder.append(delimiter);
  9.     }
  10.     return builder.toString();
  11. }

Z dokładnością do szczegółów generycznych kolekcji i operacji na stringach, powyższą implementację powinno się dać łatwo przetłumaczyć także na C++.

Tags: , , , ,
Author: Xion, posted under Programming » 7 comments

Xoom, czyli tablety mają swój urok

2011-04-24 18:02

Sprzętowe odkrycie zeszłego roku – tablety – to wynalazek, którego użyteczność wciąż wymykała się moim zdolnościom poznawczym. Ponieważ jednak staram się zwykle być jak najdalej od negowania czegoś, czego do końca mogę nie rozumieć, chciałem już od dość dawna przyjrzeć się sprawie nieco bliżej. Za bliższe poznanie nie może niestety uchodzić kilkadziesiąt minut raczej bezładnego mazania po ekranie iPada (w obu wersjach), zatem postanowiłem na czas świątecznego weekendu wypożyczyć z pracy inne urządzenie tego rodzaju: Motorolę Xoom. Po kilku dniach korzystania z tego gadżetu sądzę, że już mniej więcej rozumiem zamysł stojący za tego typu sprzętem.

I właśnie tym cennym odkryciem chciałem się dzisiaj podzielić :)

Proste gesty dotykowe

2011-04-20 19:38

Urządzenia, w których jedyną lub główną metodą interakcji jest ekran dotykowy prezentują interesują wyzwanie w zakresie sterowania i interfejsu użytkownika. Naiwne w rozwiązania zwykle sprawdzają się słabo, czego przykładem może być wydzielenie części ekranu na przyciski kontrolne. Brak skoku oraz fizycznych krawędzi klawiszy sprawia, że stosunkowo łatwo tutaj o pomyłkę i niezamierzone wciśnięcie błędnego klawisza.
Dlatego też ta forma komunikacji użytkownika z urządzeniem wymaga nieco innego podejścia, które wykorzystuje jego mocne punkty i pozwala jakoś żyć z jego słabymi stronami. Można na przykład zauważyć, że palec użytkownika jeżdżący po ekranie (pozwolę sobie pominąć tutaj multitouch :)) przypomina pod wieloma względami kursor myszki i często można z powodzeniem traktować go jako taki. Podstawową różnicą jest brak wykrywalnego ruchu między miejscami interesującymi użytkownika, a co za tym idzie brak również zdarzeń typu hover (mouseover), służących często do wyświetlania podpowiedzi.


Jak się tapuje :) (Źródło)

Jest więc podobnie, ale inaczej :) Ponieważ nie mażemy palcem po ekranie przez cały czas, interakcja użytkownika z urządzeniem przebiega wyłącznie za pośrednictwem zamierzonych gestów. Częściowo przypominają one kliknięcia lub przeciąganie wykonywane jednoprzyciskową myszą, ale ich wachlarz jest nieco szerszy. Wśród nich mamy bowiem takie gesty jak:

  • Tap, czyli po polsku ‘tapnięcie’ ;-) Jest to krótkie naciśnięcie (albo wręcz puknięcie) ekranu. To najkrótszy i prawdopodobnie najprostszy gest (chociaż słyszałem też opinie wprost przeciwne), który służy standardowo do wyboru wskazanego elementu. W ten sposób uruchamia się aplikacje lub przechodzi do stron wskazywanych przez linki. Gest ten jest więc funkcjonalnym odpowiednikiem pojedynczego lub podwójnego kliknięcia w przypadku zwykłej myszki.
  • Long press, czyli dłuższe wciśnięcie. Polega ono na naciśnięciu ekranu i przytrzymaniu palca w jednym miejscu, zwykle około sekundę. Taki gest często daje dostęp do drugorzędnej akcji związanej z wciskanym elementem, a czasami po prostu otwiera menu zawierające większą liczbę opcji. Przybliżonym odpowiednikiem long pressa w przypadku myszki jest więc kliknięcie prawym przyciskiem.
  • Double tap, czyli podwójne tapnięcie. Oznacza to wykonanie dwóch tapów w krótkim odstępie czasu i przestrzeni (na ekranie). Chociaż wydaje się to podobne do dwukrotnego kliknięcia, analogia jest raczej błędna. Podwójny tap wykorzystywany więc bowiem stosunkowo rzadko i raczej tylko w dość specjalnych przypadkach. Jednym z powodów jest fakt, że obsługa tego gestu opóźniałaby każdy zwykły (pojedynczy) tap, gdyż użytkownik potrzebowałby okienka czasowego na “zdecydowanie się” na ewentualne drugie tapnięcie.
    Dlatego też często stosowaną strategią jest obsługa double tapu tylko w obrębie przestrzeni między interaktywnymi elementami. Wtedy gest ten służy do przełączania między widokiem zwykłym a przybliżonym/powiększonym – czyli po prostu do zoomowania.
  • Swipe lub fling, czyli przeciąganie. Podobnie jak w long pressie tu też wciskamy ekran na dłużej, ale tym razem przeciągamy palec w inne miejsce bez jego odrywania. Ten gest w rzeczywistości tysiąc razy prostszy niż nawet ten jednozdaniowy opis i niezwykle intuicyjny, więc używa się go w bardzo wielu miejscach. Obejmuje to: przechodzenie do następnego/poprzedniego elementu, przewijanie długich list, przeciąganie elementów w stylu drag & drop i pewnie jeszcze sporo innych zastosowań. Łatwo więc zauważyć, że odpowiednikiem dla zwykłej myszki może tu być zarówno standardowe przeciąganie z wciśniętym przyciskiem, jak i kręcenie rolką.

Jak widać, istnieją pewnie nieformalne standardy obsługi poszczególnych gestów w taki sposób, aby interfejs użytkownika był w miarę spójny. Zdaje mi się jednak, że ekrany dotykowe – mimo postulowanej intuicyjności – wciąż mogą niedoświadczonym użytkownikom wydawać się nieco zagadkowe w obsłudze. Spójna obsługa powyższych gestów w aplikacjach pomogłaby oczywiście w eliminacji tego problemu.

Tags: , ,
Author: Xion, posted under Applications, Programming » 2 comments

Do czego przydaje się AJAX

2011-04-16 22:44

Kiedyś wymyślono, że statyczne strony WWW są nieco nudne i że trochę bardziej zaawansowanej logiki mogłoby dodać im funkcjonalności. Powstał więc język JavaScript, który po pewnym czasie (gdy minął okres wykorzystywania go do animowanych zegarków, spadających płatków śniegu i innych niepoważnych zastosowań) znacząco zyskał na funkcjonalności. Dorobił się między innymi możliwości wysyłania dodatkowych żądań HTTP, niezależnie od pierwotnego requestu, wczytującego całą stronę.
Technika ta jest znana jako AJAX, czyli Asynchronous Javascript And XML. Ten łatwo wpadający w oko akronim jest notabene jednym z najbardziej nietrafnych, jakie da się znaleźć w całej szerokiej domenie informatyki. Jest tak dlatego, gdyż żądania HTTP wysyłane ze skryptów strony WWW:

  • wcale nie muszą być asynchroniczne, chociaż zwykle są
  • wcale nie muszą być kodowane w języku JavaScript (chociaż niemal zawsze są)
  • wcale nie muszą zwracać wyniku w formacie XML, bo zwykle używa się prostszych formatów

Ważna jest tu zwłaszcza uwaga ostatnia. Chociaż API do wysyłania żądań HTTP składa się z klasy o nazwie XMLHTTPRequest, to w istocie nie ma obowiązku korzystania z wbudowanego w nią parsera XML. Równie dobrze potrafi ona zwrócić odpowiedź serwera HTTP w postaci tekstowej, którą możemy potem przetworzyć ręcznie. W praktyce chyba najbardziej popularnym formatem zwrotnym dla zapytań AJAX-owych jest opisywany już przeze mnie JSON.
Oczywiście, nikt przy zdrowych zmysłach nie pisze samodzielnie kodu do owego “przetwarzania ręcznego” odpowiedzi z serwera. Zarówno ten końcowy etap, jak i samo wysyłanie żądania zostało bowiem opakowane w kilka użytecznych frameworków. Jednym z nich jest choćby jQuery, który poza ukrywaniem zbędnych szczegółów AJAX-u posiada też mnóstwo innych przydatnych funkcji ogólnego przeznaczenia.

Do czego może przydać się możliwość łączenia się z serwerem HTTP z poziomu Javascript? Żeby znaleźć odpowiedź, wystarczy dobrze przyjrzeć się właściwie dowolnej bardziej skomplikowanej stronie internetowej..Prawie na pewno znajdziemy na niej mechanizmy, które w tle pobierają dodatkowe dane z macierzystego serwera lub wysyłają doń jakieś informacje. Dzięki temu mogą one realizować takie funkcje jak:

  • Dynamicznie pobieranie nowych treści, które pojawiły się od czasu przeładowania witryny. Ładnym przykładem takie zachowania jest Twitter. Jeśli zostawimy stronę otwartą w zakładce przeglądarki, wówczas po jakimś czasie możemy odnaleźć na niej ramkę z napisem w rodzaju “2 new tweet(s)”, po kliknięciu której zobaczymy od razu nowe statusy.
  • Doczytywanie starszych elementów w trakcie przewijania. To odwrotny (chronologicznie) przypadek do powyższego, będący alternatywą dla stronicowania. Przykładem strony świetnie stosującej to rozwiązanie jest dzone.
  • Wyświetlanie szczegółów elementu, na przykład w dymku (tooltip) po najechaniu na niego kursorem myszy lub po rozwinięciu do większej postaci. Oczywiście ma to sens głównie wtedy, gdy treść do pobrania jest na tyle duża, że nie jest rozsądne dostarczanie jej wraz z pierwotną treścią strony.
  • Wysyłanie formularzy bez przeładowywania strony. Normalnie przesłanie formularza na stronie skutkuje jej przeładowaniem w wyniku żądania typu POST (rzadziej GET). Można jednak przechwycić zdarzenie wysłania formularza i zamiast niego przesłać zapytanie AJAX-owe. Sensownym wykorzystaniem tej techniki jest weryfikacja nazwy użytkownika po wciśnięciu osobnego przycisku w formularzy rejestracyjnym do wielu serwisów sieciowych.
  • Podpowiadanie zapytań w przypadku wyszukiwania. Tutaj nietrudno o przykłady, bo robią to wszystkie wyszukiwarki internetowe ogólnego przeznaczenia, a także sporo dedykowanych mechanizmów wyszukiwania obecnych w serwisach sieciowych.
  • Synchronizacja edytowanego dokumentu (Google Docs), obsługa czata (Facebook), map (Google Maps) i wielu innych zaawansowanych logicznie aplikacji webowych.
Tags: , , ,
Author: Xion, posted under Internet, Programming » 6 comments

Wyroby komputeropodobne

2011-04-12 23:46

Jeszcze sześć, siedem lat temu sprawa była jasna: komputer to takie dużo pudełko stojące pod biurkiem, a także dołączony do niego (niezbyt wtedy duży) monitor oraz klawiatura i myszka. Laptopy wciąż nie były specjalnie powszechne (a przynajmniej nie w Polsce), telefony komórkowe nadal służyły głównie do dzwonienia i SMS-owania, a słowo ‘tablet’ kojarzyło się niemal wyłącznie ze specjalistycznym sprzętem dla grafików.
Od tamtych czasów (wcale nie takich “starych i dobrych”, swoją drogą) zmieniło się jednak bardzo wiele, jeśli chodzi o bogactwo form i rodzajów zaawansowanych urządzeń elektronicznych zbliżonych do komputerów. Okazało się też, że tradycyjne komputery biurkowe to tylko jedna opcji do wyboru i to nawet niekoniecznie główna i preferowana. Krótko mówiąc poczciwe blaszaki przestały być niezastąpione.

Od tego momentu rozpoczął się proces różnicowania urządzeń wciąż nazywanych mniej lub bardziej potocznie komputerami, jak również pojawiania się takich, które dopiero na drugi rzut oka zdają się zasługiwać na to miano. Oprócz aż nazbyt już oczywistych laptopów czy netbooków, a także coraz bardziej popularnych, ale wciąż wątpliwie użytecznych tabletów mamy też nieco bardziej egzotyczne i wyspecjalizowane wynalazki. Interesującą opcją są chociażby e-czytniki, powoli acz nieprzerwanie zmieniające sposób czytania książek, bez wątpienia przyczyniając się zresztą do wzrostu czytelnictwa.
Częstym zarzutem wobec tego rodzaju komputeropodobnych wyrobów jest to, że służą one jedynie do “konsumpcji contentu” (czyli głównie mediów), natomiast domena twórcza zarezerwowana jest wciąż dla pecetów. Wydaje się to przynajmniej częściowo trafioną tezą, jednak powoli i to zaczyna się zmieniać. Powstają nawet takie urządzenia, których twórcze możliwości bardzo ciężko byłoby imitować zwykłym komputerom – jak chociażby swego rodzaju elektroniczna wersja kartki papieru.

Prawdopodobnie najciekawszym aspektem tych przemian form komputerowej elektroniki jest fakt, iż – o ile tylko długoterminowa pamięć nie zawodzi mnie zupełnie – były one w całkiem znaczącym stopniu przewidziane. Szczegóły naturalnie się nie zgadzają, gdyż na początku stulecia modne były raczej prognozy, że urządzenia elektroniczne staną się chociaż w pewnym wymiarze częścią garderoby. Świetnym przykładem są różne “magiczne” funkcje okularów w wielu filmach akcji – jak choćby w początkowej sekwencji Mission Impossible II (rok 2000).
To się oczywiście nie sprawdziło… w powszechnym użyciu (bo prototypy naturalnie są). Myślę jednak, że przy obecnym kierunku ewolucji sprzętu możemy spodziewać się przynajmniej równie efektownych gadżetów w niezbyt odległej przyszłości. Jak zwykle okaże się, iż nie mieliśmy bladego pojęcia, do czego coś może się przydać, dopóki ktoś tego czegoś nie stworzy :)

Tags: , , ,
Author: Xion, posted under Computer Science & IT, Thoughts » 8 comments

Going social

2011-04-09 11:29

W odpowiedzi na rosnące społeczne zapotrzebowanie (ta, jasne ;]) i trudny do zignorowania potencjał tzw. social medias, poczułem się w obowiązku włączenia w ten wciąż dziwny dla mnie, ale będący niewątpliwie rzeczywistością trend. Tak więc oto postanowiłem “uspołecznić” bloga, tworząc mu stronę na Facebooku i dodając wspaniałe przyciski Like! tu i ówdzie…

Cóż, trzeba iść z duchem czasu – w końcu to już dokładnie 500 postów :-)

Tags: ,
Author: Xion, posted under Internet, Website » 8 comments

Przenośne aplikacje mobilne

2011-04-05 21:07

Odkryłem niedawno bardzo ciekawy projekt o nazwie jQuery Mobile. Jego założeniem jest uproszczenie procesu tworzenia aplikacji na różne platformy mobilne poprzez dostarczenie odpowiednio przenośnego frameworka webowego. Powstałe przy jego pomocy “aplikacje” (a tak naprawdę odpowiednio spreparowane strony) mają wyglądać i działać tak samo na większości przenośnych urządzeń takich jak smartphone‘y i tablety.

Całkiem interesujące, prawda? Jeszcze ciekawsze jest to, że mimo bycia wciąż w stadium alpha (wersję alpha 4 wydano parę dni temu) całość działa już bardzo dobrze i rzeczywiście spełnia większość swoich obietnic. Oczywiście nie każdemu może uśmiechać się “programowanie w HTML” (;D), ale tutaj jest ono dość ładnie zorganizowane w warstwę interfejsu (odpowiednio spreparowane tagi HTML) i logiki (kod JavaScript wykorzystujący jQuery). Ta pierwsza pozwala między innymi na umieszczanie kilku stron w jednym pliku i efektowne przełączanie miedzy nimi:

  1. <div data-role="page" id="menu">
  2.     <div data-role="content">
  3.         <ul data-role="listview">
  4.             <li><a href="#one">One</a></li>
  5.             <li><a href="#two">Two</a></li>
  6.         </ul>
  7.     </div>
  8. </div>
  9. <div data-role="page" id="one">
  10. ...
  11. </div>
  12. <div data-role="page" id="two">
  13. ...
  14. </div>

Przejścia pomiędzy stronami nieźle imitują natywny UI platform mobilnych, gdyż są zrealizowane przy pomocy javascriptowych animacji zaimplementowanych w jQuery. Co więcej, jak widać powyżej odnośniki mogą być zwykłymi linkami (<a>). Czego zaś nie widać to to, że przy okazji przechodzenia między stronami historia przeglądarki – a więc chociażby przyciski Wstecz i Dalej – działa zgodnie z przewidywaniami i “nie psuje” zachowania aplikacji.
Naturalnie samo przełączanie stron to nie wszystko, bo wypadałoby przecież coś na nich pokazać :) Tutaj jQuery Mobile też prezentuje się dobrze, bo niejako automagicznie dba o odpowiedni wygląd elementów aplikacji poprzez stosowanie wbudowanego zestawu “mobilnych” stylów CSS. Zmieniają one wygląd tekstu, linków oraz pól formularzy na taki, który dobrze udaje kontrolki natywnego interfejsu. No, a przynajmniej może uchodzić za takowy w przypadku urządzeń pracujących pod kontrolą iOS-a, bo właśnie do interfejsu tego systemu aplikacje jQuery Mobile są najbardziej podobne.

Niemniej także na innych platformach (chociażby Androidzie) rezultat zastosowania tego frameworka jest więcej niż zadowalający. Wydaje mi się aczkolwiek, że podobne rozwiązania chwilowo wyprzedzają jeszcze trochę swój czas. Ich podstawowym mankamentem jest brak sensownych dojść z przeglądarki internetowej do większości ciekawych podsystemów urządzeń mobilnych, takich chociażby jak kamera; póki co dostępne są chyba tylko usługi lokalizacyjne. Nie da się więc w ten sposób tworzyć skomplikowanych aplikacji, korzystających ze sprzętu czy bardziej zaawansowanych funkcjonalności systemu.
Jeśli jednak chodzi o proste rozwiązania oparte na tekście, obrazkach i formularzach – a więc jako szeroko pojęte front-endy do zdalnych repozytoriów z danymi – to jQuery Mobile może być dobrą alternatywą dla mozolnego portowania aplikacji między różnymi platformami. Podobnie zresztą rzecz ma się z mobilnymi wersjami zwykłych stron internetowych.

Tags: , , ,
Author: Xion, posted under Applications, Internet, Programming » 8 comments
 


© 2017 Karol Kuczmarski "Xion". Layout by Urszulka. Powered by WordPress with QuickLaTeX.com.