Posts from 2011

Regulacja głośności jako porażka funkcjonalna

2011-02-21 19:36

Fajnie jest używać oprogramowania, które da się łatwo dopasować do swoich upodobań – zwłaszcza, jeśli da się to zrobić łatwo, szybko i intuicyjnie, bez konieczności czytania długich manuali. Niestety, konstruowanie interfejsu udostępniającego szeroką funkcjonalność oraz wcześniej wspomniane cechy nie jest łatwe. Dla mnie dobrym przykładem tego, co może pójść źle podczas próby uszczęśliwienia użytkownika mnogością opcją i elastycznością konfiguracji jest banalny na pierwszy rzut oka mechanizm: regulacja głośności dźwięku w komputerach PC.

Problem z nim związany polega – mówiąc ogólnie – na rozbiciu zagadnienia na mniejsze fragmenty (dzięki czemu w teorii uzyskujemy większą kontrolę nad każdym z nich) bez zastanowienia się nad niepożądanymi efektami wzajemnych relacji między tymi fragmentami. Regulacja głośności w komputerach PC występuje bowiem obecnie nie w jednym, a w kilku miejscach. W skrajnych przypadkach może być ich więcej, niż da się policzyć na palcach jednej dłoni, gdy w grę wchodzi:

  • sprzętowe pokrętło głośności, będące częścią słuchawek, zestawu głośników lub kontrolek na obudowie laptopa
  • globalne, systemowe ustawienie głośności dźwięku (w Windows dostępne po kliknięciu na ikonkę w zasobniku)
  • globalne ustawienie głośności regulowane w panelu kontrolnym sterownika karty dźwiękowej
  • systemowy poziom dźwięku ustawiany dla każdego z głośników (centralnego, subwoofera, itd.)
  • systemowy poziom dźwięku ustawiany dla poszczególnych aplikacji lub komponentów systemowych
  • właściwy dla aplikacji (np. gier) poziom głośności ustawiany w samym programie

Ałć. Sporo tego, prawda? W celu usprawiedliwienia tego bałaganu można argumentować, że za prawie każdy z elementów tej listy odpowiada ktoś, jako że znajdują się one w rożnych warstwach abstrakcji. Tak też w teorii powinniśmy je traktować i nawet czerpać korzyści z tego faktu, na przykład poprzez przyciszenie efektów dźwiękowych w grze na rzecz muzyki z działającego w tle odtwarzacza.
Teoria zaś, jak wiemy, niczym nie różni się od praktyki – ale tylko w teorii. W praktyce możemy mieć zupełnie inny przypadek użycia, kiedy na przykład próbujemy rozmowy przez komunikator i stwierdzamy, że nie słyszymy drugiej strony wystarczająco głośno. Będąc rozsądnym użytkownikiem (optymistyczne założenie ;]) udamy się wpierw do ustawień programu i tam wyregulujemy głośność. Ale jeśli to nie pomoże, zapewne w drugim kroku pokręcimy odpowiednim pokrętłem lub przesuniemy globalny systemowy suwak. W konsekwencji następny chord.wav czy inny dźwięk będący częścią UI systemu może nam dostarczyć, mówiąc oględnie, zaskakująco intensywnych wrażeń słuchowych ;)

To jest właśnie przykład niepożądanej interakcji pomiędzy zachodzącymi na siebie fragmentami zagadnienia. Ale w przypadku regulacji głośności nawet pożądane interakcje nie są oczywiste. Czy łatwo jest bowiem określić, w jaki sposób X% nadrzędnego i Y% podrzędnego poziomu dźwięku przełoży się na to, co ostatecznie usłyszymy w głośnikach? Wymaga to chwili zastanowienia, a przecież mówimy tu o czynności, którą powinno się wykonywać automatycznie, bezwiednie i niemal zupełnie nieświadomie! Nie spodziewam się też, aby statystyczny użytkownik miał jakiekolwiek pojęcie o istotnym tutaj prawie Webera-Fechnera, które dodatkowo wpływa na faktycznie słyszaną intensywność wynikowego dźwięku.

Z tych wszystkich narzekań wyłania się wniosek, że regulacja głośności w PC-tach to zagadnienie o sztucznie zawyżonym poziomie komplikacji. Mogłoby ono być znacznie prostsze, gdyby nie obciążono go balastem pozornej konfigurowalności. Jako dobry przykład może służyć analogiczny mechanizm w telefonach, opierający się na dokładnie jednej sprzętowej kontrolce poziomu dźwięku (np. przyciskach) i braku zależności między poszczególnymi ustawieniami (np. multimediów, dzwonka czy rozmowy).

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

Więcej niż operatory logiczne

2011-02-11 20:44

Bardzo przydatną cechą operatorów logicznych w wielu językach programowania jest leniwa ewaluacja (lazy evaluation). Polega ona na pominięciu obliczania tych argumentów operatorów && (and) i || (or), które i tak nie mają szans wpłynąć na ostateczny wynik. To pozwala na tworzenie warunków podobnych do poniższego:

  1. if (obj != null && obj.Valid) { obj.DoSomething(); }

Drugi człon nie wykona się tutaj w ogóle, jeśli pierwszy okaże się fałszywy, więc zmienna obj ustawiona na null nie spowoduje błędu wykonania.
Oczywiście technika ta jest doskonale znana każdemu przynajmniej średnio zaawansowanemu programiście. Okazuje się jednak, że przynajmniej jeden język idzie dalej i uogólnia ją w sposób pozwalający na stosowanie operatorów and i or do argumentów niebędących wartościami logicznymi. Jaki to język?… Python, rzecz jasna :)

W Pythonie dwa standardowe operatory ‘logiczne’ działają w oparciu o możliwość określenia specyficznie pojmowanej prawdziwości wyrażenia, którego typem niekoniecznie jest bool. Mówiąc w skrócie, każde wyrażenie niepuste i różne od zera – łącznie z odwołaniami do obiektów, liczbami, tablicami, słownikami i innymi kolekcjami – jest uważane za prawdziwe, gdy wystąpi w kontekście wymagającym rozróżnienia prawdy i fałszu.
Takim kontekstem jest chociażby warunek instrukcji if lub while – ale nie tylko. Możliwość “rzutowania na bool” (fachowo nazywanego koercją) jest też wykorzystywana w definicji operatorów and i or, które są z grubsza następujące:

  • A and B jest równe:
    • A, jeśli A jest wyrażeniem fałszywym
    • B – w przeciwnym wypadku
  • A or B jest równe:
    • A, jeśli A jest wyrażeniem prawdziwym
    • B – w przeciwnym wypadku

W pierwszej chwili mogą one wydawać się dość skomplikowane, ale nietrudno jest zauważyć, że “działają” one zgodnie z oczekiwaniami wobec argumentów typu bool i mogą być obliczane leniwie. Ponieważ jednak dzięki nim rezultatem operatora nie jest po prostu True lub False, lecz jeden z argumentów, możliwe jest stosowanie and i or także wtedy, gdy wynikiem nie ma być wcale wartość logiczna.

Wbrew pozorom ma to czasem wielki sens. Oto bardzo typowy przykład kodu, który korzysta z tej sztuczki:

  1. s = get_a_string_from_somewhere() or "N/A"
  2. print s

Co tu się dzieje?… Jeśli wywołanie funkcji zwróci prawdziwą (czyli niepustą i niezerową, więc zapewne sensowną) wartość, jest ona wyświetlona. W przeciwnym razie korzysta się z napisu zastępczego. Dzięki elastycznemu operatorowi or łatwo więc można określić pewnego rodzaju wartość domyślną (czyli fallback) dla wyrażenia.
Z kolei operator and jest często wykorzystywany do warunkowego odwoływania się do “głęboko ukrytej” wartości, wymagającej przejścia przez ciąg kilku potencjalnie pustych odwołań:

  1. return obj and obj.wrapper and obj.wrapper.result

Jeśli któreś z nich jest równe None, to taki będzie rezultat całej konstrukcji. W przeciwnym razie wynikiem będzie ostatni argument.

Istnieje szansa, że przynajmniej jeden z powyższych mechanizmów wygląda znajomo, jeśli ma się doświadczenie w językach Java lub C#. Sztuczka z operatorem or odpowiada bowiem podwójnemu znakowi zapytania (??) z C#, zaś przykład z and wprowadzonemu w Javie 7 operatorowi ?. (znak zapytania i kropka).
Zapewne też w tym momencie wszyscy przypomną sobie o starym dobrym operatorze trójargumentowym, występującym we wspomnianych dwóch językach i jeszcze wielu innych. Okazuje się, że w Pythonie jego działanie też można symulować przy użyciu operatorów and i or:

  1. res = (condition and if_true) or if_false

Nie trzeba jednak tego robić, bowiem od wersji 2.5 istnieje nieco inny składniowo odpowiednik takiej konstrukcji:

  1. res = if_true if condition else if_false

Warto zwrócić uwagę na inną niż typowa kolejność wyrażeń w tej konstrukcji.

Tags: ,
Author: Xion, posted under Programming » 1 comment

Dwa podejścia do technologii

2011-02-05 1:36

Tematy związane z technologiami komputerowymi są zaskakująco często motywem wielu zażartych sporów między ich użytkownikami. Nie jest to w sumie nowość, bo tak zwane święte wojny są niemal tak stare, jak szeroko pojęta kultura hakerska – a więc liczą sobie dziesiątki lat. Teraz jednak wspomniane technologie są wszędzie i w związku tym dyskusje między zwolennikami poszczególnych rozwiązań zataczają o wiele szersze kręgi. Wydaje mi się też, że w przeważającej części inny jest też ich charakter. Zaryzykuję też twierdzenie, że wiele z nich – w tym te najbardziej prominentne – maja u swych podstaw jedną przyczynę, której uczestnicy sporów nie są najczęściej świadomi.

Uważam mianowicie, że istnieją dwa wyraźnie różne podejścia do rozwiązań technologicznych dowolnego rodzaju. Z braku lepszych terminów określę je mianem geeka i laika. To właśnie zasadnicze różnice w postrzeganiu nowoczesnych technologii między tymi dwoma podejściami są, według mnie, główną przyczyną zażartych, często jałowych i zawsze niekonkluzywnych pojedynków na słowa.
Doprecyzowując, chodzi o priorytety: skłonność do poświęcenia pewnego zbioru cech produktów, rozwiązań i technologii na rzecz innego zbioru właściwości. Nie muszą to być zresztą własności ze sobą sprzeczne, ale zwykle każdy ze zbiorów może być dość jednoznacznie przypisany do jednego konkretnego rozwiązania z danej kategorii.

W przypadku, gdy mówimy o laiku, pożądanymi własnościami będą przede wszystkim: atrakcyjne wykonanie, bezproblemowe działanie i prostota obsługi. To będą główne kryteria, jakimi kierować się będzie osoba reprezentująca to podejście i będą one wpływały na dokonywane przez nią wybory konkretnych opcji spośród wielu możliwości.
Przykłady oczywiście znaleźć nietrudno. Jeśli ktoś reprezentuje taką postawę, to będzie używał raczej systemu Windows (lub OS X-a) niż Linuksa; przeglądał sieć raczej za pomocą Chrome’a niż Firefoksa; posługiwał się raczej iPhonem niż innym rodzajem smartphone‘a; preferował raczej laptopy lub tablety niż komputery stacjonarne – i tak dalej, żeby wspomnieć tylko o tych najbardziej rozgrzewających Internet debatach.
Dla geeka cennymi wartościami będzie natomiast zupełnie inny zestaw: elastyczność, rozszerzalność i szerokie pole manewru w zakresie dostosowywania do specyficznych potrzeb. To zaś potencjalnie koreluje z opcjami, które w wymienionych wcześniej alternatywach były określone jako mniej prawdopodobne.

Te dwie postawy nie są w żadnym wypadku wykluczające się – zwłaszcza wtedy, gdy przejawiają się wyborami w osobnych, mało związanych ze sobą dziedzinach. Sądzę jednak, że przewaga częstości występowania jednej lub drugiej mogłaby sugerować związek z jakimiś bardziej fundamentalnymi cechami charakteru czy osobowości danej osoby. Przy okazji należałoby oczywiście oszacować wpływ takich czynników jak podatność na działania marketingowe czy łatwość zmiany przyzwyczajeń.
W sumie więc mógłby to być interesujący temat do badań porównawczych, potencjalnie skutkujący gazetowymi nagłówkami w stylu: Amerykańscy naukowcy odkryli, że użytkownicy Linuksa jedzą więcej fistaszków ;-)

mgr inż. Xion

2011-01-31 18:18

Taka okazja zdarza się tylko raz, więc nie widzę powodów, by się tym nie chwalić ;P Udało mi się dzisiaj zdać egzamin dyplomowy, wobec czego oficjalnie zostałem magistrem inżynierem informatyki, specjalność Metody sztucznej inteligencji. Innymi słowy, mogę sobie przed imieniem i nazwiskiem dopisywać już nie trzy, a całe sześć liter :)

Kolejny symboliczny etap edukacji mam więc już za sobą. A przed sobą na pewno jeszcze mnóstwo nauki, bo w tej branży człowiek uczy się przecież przez całe życie…


Author: Xion, posted under Events, Studies » 27 comments

Duże i małe commity

2011-01-29 23:49

Mam ciekawą obserwację związaną ze sposobem używania różnych systemów kontroli wersji. Dokładniej mówiąc, chodzi o dość wyraźną różnicę w częstotliwości commitów między zwykłymi a rozproszonymi VCS-ami. Do tych pierwszych kod commituje się stosunkowo rzadko, ponieważ każda zmiana jest od razu widoczna w publicznym repozytorium. To ma zaś daleko idące konsekwencje, jak choćby natychmiastowa dostępność naszych modyfikacji dla innych osób pracujących nad projektem. Dlatego też trzeba starać się, aby nie wypuścić bubla. Minimalnym wymaganiem jest kompilowalność commitowanego kodu, a dobrze by było, żebyśmy też poddali go choćby wstępnemu testowaniu.

Gdy z kolei pracujemy z rozproszonymi systemami kontroli wersji, możemy teoretycznie robić dokładnie tak samo. Wówczas jednak nie tylko nie korzystamy z faktu posiadania lokalnego repozytorium, ale wręcz dodajemy sobie pracy. Osiągnięcie tego samego efektu (upublicznienia zmian) wymaga bowiem dwóch kroków – dodatkowym jest push, czyli synchronizacja z globalną bazą kodu. Będąc przyzwyczajonym do scentralizowanych VCS-ów można łatwo o nim zapomnieć.
Dlatego też wydaje mi się, że przy systemie rozproszonym warto nieco zmienić nawyki. Commitów można bowiem dokonywać częściej – znacznie częściej. Ponieważ żaden z nich nie wydostaje się automatycznie poza nasz komputer, nie muszą one dodawać kompletnych funkcjonalności albo w pełni poprawiać znalezione wcześniej błędy. Nie muszą działać. Ba, w zasadzie to nie muszą nawet się kompilować. Grunt, żeby zawierały modyfikacje, które wydają nam się warte zachowania i opatrzenia komentarzem. W praktyce w ciągu dnia można w ten sposób wykonać nawet do kilkudziesięciu commitów – w porównaniu do dwóch lub trzech w przypadku pracy z system scentralizowanym.

Czy taka częstotliwość dobrze wpływa na efektywność kodowania? Z początku nie byłem o tym przekonany, ale teraz widzę, że ma ona niewątpliwe zalety. Wykonując częste commity (a zwłaszcza opisując je), programujemy w sposób bardziej zdyscyplinowany. Trochę trudniej jest wtedy napisać wysublimowany, barokowo skomplikowany i ogólnie przekombinowany moduł albo takąż klasę. Mamy raczej większe szanse na to, że poczynimy jakieś realne postępy w pracy nad projektem. Dodatkowo częste “odhaczanie” wykonanych zadań i poczynionych postępów (nawet jeśli są bardzo drobne) jest bardziej motywujące niż oznaczanie zmian rzadkich a duże.
A co jeśli naszą przeszkodą w wykonywaniu częstych commitów jest brak weny twórczej odnośnie komentarzy do nich?… No cóż, wtedy zawsze można poszukać inspiracji tutaj ;-)

Tags: ,
Author: Xion, posted under Programming, Thoughts » 5 comments

Bo konsola to też okno

2011-01-26 9:48

Systemy uniksowe dość długo wyróżniały się znacznie lepszym wsparciem dla trybu wiersza poleceń niż Windows. To się w pewnym sensie zmieniło po powstaniu PowerShella, będącego co najmniej równie dobrą powłoką tekstową co bash czy zsh. Jednak przynajmniej w jednym aspekcie Linuksy wciąż mają tutaj wyraźną przewagę. Chodzi o graficzną otoczkę tekstowej konsoli.
W Windows programy konsole uruchamiane są wciąż w starym, w gruncie rzeczy obleśnym i w dodatku bardzo słabo i trudno konfigurowalnym oknie. Nie da się płynnie zmienić jego rozmiaru, zmaksymalizować, nie wspominając już nawet o otwieraniu kilku konsol w zakładkach tego samego okna. Możliwość modyfikacji czcionki czy też kolorów tekstu i tła też jest ograniczona i niewygodna. Dla porównania, okienka konsoli w systemach linuksowych są pod tym względem o wiele elastyczniejsze, zapewniając wszystkie te feature‘y i jeszcze sporo innych. W rezultacie interfejs tekstowy jest tam przyjemniejszy w obsłudze, nawet jeśli obiektywnie ustępuje możliwościami temu windowsowemu.

Czy da się coś na to poradzić, czyniąc windowsowe okienko konsoli bardziej znośnym?… Otóż można w pewnym – może nawet zadowalającym – stopniu to uczynić, lecz w tym celu trzeba się posłużyć zewnętrzną aplikacją. Chodzi mianowicie o open-source‘owy projekt Console2, będący okienkowym środowiskiem uruchamiania programów konsolowych. Technicznie działa on zapewne w podobny sposób, jak mój eksperyment sprzed prawie trzech lat, z tym że oczywiście robi to znacznie lepiej :) W międzyczasie zapewnia też sporą część funkcjonalności okienek terminala pracujących w X-Window, a mianowicie:

  • obsługę kilku zakładek z przełączaniem się między nimi za pomocą konfigurowalnych skrótów klawiszowych
  • wybór domyślnego shella (np. cmd, cygwin albo powershell), a także możliwość skonfigurowania kilku powłok uruchamianych automatycznie w osobnych zakładkach
  • zaawansowaną konfigurację wyglądu, aż do kształtu kursora włącznie
  • obsługę przezroczystości całego okna
  • zmianę jego rozmiaru poprzez przeciąganie za krawędź

i jeszcze kilka innych, w gruncie rzeczy naturalnych funkcji, których w tajemniczy sposób zabrakło w standardowym oknie konsoli w Windows. Jeżeli chodzi o stabilność i szybkość działania, to również prezentuje się nie najgorzej, chociaż zdarzają się problemy, np. z przesłaniem sygnału Ctrl+C w celu przerwania spamującego polecenia w rodzaju ls -r /. Małą wadą jest też konfiguracja, która może zająć trochę czasu i kłopotów, jeśli umieścimy program w standardowy folderze Program Files (wskazówka: należy wtedy poinstruować go, by zapisywał ustawienia w katalogu użytkownika).
Ogólnie jednak moje wrażenia co do tej aplikacji są w miarę pozytywne, lecz pamiętajmy, że rywal jest godny pożałowania ;) Tym niemniej polecam zapoznanie się z tym programem, jeśli dużo pracujemy z tekstowym shellem pod Windows.

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

Nie tylko pisanie kodu

2011-01-21 19:25

Gdyby było to fizycznie możliwe, chętnie przeprowadziłbym następujący eksperyment. Z odległej przeszłości – na przykład z połowy lat 90. poprzedniego stulecia – sprowadziłbym w obecne czasy dowolnego ponadprzeciętnie uzdolnionego programistę. Jak szybko odnalazłby się we współczesnym koderskim środowisku pracy?… W celu redukcji złożoności problemu poczyńmy daleko idące uproszczenia i pomińmy wszelkiego typu zmiany związane z postępem technologicznym (jak choćby nieporównywalnie większe znaczenie Internetu wtedy i teraz), a także modyfikacje, które zachodzą w samych językach programowania. Interesuje mnie raczej to, czy ów przybysz z przeszłości doceniłby i uznał za przydatne różnego rodzaju czynności i narzędzia pomocnicze, niebędące edytorem tekstu (lub IDE) ani kompilatorem, i pozostające w luźniejszym związku z samym pisaniem kodu jako takiego.

Jakby bowiem przyjrzeć się dokładnie wachlarzowi tych narzędzi, okazuje się, że jest on już całkiem szeroki. Programowanie, zwłaszcza zespołowe (jeżeli w ogóle istnieje jeszcze jakieś inne) już od dawna przestało ograniczać do tworzenia kodu i czasami wydaje się nawet, że czynność ta stała się poboczną. Coraz więcej czasu zajmuje praca z takimi narzędziami jak systemy kontroli wersji, systemy śledzenia błędów (issue tracking systems), narzędzia automatyzujące proces kompilacji, programy do statycznej analizy kodu, systemy zdalnej kompilacji i pewnie mnóstwo jeszcze innych wynalazków, z którymi nie miałem dotąd okazji się zetknąć.
Między innymi dlatego nie potrafię jednoznacznie określić, czy uważam je wszystkie raczej za przydatne czy raczej za zbędne. Wiążące opinie mogę jak dotąd wyrazić tylko o niektórych.

Tym niemniej ciekawi mnie również, czy w dziedzinie wspomagania kodowania (czy ogólnie pracy nad projektami) od strony zautomatyzowanych narzędzi da się wymyślić coś jeszcze…

 


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