Myślę, że większość programistów miała przynajmniej przelotny kontakt z wyrażeniami regularnymi. Zwykle używa się do bardziej zaawansowanego wyszukiwania podciągów w tekście – nie określonych sekwencji liter, ale fragmentów określonych raczej pewnymi warunkami. Innym ich zastosowaniem jest też sprawdzanie, czy podany łańcuch pasuje do pewnego określonego formatu. Przy pomocy poniższego wyrażenia:
można na przykład sprawdzić poprawność adresu e-mail (czy zawiera on znaczek @, czy nazwa domeny jest przynajmniej formalnie poprawna, itd.). Nietrudno zauważyć jednak, że sama postać wyrażenia jest dość odstręczająca, a poza tym sporo elementów się w nim powtarza – choćby sekwencja dopasowująca pojedynczy znak alfanumeryczny. Poza tym dokładna składnia wyrażeń w danej bibliotece może być niekiedy specyficzna, chociaż podstawy (czyli np. elementy pokazane powyżej) powinny być w zasadzie wszędzie takie same.
Mimo to czasem warto użyć tego narzędzia również w bardziej zaawansowanym celu: parsowania ciągów znaków w celu wydzielenia i odczytania z nich określonych fragmentów. Zapewne nie da się w ten sposób przetworzyć na przykład dokumentu XML czy innego skomplikowanego formatu, lecz w prostszych przypadkach może się to okazać szybsze i wygodniejsze. Alternatywą jest oczywiście samodzielne napisanie parsera, tokenizera czy innego tego typu obleśnego automatu stanów :)
Po Internecie krąży coraz więcej botów, których głównym zadaniem jest spamowanie, czego dokonują, automatycznie wypełniając przeróżne formularze na stronach WWW. Można się przed nimi bronić na wiele sposobów – na tej stronie zamieszczenie komentarza wymaga na przykład odpowiedzi na proste pytanie z gatunku arytmetycznych :) I choć komputery liczą doskonale, na tym zadaniu mogą się pośliznąć.
Chyba popularniejszą metodą jest CAPTCHA obrazkowa, która jednak też czasem potrafi sprawiać problemy… prawdziwym ludziom, mającym kłopoty z odczytaniem właściwego kodu. Zasadniczo jednak chyba wszyscy się już do takich mechanizmów przyzwyczaili i nie mają kłopotów ani większych oporów przed wykonaniem postawionego przed nimi zadania.
Pod warunkiem oczywiście, że się nie przesadza. A o to wbrew pozorom całkiem prosto. Poniżej mamy doskonały przykład:
Być może takiego testu nie przejdzie żaden istniejący obecnie bot spamerski. Ale zapewne bardziej prawdopodobne jest to, że jakiś odwiedzający o bez wątpienia biologicznym pochodzeniu zniechęci się, widząc coś takiego. W końcu nikt nie lubi udowadniać, że nie jest wielbłądem – przynajmniej niezbyt często.
A więc: CAPTCHA – tak, wypaczenia – nie ;]
Najpierw były luźne spekulacje, potem oficjalne zapowiedzi, długi czas prac i wreszcie ostatnio ujrzeliśmy nawet trochę materiałów filmowych… Ale w końcu jest, długo oczekiwany Wiedźmin ma dzisiaj swoją premierę. Czas z trwogą spojrzeć na wykaz wymagań sprzętowych i zastanowić, co można by w swoim PC-cie usprawnić ;]
Wprawdzie – jak pewnie duża część potencjalnych graczy – nie przeczytałem ani kawałka literatury, na której gra ta jest oparta, ale to jak sądzę nie ma większego znaczenia. Liczę na kawałek dobrze zrobionej gry RPG w “niemodnym” stylu single player, okraszonej oczywiście odpowiednimi efektami graficznymi i dźwiękowymi. I jeśli się nie zawiodę, to pewnie częstotliwość dodawania nowych notek może się zmniejszyć :)
Dobrą zasadą programowania obiektowego jest to, że każdy obiekt powinien w miarę możliwości dbać wyłącznie o siebie. Nazywamy to enkapsulacją. W przypadku obiektów na scenie chcielibyśmy więc, aby potrafiły one odrysować się same bez konieczności zakładania czegokolwiek choćby o stanie urządzenia przed wywołaniem metody Render
danego węzła sceny.
Obiekt do samodzielnego narysowania się może jednak potrzebować ustawienia wielu parametrów: stanów renderowania, tekstur czy nawet shaderów. Z jednej strony część z nich może się powtarzać, a z drugiej pobieranie ustawień bezpośrednio od urządzenia przed każdą potencjalną zmianą kosztowałoby o wiele za dużo.
Prostym rozwiązaniem jest tutaj tzw. menedżer stanów, czyli warstwa pośrednicząca. Obiekt ten zachowuje wszystkie już ustawione stany urządzenia i kontroluje każde żądanie zmiany z zapisanymi wcześniej wartościami. Faktyczny stan urządzenia jest modyfikowany tylko wówczas, gdy nowa wartość jest rzeczywiście różna od starej.
Stworzenie takiego menedżera pozwala więc odciążyć nieco urządzenie zajęte ciągłym przełączaniem stanów w przypadku, gdy zgodnie ze słuszną filozofią OOPu każdy węzeł sceny renderuje się, dbając wyłącznie o siebie. Jedyną niedogodnością jest to, że w naszym menedżerze należy skopiować większość interfejsu urządzenia DirectX – a przynajmniej tę jego część, którą używamy. Jest to jednak potrzebne, aby w połączeniu z sortowaniem fragmentów geometrii sceny względem materiałów uzyskać jako taką wydajność całości.
Tworzenie oprogramowania nie jest łatwe. Zwłaszcza, jeżeli mówimy tu o komercyjnym jego wytwarzaniu, gdzie mamy przecież “nieprzekraczalne” (przynajmniej w teorii) terminy i takież koszty. Dlatego właśnie powstała inżynieria oprogramowania, która ma na celu uczynienie tego procesu bardziej systematycznym i przewidywalnym.
Większość modeli zakłada jednak całe mnóstwo dodatkowej pracy, którą należy wykonać przed, po i w trakcie zasadniczej części tworzenia – czyli implementacji. Jest to głównie produkowanie różnej maści dokumentów, wypełnianie dziwnych tabelek, rysowanie wykresów rzekomo pomocnych w szacowaniu kosztów przyszłych przedsięwzięć, i tym podobne. Jakie daje to korzyści?… Chyba najlepiej odpowiada pewna obserwacja dotycząca jednej z metod szacowania kosztów właśnie. Otóż przy jej użyciu mamy “aż” 25% szansy na to, że nasze przewidywania będą się różniły od rzeczywistości “tylko” o co najwyżej 25%. Innymi słowy, w trzech przypadkach na cztery moglibyśmy równie dobrze wziąć wszystkie liczby z sufitu :)
Zatem komercyjne tworzenie oprogramowania to rzeczywiście sport dla odważnych, ale parę lat temu było dość głośno o pewnej technice, która paradoksalnie jest jak najdalsza od wszelkiego formalizmu na siłę wrzucanego do inżynierii oprogramowania. Nazywa się ona – nomen omen – programowaniem ekstremalnym (XP) i faktycznie jest dość drastyczna :) Prawdopodobnie jest ona najbardziej znana z tego, że programuje się w parach: jedna osoba pisze kod, a druga ją kontroluje, wnosi poprawki, zadaje pytania i odpowiada na nie, itd. Ważniejsze jest jednak to, że cała ta metodologia (tak, bardzo mądre słowo) jest chyba najbardziej “programistyczna” ze wszystkich – no może amatorskim kodzeniem ‘na hurra’. Tutaj przede wszystkim pisze się kod: kod testów – bardzo ważny, kod właściwy, kod służący wypróbowywaniu różnych rozwiązań, kod służący do komunikacji między członkami zespołu… Kod zresztą chyba zastępuje nawet projekt, który często nie jest zbyt szczegółowy albo nawet kompletny, lecz rodzi się z czasem. Najważniejsze jest tu bowiem pisanie kodu, realizowanie poszczególnych wytycznych tak, aby jak najszybciej cokolwiek działało i żeby potem okres “rozgrzebania” kodu między kolejnymi zmianami był jak najkrótszy. A żeby jeszcze mieć jako taką pewność, że wynikowy produkt działa, trzeba po prostu testować, testować i jeszcze raz testować – na każdym etapie.
Wygląda interesująco, prawda? Być może wydaje się, że to lekka przesada, że bez porządnego projektu dużo się nie zrobi – i pewnie rzeczywiście prawda jak zwykle leży pośrodku. Ale metody podobne do XP stosowano chyba powszechnie podczas… konkursów Compo organizowanych w czasie konferencji IGK. I niekiedy nawet osiągano zadowalające efekty :)
Może po prostu gdy się zbierze kilku programistów nieobciążonych wiedzą o ‘bardziej profesjonalnych’ metodach zarządzania projektami, to w naturalny sposób wybiorą taką właśnie metodę pracy. A to, że usiłuje się ją systematyzować i wykorzystywać w inżynierii, jest chyba korzyścią dla jednej i drugiej.
W programowaniu też trzeba często podejmować różne trudne decyzje; zwykle dotyczą one kwestii projektowych. Szczególnie złożone robią się one tam, gdzie idee OOPu muszą się spotkać ze sprowadzeniem na ziemię przez wymagania wydajnościowe obecne w programowaniu grafiki i interfejs graficznych API takich jak DirectX.
Na co więc tak narzekam? Otóż chodzi o odpowiednie opakowanie systemu materiałów. Jak wiadomo, materiał to jest taka cecha geometrii, która nie jest zapisana w danych o wierzchołkach – czyli właściwie wszystko, co może być w geometrii interesujące :) Materiał określa więc cechy powierzchni (gładka, bump-mapowana), właściwości świetlne albo nawet tak fundamentalne cechy jak półprzezroczystość lub renderowanie jako siatki (wireframe).
Zakodowanie takiego systemu materiałów zgodnie z regułami programowania obiektowego oznaczałoby przede wszystkim to, że część potoku odpowiedzialna za rysowanie nie musiałaby nawet wiedzieć, z jakiego dokładnie materiału korzysta dany fragment geometrii. Za pomocą metod wirtualnych można by bowiem albo pobrać odpowiednie ustawienia stanów renderowania, albo wręcz kazać materiałowi, aby sam je ustawił.
To da się zrobić. Sęk w tym, że wszystkie te dane trzeba przekazać do shadera, który już taki sprytny nie jest. W rzeczy samej, dopiero od niezbyt w sumie długiego czasu shadery można pisać w czymś, co przypomina język wysokiego poziomu, a o OOPie czy tym bardziej polimorfizmie nawet nie ma co marzyć. Chociaż… w HLSL już teraz do ewentualnego przyszłego użycia zarezerwowano słowo kluczowe class
:)
Na teraz trzeba jednak zdecydować się na rozwiązanie pośrednie, które mniej więcej zadowoli obie strony – elastyczną obiektowość i “sztywny” shader. Osobiście widzę trzy rozwiązania dla organizacji klas(y) materiałów w silniku:
Zapewne to ostatnie rozwiązanie jest najbardziej elastyczne, rzeźnickie i w ogóle “naj” – tyle że jest też najbardziej skomplikowane i zdecydowanie nie chciałbym się za nie zabierać już za pierwszym razem. Dlatego, jak sądzę, powinienem wybrać coś między opcją pierwsza a drugą. Obie są właściwie pewnymi odcieniami tego samego wariantu, w którym możliwe cechy materiału są po prostu wpisane na sztywno w kodzie – zarówno samej aplikacji, jak i shaderów.
W przypadku drugiej opcji istnieje naturalnie tradycyjny dylemat: czy dana cecha zasługuje tylko na osobne pole, czy może wymaga już nowej klasy pochodnej. Myślę jednak, że tutaj można zastosować dość prostą zasadę związania klasy z shaderem. Jeśli więc dwa materiały należą do tej samej klasy, to różnią się tylko wartościami stanów renderowania. Natomiast materiały z różnych klas różnią się samym zestawem stanów, jakie można dla nich ustawiać; potrzebują zatem innych shaderów.
Przez ostatnie tygodnie występowało u nas zjawisko, które ciężko było zignorować. Każda taka próba była zresztą zupełnie sprzeczna z intencjami tych, którzy za owym zjawiskiem stoją. Podstawowym założeniem rzeczonego procederu było bowiem przede wszystkim zwrócenie na siebie powszechnej uwagi, wzbudzenie zainteresowania, chociaż ostatecznie głównym osiągnięciem było chyba tylko powodowanie niezdrowych emocji. Tak, mówię oczywiście o kończącej się właśnie kampanii wyborczej. I zanim rozpocznie się ustawowy, 44-godzinny okres ciszy, nie zaszkodzi się nad tym przez chwilę zastanowić (gwoli ścisłości: na pewno mi to nie zaszkodzi ;D).
Już wiele razy słyszałem, że jak dotąd to najważniejsze wybory w historii III (IV?) RP i pewnie jest w tym sporo racji. Świadczy o tym choćby fakt, że według sondaży zdecydowana większość obywateli planuje w tym roku pójście do urn, co u nas nie zdarza się zbyt często. Pewien (i to, jak sądzę, spory) wpływ na ten stan rzeczy może mieć również wysyp różnego rodzaju serwisów zachęcających właśnie do głosowania.
Zaczęły się one pojawiać wkrótce po ogłoszeniu decyzji o wyborach i każdy z nich stara się chyba prześcignąć pozostałe w znajdowaniu różnych powodów, dla których warto pojutrze oddać swój głos na wybraną partię. Do ciekawszych stron tego typu należą chociażby:
Jeżeli zaś jesteśmy już przekonani, że głosować pójdziemy, to wypadałoby jeszcze wiedzieć, na kogo :) Naturalnie malkontenci zawsze mówią, że “znowu nie ma na kogo głosować”, ale prawie połowa społeczeństwa jakoś sobie z tym wyborem radzi. Można rzucać monetą, patrzeć na sondaże, zastanawiać się który lider ładniej wygląda itp., lecz chyba lepiej kierować się programami (nawet jeśli to ‘tylko obietnice’).
A jeśli nie mamy ochoty na ich studiowanie, to i tutaj pomaga nam Internet. Serwis Wybory 2007 Wirtualnej Polski oraz strona twojwybor.pl oferują testy, składające się odpowiednio z 20 i 30 pytań, na które można odpowiedzieć i poznać przystawalność naszych opinii do programów różnych partii politycznych. Jednoznacznej odpowiedzi zapewne nie uzyskamy, lecz dla zupełnie niezdecydowanych rezultat może być przydatny.
Tak czy siak, na coś wypadałoby się zdecydować. A przy okazji można też pozazdrościć tym, którzy głosować jeszcze nie mogą i takich dylematów nie muszą rozstrzygać :)
Co do obrazka po prawej, to niniejszym informuję, że widoczna na nim kolejność symboli komitetów wyborczych wynika wyłącznie porządku alfabetycznego ich nazw :)