<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0"
	xmlns:content="http://purl.org/rss/1.0/modules/content/"
	xmlns:wfw="http://wellformedweb.org/CommentAPI/"
	xmlns:dc="http://purl.org/dc/elements/1.1/"
	xmlns:atom="http://www.w3.org/2005/Atom"
	xmlns:sy="http://purl.org/rss/1.0/modules/syndication/"
	xmlns:slash="http://purl.org/rss/1.0/modules/slash/"
	xmlns:itunes="http://www.itunes.com/dtds/podcast-1.0.dtd"
	xmlns:media="http://search.yahoo.com/mrss/"
>

<channel>
	<title>TeMPOraL&#039;s devBlog</title>
	<atom:link href="http://temporal.pr0.pl/devblog/feed/" rel="self" type="application/rss+xml" />
	<link>http://temporal.pr0.pl/devblog</link>
	<description>(devblog :about (Lisp C++ gamedev)</description>
	<lastBuildDate>Sun, 01 Aug 2010 00:16:22 +0000</lastBuildDate>
	<generator>http://wordpress.org/?v=2.9.1</generator>
	<language>pl</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
		<!-- podcast_generator="podPress/8.8" - maintenance_release="8.8.4" -->
		<copyright>2006-2007 </copyright>
		<managingEditor>temporal.pl@gmail.com (TeMPOraL&#039;s devBlog)</managingEditor>
		<webMaster>temporal.pl@gmail.com (TeMPOraL&#039;s devBlog)</webMaster>
		<category>posts</category>
		<ttl>1440</ttl>
		<itunes:keywords></itunes:keywords>
		<itunes:subtitle></itunes:subtitle>
		<itunes:summary>C++, programowanie gier i nauka w zastosowaniach</itunes:summary>
		<itunes:author>TeMPOraL&#039;s devBlog</itunes:author>
		<itunes:category text="Society &amp; Culture"/>
		<itunes:owner>
			<itunes:name>TeMPOraL&#039;s devBlog</itunes:name>
			<itunes:email>temporal.pl@gmail.com</itunes:email>
		</itunes:owner>
		<itunes:block>No</itunes:block>
		<itunes:explicit>no</itunes:explicit>
		<itunes:image href="http://temporal.pr0.pl/devblog/wp-content/plugins/podpress/images/powered_by_podpress_large.jpg" />
		<image>
			<url>http://temporal.pr0.pl/devblog/wp-content/plugins/podpress/images/powered_by_podpress.jpg</url>
			<title>TeMPOraL&#039;s devBlog</title>
			<link>http://temporal.pr0.pl/devblog</link>
			<width>144</width>
			<height>144</height>
		</image>
		<item>
		<title>Dlaczego Lisp?</title>
		<link>http://temporal.pr0.pl/devblog/2010/08/01/dlaczego-lisp/</link>
		<comments>http://temporal.pr0.pl/devblog/2010/08/01/dlaczego-lisp/#comments</comments>
		<pubDate>Sun, 01 Aug 2010 00:15:46 +0000</pubDate>
		<dc:creator>Jacek Złydach</dc:creator>
				<category><![CDATA[Informatyka]]></category>
		<category><![CDATA[Rozwój osobisty]]></category>
		<category><![CDATA[Common Lisp]]></category>
		<category><![CDATA[Lisp]]></category>
		<category><![CDATA[Scheme]]></category>
		<category><![CDATA[SICP]]></category>

		<guid isPermaLink="false">http://temporal.pr0.pl/devblog/?p=1056</guid>
		<description><![CDATA[Wielokrotnie byłem pytany, dlaczego interesuję się Lispem, co mnie skłoniło do jego nauki i &#8220;co w nim jest takiego fajnego&#8221;. W tym tekście chcę odpowiedzieć na te pytania i wyjaśnić, czego szukam w tym języku i jak jego nauka wpłynęła na mnie do tej pory.
Historia zaczęła się rok temu, gdy aktywnie prokrastynując celem ucieczki od [...]]]></description>
			<content:encoded><![CDATA[<p>Wielokrotnie byłem pytany, dlaczego interesuję się Lispem, co mnie skłoniło do jego nauki i &#8220;co w nim jest takiego fajnego&#8221;. W tym tekście chcę odpowiedzieć na te pytania i wyjaśnić, czego szukam w tym języku i jak jego nauka wpłynęła na mnie do tej pory.</p>
<p>Historia zaczęła się rok temu, gdy aktywnie prokrastynując celem ucieczki od projektu, który został mi &#8220;na wrzesień&#8221;, trafiłem na interesujący post na devBlogach &#8211; <a href="http://www.devblogi.pl/2009/09/niebezpieczne-java-szkoy.html">&#8220;Niebezpieczne Java-Szkoły&#8221;</a>. Sam artykuł, którego lekturę gorąco polecam, wspomina o Lispie w kilku miejscach, ale jedna wzmianka okazała się decydująca. <strong><a href="http://www.paulgraham.com/avg.html">&#8220;Beating the Averages&#8221;</a> Paula Grahama</strong>. </p>
<p>Tak, słyszałem wcześniej o Lispie. To ten język, w którym nawiasy tworzą większość kodu. Wygląda jak mleko z powrzucanymi obciętymi paznokciami. To najdziwniejszy język, w jakim można pisać kod, zaraz po <a href="http://pl.wikipedia.org/wiki/Brainfuck">BF</a> i <a href="http://pl.wikipedia.org/wiki/Whitespace">Whitespace</a>. Tego typu opinie. A tu nagle pewien człowiek twierdzi w porywającym eseju, że <strong>Lisp jest najpotężniejszym językiem programowania dostępnym obecnie</strong>. I przedstawia argumenty. To przykuwa uwagę.</p>
<p><strong>Blub programmer</strong><br />
Jedną z najważniejszych myśli eseju Paula Grahama jest to, że <strong>języki programowania różnią się w mocy</strong>. Myślę, że intuicyjnie zdawałem sobie z tego sprawę od jakiegoś czasu, ale nigdy nie myślałem o tym świadomie. Właściwie, muszę się do czegoś przyznać. Do tego momentu, zgodnie z terminologią eseju, byłem typowym &#8220;Blub programmerem&#8221; (jeżeli Czytelniku <a href="http://www.paulgraham.com/avg.html">jeszcze nie przeczytałeś tego eseju</a>, to gorąco zachęcam do lektury). Mój ulubiony język programowania (tak się złożyło, że był nim C++) <em>jest najlepszy. Wszystko co jest na niższym poziomie to niepotrzebne męczenie się. Wszystko, co jest na wyższym poziomie (zwłaszcza Java, za którą nie przepadałem) i tak można zaimplementować w C++.</em> Właściwie cały mój świat programistyczny skupiał się wokół C++, Javy (która jak dla mnie jest <a href="http://en.wikipedia.org/wiki/Software_bloat">bloatware&#8217;m</a>), C# i PHP. Programowanie funkcyjne? Nie słyszałem nigdy o czymś takim.</p>
<p><strong>Wielkie obietnice</strong></p>
<blockquote><p>Lisp is worth learning for the profound enlightenment experience you will have when you finally get it; that experience will make you a better programmer for the rest of your days, even if you never actually use Lisp itself a lot. </p></blockquote>
<p>Powyższy cytat, przytoczony przez Paula a pochodzący z <a href="http://catb.org/esr/faqs/hacker-howto.html">&#8220;How To Become A Hacker&#8221;</a> Erica Stevena Raymonda, był intrygujący. Przeczytałem więc inne eseje &#8211; w tym <a href="http://www.paulgraham.com/icad.html">&#8220;Revenge of the Nerds&#8221;</a>, <a href="http://www.paulgraham.com/diff.html">&#8220;What Made Lisp Different&#8221;</a>. Na innej stronie znalazłem też <a href="http://www.defmacro.org/ramblings/lisp.html">&#8220;The Nature of Lisp&#8221;</a>. Wszystko to przyswojone &#8220;na raz&#8221; robi mętlik w głowie, ale pewne trendy zaczynały stawać się widoczne.</p>
<p>Widziałem trochę kłótni, dysput i artykułów na temat wyższości jednych języków nad drugimi (C++ vs. Delphi i C++ vs. Java były moimi ulubionymi sporami). Zwykle fani danego języka twierdzą, że jest on lepszy od języka przeciwników. Ale nigdy wcześniej nie widziałem, żeby ktoś twierdził, że ich język jest <strong>naj</strong>lepszy, <strong>naj</strong>potężniejszy, że <strong><a href="http://www.gnu.org/fun/jokes/eternal-flame.html">Bóg</a> <a href="http://www.youtube.com/watch?v=5-OjTPj7K54">stworzył</a> za jego pomocą <a href="http://xkcd.com/224/">wszechświat</a></strong>. Tylko Lisp odważył się zająć miejsce ponad wszystkimi. Zwykła arogancja? A może uzasadniona<a href="#POST_WHYLISP_REF_1" name="POST_WHYLISP_MT_1">*</a>?</p>
<p>W dużym skrócie, najważniejsze argumenty stawiane przez zwolenników Lispu to:</p>
<ul>
<li><strong>Język ten jest unikatowy w swojej możliwości wyrażania myśli przez programistę.</strong> Dzięki umiejętności przepisywania własnego kodu źródłowego w czasie kompilacji można zmieniać sam język w taki sposób, żeby dopasowywał się do rozwiązywanego problemu. Programując w Lispie człowiek używa najpotężniejszego języka programowania dostępnego obecnie.</li>
<li><strong>Sam proces poznawania i zrozumienia Lispu czyni człowieka lepszym programistą</strong>, niezależnie od języka jakiego przyjdzie mu później używać (ten argument zdaje się też pasować do teoretycznych, matematycznych stron informatyki; biorąc pod uwagę <a href="http://paulgraham.com/rootsoflisp.html">pochodzenie Lispu</a>, może to nie jest zbieg okoliczności).</li>
<li><strong>Kolejne języki programowania powstające obecnie stopniowo zdążają do Lispu</strong>, implementując różne cechy, które w tym ostatnim były dostępne od wielu lat. Nauka Lispu jest więc strategicznie najlepszą opcją, bo język ten zawiera wszystkie ważne elementy semantyczne innych języków, a wciąż ma cechy, których nikt inny nie powielił (np. makra).</li>
</ul>
<p>To wszystko brzmiało dla mnie bardzo intrygująco &#8211; zwłaszcza, że nie chciałem (i dalej nie chcę) skończyć jako klepacz biznesowego kodu w Javie. Bardzo zaciekawiony postanowiłem więc nauczyć się Lispu i sprawdzić doświadczalnie, czy te wszystkie zapewnienia jego zwolenników są uzasadnione.</p>
<p><strong>Eksperyment</strong><br />
Przez ostatni rok uczyłem się Lispu w wolnych chwilach (czasem nawet spychając &#8216;przyziemne sprawy uczelni&#8217; na dalszy plan). Chociaż póki co zdążyłem napisać w nim jedynie <a href="http://temporal.pr0.pl/devblog/projekty/cloze-call/">małą grę</a> i kilka drobnych narzędzi, to mogę dziś powiedzieć, że odniosłem wiele korzyści, często nie związanych stricte z naturą języka Lisp.</p>
<ul>
<li><strong>Odkryłem, że tam daleko, poza C++, Javą i C# jest cały wielki świat programowania.</strong> Że programowanie zorientowane obiektowo nie jest receptą na wszystko (świadomie bądź nie, ale wcześniej w to wierzyłem); są inne paradygmaty programowania, które w wielu miejscach są bardziej odpowiednie.</li>
<li><strong>Poznałem programowanie funkcyjne.</strong> Chociaż Lisp <strong>nie jest</strong> językiem funkcyjnym (jest wieloparadygmatowy), to wiele wzorców pisania kodu &#8211; związanych z pracą na listach i drzewach oraz funkcjach wyższego rzędu i wyrażeniach lambda &#8211; stanowi podstawę funkcyjnego tworzenia oprogramowania (która to jest tematem na zupełnie osobny wpis). Gdyby nie Lisp, najprawdopodobniej w ogóle nie zainteresowałbym się Erlangiem, i nie pisałbym w nim dziś oprogramowania.</li>
<li><strong>Zrozumiałem, że C++ w programowaniu zorientowanym obiektowo nie mówi ostatniego słowa.</strong> Common Lisp tak na prawdę pokazał mi, że <a href="http://en.wikipedia.org/wiki/Common_Lisp_Object_System#Meta-Object_Protocol">model obiektowy</a> może być zrobiony wokół zupełnie innych założeń, <a href="http://temporal.pr0.pl/devblog/2010/05/04/clos-jedynym-slusznym-systemem-obiektowym/">być większy</a> i <a href="http://en.wikipedia.org/wiki/Multiple_dispatch">bogatszy</a>.</li>
<li><strong>Nabrałem wstrętu do pisania rzeczy, które powinien pisać za mnie komputer.</strong> Jak powiedział Olin Shivers, <em>&#8220;I object to doing things that computers can do.&#8221;</em> Przykładowo, wśród programistów C/C++ (a także innych języków, np. Erlanga) znana jest niechęć do używania makr preprocesora. W wielu przypadkach jest ona uzasadniona, jednak dzięki &#8220;Lispowemu sposobowi myślenia&#8221; zacząłem traktować preprocesor jako przydatne narzędzie generowania kodu w czasie kompilacji.</li>
</ul>
<p>Nauka Lispu miała też potężny efekt uboczny:</p>
<ul>
<li><strong>Zacząłem dostrzegać wpływy Lispu wszędzie.</strong> Tak, wiem &#8211; niektórych to denerwuje. Odruchowe zwracanie uwagi, że &#8220;XYZ zgapiło to z Lispu!&#8221;. Te skojarzenia nie są jednak nieuzasadnione. Dobrze oddaje to <a href="http://en.wikipedia.org/wiki/Greenspun%27s_Tenth_Rule">&#8220;10-ta zasada programowania Greenspuna&#8221;</a>:<br />
<blockquote><p>Any sufficiently complicated C or Fortran program contains an ad hoc, informally-specified, bug-ridden, slow implementation of half of Common Lisp.</p></blockquote>
<p>Na to, jak ten sposób myślenia udziela się programistom Lispu, samokrytycznie zwrócił uwagę Slobodan Blazeski w <a href="http://tourdelisp.blogspot.com/2008/03/lisper-first-look-at-haskell.html">artykule o Haskelu</a>:</p>
<blockquote><p>(&#8230;) The reasons vary but it probably has something with lispers&#8217; being spoiled brats. They&#8217;re damn hard to impress. You show them the cool feature that your favourite language has and they either already have it, have something better or they&#8217;ve already seen it and decided it&#8217;s not such a good idea as you might think.</p></blockquote>
</li>
</ul>
<p><strong>A droga długa jest; nie wiadomo, czy ma kres&#8230;</strong><br />
W dalszym ciągu intrygują mnie możliwości Lispu, których jeszcze w ogóle nie poznałem. W szczególności makra i metaprogramowanie. Chciałbym też dokładniej sprawdzić, czy Lisp jest faktycznie tak wygodnym narzędziem do pisania eksperymentalnych aplikacji jak pisał Paul Graham<a href="#POST_WHYLISP_REF_2" name="POST_WHYLISP_MT_2">**</a>. Przede mną jeszcze daleka droga. W dalszym ciągu nie umiem używać makr ani <a href="http://www.gigamonkeys.com/book/beyond-exception-handling-conditions-and-restarts.html">rewelacyjnego systemu wyjątków w Common Lisp</a>. W szczególności, jeżeli chodzi o lekturę, to chciałbym skończyć <a href="http://mitpress.mit.edu/sicp/">SICP</a>, a następnie przeczytać <a href="http://www.paulgraham.com/onlisptext.html">&#8220;On Lisp&#8221;</a>, <a href="http://letoverlambda.com/index.cl">&#8220;Let Over Lambda&#8221;</a> i <a href="http://en.wikipedia.org/wiki/The_Art_of_the_Metaobject_Protocol">&#8220;Art of Metaobject Protocol&#8221;</a>. Do dnia dzisiejszego Lisp dał mi jednak bardzo dużo, i nie żałuję, że zacząłem się go uczyć. Dzięki niemu wyszedłem z &#8220;zastoju&#8221; informatycznego i odkryłem wiele nowych dziedzin i rozwiązań, o których wcześniej nawet mi się nie śniło.</p>
<p><strong>(przypisy)</strong><br />
<a href="#POST_WHYLISP_MT_1" name="POST_WHYLISP_REF_1">*</a> &#8211; Podobnie do mnie czuł się pewien człowiek, którego Paul Graham <a href="http://paulgraham.com/quotes.html">cytuje</a> na swojej stronie</p>
<blockquote><p>&#8220;I have heard more than one LISP advocate state such subjective comments as, &#8220;LISP is the most powerful and elegant programming language in the world&#8221; and expect such comments to be taken as objective truth. I have never heard a Java, C++, C, Perl, or Python advocate make the same claim about their own language of choice.&#8221;</p>
<p>- A guy on Slashdot. What theory fits this data?</p></blockquote>
<p><a href="#POST_WHYLISP_MT_2" name="POST_WHYLISP_REF_2">**</a> &#8211; W czasach, gdy Paul pisał swój esej, języki takie jak Python, Perl czy Ruby nie były powszechnie używane w taki sposób jak dzisiaj; obecna ilość i rozmiar projektów powstających w językach dynamicznie typowanych wysokiego poziomu, posiadających REPL jest argumentem za tym, że miał rację.</p>
]]></content:encoded>
			<wfw:commentRss>http://temporal.pr0.pl/devblog/2010/08/01/dlaczego-lisp/feed/</wfw:commentRss>
		<slash:comments>1</slash:comments>
		</item>
		<item>
		<title>RSS &#8211; co to jest, i dlaczego warto korzystać z tego na co dzień?</title>
		<link>http://temporal.pr0.pl/devblog/2010/07/25/rss-co-to-jest-i-dlaczego-warto-korzystac-z-tego-na-codzien/</link>
		<comments>http://temporal.pr0.pl/devblog/2010/07/25/rss-co-to-jest-i-dlaczego-warto-korzystac-z-tego-na-codzien/#comments</comments>
		<pubDate>Sun, 25 Jul 2010 12:58:18 +0000</pubDate>
		<dc:creator>Jacek Złydach</dc:creator>
				<category><![CDATA[Informatyka]]></category>
		<category><![CDATA[Pragmatyzm]]></category>
		<category><![CDATA[ATOM]]></category>
		<category><![CDATA[page2rss]]></category>
		<category><![CDATA[porady]]></category>
		<category><![CDATA[RSS]]></category>

		<guid isPermaLink="false">http://temporal.pr0.pl/devblog/?p=1235</guid>
		<description><![CDATA[Wielkim zaskoczeniem było dla mnie zorientowanie się, że sporo osób, które znam &#8211; w tym ludzie z szeroko rozumianej &#8220;branży IT&#8221; &#8211; nie używa, bądź nawet nie słyszało o RSS*. W dobie zasypującej nas, rosnącej lawiny informacji narzędzie to staje się coraz bardziej pomocne. W telegraficznym skrócie, kanały RSS pozwalają nam zobaczyć skrót nowości / [...]]]></description>
			<content:encoded><![CDATA[<p><img src="http://temporal.pr0.pl/devblog/download/varia/128px-Feed-icon.svg.png" alt="RSS 2.0" align="left" style="margin-right: 7px;" />Wielkim zaskoczeniem było dla mnie zorientowanie się, że sporo osób, które znam &#8211; w tym ludzie z szeroko rozumianej &#8220;branży IT&#8221; &#8211; nie używa, bądź nawet nie słyszało o RSS<a href="#POST_RSS_REF_1" name="POST_RSS_MT_1">*</a>. W dobie zasypującej nas, rosnącej lawiny informacji narzędzie to staje się coraz bardziej pomocne. W telegraficznym skrócie, kanały RSS pozwalają nam zobaczyć skrót nowości / zmian na stronach bez konieczności odwiedzania tych ostatnich. Aktualizacje &#8220;przychodzą do czytnika&#8221;, który przedstawia je w podobny sposób jak pocztę elektroniczną. Innymi słowy, <strong>RSS oszczędza nam czas i zmniejsza stres związany z pamiętaniem o regularnym sprawdzaniu różnych serwisów</strong>. Strony publikujące kanały RSS zwykle łatwo poznać po <a href="http://temporal.pr0.pl/devblog/download/varia/128px-Feed-icon.svg.png">charakterystycznej, pomarańczowej ikonce</a> obok pasku adresu, którą wyświetlają niektóre przeglądarki.</p>
<p>Kanały RSS subskrybuje się za pomocą wszelkiego rodzaju czytników RSS &#8211; dostępnych <a href="http://reader.google.com/">on-line</a>, <a href="http://www.google.com/search?q=rss+reader+download">off-line</a> czy nawet wbudowanych w przeglądarkę. Subskrybcja ta nabiera prawdziwej mocy w połączeniu z czytnikami wbudowanymi w programy pocztowe &#8211; można wtedy przeglądać pocztę i większość istotnych dla nas informacji w sieci wewnątrz jednego programu. Jest to szczególnie wygodne dla osób stosujących w życiu coś <a href="http://biz.blox.pl/2009/06/Wakacyjny-kurs-ZTD.html">mniej lub bardziej</a> przypominającego <a href="http://pl.wikipedia.org/wiki/Getting_Things_Done">GTD</a> &#8211; wtedy wszystkie ważne informacje i sieciowe ciekawostki same trafiają do miejsca, gdzie znaleźć się powinny &#8211; do skrzynki spraw przychodzących.</p>
<p>Potężną zaletą &#8220;korzystania z RSS-ów&#8221; jest <strong>zwolnienie z obowiązku pamiętania o sprawdzaniu zmian na stronach</strong>. Każda rzecz, o której trzeba pamiętać zajmuje nam &#8220;RAM&#8221; i zabiera &#8220;cykle procesora&#8221; w głowie, które lepiej przeznaczyć na przykład na pracę, którą aktualnie wykonujemy. Pół biedy, jeżeli rozprasza nas regularna, acz przelotna myśl o sprawdzeniu, czy znajomy blogger nie napisał nowego postu. Są sytuacje, w której wymaga się od osób, by były na bieżąco z informacjami &#8211; na przykład sekretariaty czy dyrekcje szkół powinny wiedzieć o wszystkim, co ogłaszają kuratoria.<strong> Konsekwencje przeoczenia jakiejś informacji mogą być ogromne</strong>; ryzyko to jest jednak znacznie mniejsze, gdy wszystkie aktualizacje &#8220;wpadają&#8221; w jedno miejsce obok poczty elektronicznej.</p>
<p><strong>Tam, gdzie RSS-ów nie ma&#8230;</strong><br />
Zdarza się, że autorzy strony <a href="http://www.eaie.agh.edu.pl/">zapomną, lub z innych powodów nie umieszczą na stronie kanału RSS</a>. W takiej sytuacji pomóc mogą serwisy typu <a href="http://page2rss.com/">page2rss</a>, które &#8220;przerabiają&#8221; zmiany na stronach na kanał RSS. Zrobiłem tak ze stroną wydziału uczelni, na której studiuję i w końcu już jestem na bieżąco z informacjami organizacyjnymi.</p>
<p>Oprócz zwykłych stron internetowych serwujących informacje są też przeróżne usługi, które oferują bądź powinny oferować kanał RSS. Przykładem jest serwis <a href="http://github.com">GitHub</a>, który udostępnia w ten sposób historię ostatnich commit&#8217;ów. Osobiście też bardzo zadowolony jestem z kanału RSS z pewnego serwera FTP współdzielonego przez dużą grupę osób &#8211; ale takie &#8220;dobrodziejstwo&#8221; wymagało już odrobinę brudnej zabawy z PHP. Osobiście chciałbym zobaczyć kiedyś kanał RSS z &#8220;Ściany&#8221; (ang. Wall) na <a href="http://facebook.pl">Facebook</a>&#8216;u; podobno ktoś podejmował takie próby, ale <a href="http://www.readwriteweb.com/archives/facebook_shuts_down_rss_feed_app.php">Facebook je zwalczył</a> (&#8220;prywatność&#8221;, takie tam). Byłaby jedna strona mniej do codziennego sprawdzania.</p>
<p><strong>Negatywna strona RSSów</strong><br />
Oczywiście, &#8220;nie ma róży bez kolców&#8221; &#8211; głównym problemem RSS-ów jest coś, co jest też ich największą zaletą &#8211; nowa treść trafia nam &#8220;prosto przed nos&#8221;. Mając wszystkie ciekawe teksty i nowinki w jednym miejscu można bardzo łatwo zacząć &#8211; <a href="http://www.paulgraham.com/procrastination.html">mniej lub bardziej szkodliwie</a> &#8211; <a href="http://pl.wikipedia.org/wiki/Prokrastynacja">prokrastynować</a>. Jak każde narzędzie, jakie dają nam nauka i technika, tak i kanałów RSS należy używać rozważnie &#8211; ale to już nie jest temat tego postu.</p>
<p><a href="#POST_RSS_MT_1" name="POST_RSS_REF_1">*</a> &#8211; RSS nie jest jedynym protokołem tzw. <a href="http://en.wikipedia.org/wiki/Web_syndication">syndykacji w Internecie</a>. Niemniej jednak termin RSS jest używany czasem w rozumieniu różnych protokołów, podobnie jak w przypadku obuwia &#8211; &#8220;adidasy&#8221; niekoniecznie muszą być wyprodukowane przez firmę Adidas. W tym znaczeniu używam skrótowca RSS w powyższym tekście.</p>
]]></content:encoded>
			<wfw:commentRss>http://temporal.pr0.pl/devblog/2010/07/25/rss-co-to-jest-i-dlaczego-warto-korzystac-z-tego-na-codzien/feed/</wfw:commentRss>
		<slash:comments>2</slash:comments>
		</item>
		<item>
		<title>C++, Lisp&#8230; Erlang?</title>
		<link>http://temporal.pr0.pl/devblog/2010/07/20/c-lisp-erlang/</link>
		<comments>http://temporal.pr0.pl/devblog/2010/07/20/c-lisp-erlang/#comments</comments>
		<pubDate>Tue, 20 Jul 2010 21:04:26 +0000</pubDate>
		<dc:creator>Jacek Złydach</dc:creator>
				<category><![CDATA[Informatyka]]></category>
		<category><![CDATA[Erlang]]></category>
		<category><![CDATA[programowanie funkcyjne]]></category>

		<guid isPermaLink="false">http://temporal.pr0.pl/devblog/?p=1298</guid>
		<description><![CDATA[Jest pewien język, którego uczyłem się ostatnimi czasy praktycznie równolegle z Lispem, a o którym nic nie pisałem na łamach tego blogu. Traktowałem go jako coś pobocznego, jako dodatkową możliwość użycia pewnych świeżo poznanych, lispowych koncepcji. Teraz jednak odbywam praktyki w firmie używającej i propagującej tenże język. Mowa oczywiście o Erlangu. Jako, że teraz pracuje [...]]]></description>
			<content:encoded><![CDATA[<p><img src="http://temporal.pr0.pl/devblog/download/varia/erlang.gif" alt="Erlang" align="left" style="margin-right: 7px;" />Jest pewien język, którego uczyłem się ostatnimi czasy praktycznie równolegle z Lispem, a o którym nic nie pisałem na łamach tego blogu. Traktowałem go jako coś pobocznego, jako dodatkową możliwość użycia pewnych świeżo poznanych, lispowych koncepcji. Teraz jednak odbywam praktyki w <a href="http://www.erlang-solutions.com/">firmie używającej i propagującej tenże język</a>. Mowa oczywiście o <strong><a href="http://erlang.org/">Erlangu</a></strong>. Jako, że teraz pracuje z nim na codzień, język ten będzie często gościł na tym blogu.</p>
<p>Gdybym miał podsumować Erlanga w kilku hasłach, byłyby to: <strong>niezawodność, współbieżność (concurrency), lekkie procesy (lightweight processes), <a href="http://en.wikipedia.org/wiki/Functional_programming">język funkcyjny</a>, <a href="http://temporal.pr0.pl/devblog/2009/09/15/repl-i-php-czyli-telnetem-do-rakiety/">interaktywność</a></strong>. Język ten powstał w laboratoriach firmy <a href="http://en.wikipedia.org/wiki/Ericsson">Ericsson</a> (tak, tej od <a href="http://en.wikipedia.org/wiki/Sony_Ericsson">Sony Ericsson</a>) i pozwolił jej osiągnąć <a href="http://www.adelcogroup.com/EricssonAXD301.htm">w jednym ze swoich projektów</a> niezawodność tzw. <a href="http://en.wikipedia.org/wiki/Nines_%28engineering%29">nine nines</a>, czyli 99.9999999% &#8211; innymi słowy, w ciągu roku system był niesprawny nie dłużej niż ok. <a href="http://www.wolframalpha.com/input/?i=%281-0.999999999%29+*+3600*24*365">cztery setne sekundy</a>! Taki poziom bezawaryjności jest osiąganlny dzięki pewnym bardzo ciekawym koncepcjom, o których chciałbym napisać w przyszłości.</p>
<p>Nie będę się w tym poście rozpisywał o innych mniej lub bardziej znanych projektach zrealizowanych w Erlangu (w o tym klasycznych, używanych wręcz marketingowo przykładach Facebook&#8217;a czy Amazonu). Warto moim zdaniem wspomnieć tu jeszcze o jednym &#8211; edytorze modeli 3D o nazwie <a href="http://en.wikipedia.org/wiki/Wings_3D">Wings 3D</a>, napisanym w całości w Erlangu. Jest to o tyle specyficzny przykład, że Erlang jako język nie jest stworzony do pisania aplikacji przeprowadzających ogromne ilości obliczeń matematycznych w czasie rzeczywistym, a jego funkcyjność średnio pomaga przy programach trzymających duże ilości wewnętrznego stanu. A do czego ten język się nadaje najlepiej i jakie ciekawe rozwiązania zostały dla niego pomyślane &#8211; to już temat na kolejne posty.</p>
]]></content:encoded>
			<wfw:commentRss>http://temporal.pr0.pl/devblog/2010/07/20/c-lisp-erlang/feed/</wfw:commentRss>
		<slash:comments>2</slash:comments>
		</item>
		<item>
		<title>Funktory &#8211; traktowanie obiektów jak funkcje w Common Lisp</title>
		<link>http://temporal.pr0.pl/devblog/2010/06/14/funktory-traktowanie-obiektow-jak-funkcje-w-common-lisp/</link>
		<comments>http://temporal.pr0.pl/devblog/2010/06/14/funktory-traktowanie-obiektow-jak-funkcje-w-common-lisp/#comments</comments>
		<pubDate>Mon, 14 Jun 2010 01:34:15 +0000</pubDate>
		<dc:creator>Jacek Złydach</dc:creator>
				<category><![CDATA[Informatyka]]></category>
		<category><![CDATA[Matematyka]]></category>
		<category><![CDATA[C++]]></category>
		<category><![CDATA[Common Lisp]]></category>
		<category><![CDATA[Lisp]]></category>

		<guid isPermaLink="false">http://temporal.pr0.pl/devblog/?p=1251</guid>
		<description><![CDATA[Funktorem nazywamy obiekt, który może być wywoływany jak funkcja. Często chcemy też, by wywołanie takiego funktora przypominało składnią wywołanie normalnej funkcji w danym języku programowania.
W niektórych językach (np. w C++, o czym niedawno pisałem) funktorów używa się do naprawienia braku naturalnego wsparcia dla funkcji first-class. Jednak Common Lisp takie wsparcie ma, więc zasadnicze pytanie brzmi: [...]]]></description>
			<content:encoded><![CDATA[<p><a href="http://en.wikipedia.org/wiki/Function_object">Funktorem</a> nazywamy obiekt, który może być wywoływany jak funkcja. Często chcemy też, by wywołanie takiego funktora przypominało składnią wywołanie normalnej funkcji w danym języku programowania.</p>
<p>W niektórych językach (<a href="http://temporal.pr0.pl/devblog/2010/05/01/lisp-domkniecia-i-pokemony/">np. w C++, o czym niedawno pisałem</a>) funktorów używa się do naprawienia braku naturalnego wsparcia dla <a href="http://en.wikipedia.org/wiki/First-class_function"><em>funkcji first-class</em></a>. Jednak Common Lisp takie wsparcie ma, więc zasadnicze pytanie brzmi: po co nam funktory w języku, w którym funkcja jest takim samym typem danych jak każdy inny?</p>
<p>Zadajmy sobie inne pytanie &#8211; co robimy z funktorami?</p>
<ol>
<li>Przekazujemy je do <a href="http://pl.wikipedia.org/wiki/Funkcja_wy%C5%BCszego_rz%C4%99du">funkcji wyższego rzędu</a>, takich jak <code class="codecolorer lisp default"><span class="lisp">map</span></code> czy <code class="codecolorer lisp default"><span class="lisp">reduce</span></code>.</li>
<li>Ponieważ są to obiekty, możemy trzymać w nich dodatkowe informacje lub umożliwiać wykonywanie na nich dodatkowych operacji.</li>
</ol>
<p>Wyobraźmy sobie, że piszemy bibliotekę do obliczania minimum zadanej funkcji matematycznej<a href="#POST_CL_FUNCTOR_REF_1" name="POST_CL_FUNCTOR_MT_1">*</a>. Niektóre metody potrzebują jedynie znać wartości naszej funkcji w kilku punktach. Inne potrzebują także pochodnych lub <a href="http://pl.wikipedia.org/wiki/Gradient_%28matematyka%29">gradientu</a>. Chcielibyśmy takie informacje trzymać &#8220;razem&#8221; z naszą funkcją, móc uzyskać do nich dostęp w razie potrzeby (na tym etapie nie zastanawiamy się nad sposobem ich wyliczenia czy przechowywania). Nasza matematyczna funkcja powinna więc być obiektem. Z drugiej strony, chcemy mieć możliwość użycia jej jak normalnej funkcji w języku programowania &#8211; choćby po to, by nie mnożyć dziwnej składni tylko dlatego, że chcemy &#8220;na boku&#8221; przechowywać dodatkowe informacje. W C++ przeładowalibyśmy <code class="codecolorer cpp default"><span class="cpp">operator<span style="color: #008000;">&#40;</span><span style="color: #008000;">&#41;</span></span></code> &#8211; spełniając w ten sposób wymagania 1) i 2) naszego funktora.</p>
<p>Deklaracja i użycie wyglądałyby na przykład tak:</p>
<div class="codecolorer-container cpp default" style="overflow:auto;white-space:nowrap;border:1px solid #9F9F9F;width:435px;"><div class="cpp codecolorer" style="padding:5px;font:normal 12px/1.4em Monaco, Lucida Console, monospace;white-space:nowrap"><span style="color: #0000ff;">class</span> MathFunction<br />
<span style="color: #008000;">&#123;</span><br />
<span style="color: #666666;">//...</span><br />
<span style="color: #0000ff;">public</span><span style="color: #008080;">:</span><br />
&nbsp; &nbsp; MathFunction FirstDerivative<span style="color: #008000;">&#40;</span><span style="color: #008000;">&#41;</span><span style="color: #008080;">;</span> <span style="color: #666666;">//funkcja zwracajaca nam pierwsza pochodna</span><br />
&nbsp; &nbsp; <span style="color: #0000ff;">double</span> operator<span style="color: #008000;">&#40;</span><span style="color: #008000;">&#41;</span> <span style="color: #008000;">&#40;</span><span style="color: #0000ff;">double</span> x<span style="color: #008000;">&#41;</span><span style="color: #008080;">;</span> <span style="color: #666666;">//funkcja zwracajaca nam wartosc w punkcie</span><br />
<span style="color: #008000;">&#125;</span><span style="color: #008080;">;</span><br />
<br />
<span style="color: #666666;">//uzycie</span><br />
MathFunction funkcja<span style="color: #008080;">;</span><br />
<span style="color: #0000ff;">double</span> wynik <span style="color: #000080;">=</span> funkcja<span style="color: #008000;">&#40;</span><span style="color:#800080;">100.0</span><span style="color: #008000;">&#41;</span><span style="color: #008080;">;</span><br />
std<span style="color: #008080;">::</span><span style="color: #007788;">for_each</span><span style="color: #008000;">&#40;</span>dane.<span style="color: #007788;">begin</span><span style="color: #008000;">&#40;</span><span style="color: #008000;">&#41;</span>, dane.<span style="color: #007788;">end</span><span style="color: #008000;">&#40;</span><span style="color: #008000;">&#41;</span>, funkcja<span style="color: #008000;">&#41;</span><span style="color: #008080;">;</span></div></div>
<p>Powiedzmy raz jeszcze, co chcemy uzyskać w Lispie &#8211; chcielibyśmy mieć obiekt <code class="codecolorer lisp default"><span class="lisp">funkcja</span></code>, który dałoby się wywołać jak funkcję, pisząc: <code class="codecolorer lisp default"><span class="lisp"><span style="color: #66cc66;">&#40;</span><span style="color: #b1b100;">funcall</span> funkcja <span style="color: #cc66cc;">100</span><span style="color: #66cc66;">&#41;</span></span></code><a href="#POST_CL_FUNCTOR_REF_2" name="POST_CL_FUNCTOR_MT_2">**</a>, oraz przekazać do funkcji wyższego rzędu, np.: <code class="codecolorer lisp default"><span class="lisp"><span style="color: #66cc66;">&#40;</span>map '<span style="color: #b1b100;">list</span> funkcja dane<span style="color: #66cc66;">&#41;</span></span></code>, ale równocześnie chcemy uzyskiwać z niego pewne informacje, np. <code class="codecolorer lisp default"><span class="lisp"><span style="color: #66cc66;">&#40;</span>first-derivative funkcja<span style="color: #66cc66;">&#41;</span></span></code>.</p>
<p>Rozwiązaniem jest użycie <a href="http://en.wikipedia.org/wiki/Metaobject_protocol">Metaobject Protocol</a> do zmiany typu klasy z <code class="codecolorer lisp default"><span class="lisp">standard-class</span></code> na <code class="codecolorer lisp default"><span class="lisp">funcallable-standard-class</span></code>. Przykładowo (w Clozure Common Lisp<a href="#POST_CL_FUNCTOR_REF_3" name="POST_CL_FUNCTOR_MT_3">***</a>):</p>
<div class="codecolorer-container lisp default" style="overflow:auto;white-space:nowrap;border:1px solid #9F9F9F;width:435px;"><div class="lisp codecolorer" style="padding:5px;font:normal 12px/1.4em Monaco, Lucida Console, monospace;white-space:nowrap"><span style="color: #66cc66;">&#40;</span>defclass math-<span style="color: #b1b100;">function</span> <span style="color: #66cc66;">&#40;</span><span style="color: #66cc66;">&#41;</span><br />
&nbsp; <span style="color: #66cc66;">&#40;</span><span style="color: #66cc66;">&#41;</span> <span style="color: #808080; font-style: italic;">; tutaj mozemy umieszczac sloty, czyli zmienne skladowe</span><br />
&nbsp; <span style="color: #66cc66;">&#40;</span><span style="color: #66cc66;">:</span><span style="color: #555;">metaclass</span> ccl<span style="color: #66cc66;">:</span><span style="color: #555;">funcallable-standard-class</span><span style="color: #66cc66;">&#41;</span><span style="color: #66cc66;">&#41;</span></div></div>
<p>Definiujemy również metodę zwracającą pierwszą pochodną:</p>
<div class="codecolorer-container lisp default" style="overflow:auto;white-space:nowrap;border:1px solid #9F9F9F;width:435px;"><div class="lisp codecolorer" style="padding:5px;font:normal 12px/1.4em Monaco, Lucida Console, monospace;white-space:nowrap"><span style="color: #66cc66;">&#40;</span>defgeneric first-derivative <span style="color: #66cc66;">&#40;</span><span style="color: #66cc66;">&#41;</span><br />
&nbsp; <span style="color: #66cc66;">&#40;</span><span style="color: #66cc66;">:</span><span style="color: #555;">documentation</span> <span style="color: #ff0000;">&quot;Returns analytical first derivative of a function.&quot;</span><span style="color: #66cc66;">&#41;</span><span style="color: #66cc66;">&#41;</span><br />
<br />
<span style="color: #66cc66;">&#40;</span>defmethod first-derivative <span style="color: #66cc66;">&#40;</span><span style="color: #66cc66;">&#40;</span>f math-<span style="color: #b1b100;">function</span><span style="color: #66cc66;">&#41;</span><span style="color: #66cc66;">&#41;</span><br />
&nbsp; <span style="color: #66cc66;">&#40;</span><span style="color: #66cc66;">...</span><span style="color: #66cc66;">&#41;</span><span style="color: #66cc66;">&#41;</span> <span style="color: #808080; font-style: italic;">; kod metody pomijam</span></div></div>
<p>Od teraz obiekty klasy <code class="codecolorer lisp default"><span class="lisp">math-object</span></code> są &#8220;funcallable&#8221; &#8211; mogą być przekazane do <code class="codecolorer lisp default"><span class="lisp"><span style="color: #b1b100;">funcall</span></span></code>, co oznacza, że mogą być argumentami funkcji wyższego rzędu. Spełniamy tym samym wymagania 1) i 2) naszego funktora.</p>
<p>Pozostaje tylko pytanie, jaki kod wykona &#8220;wywołanie&#8221; naszego obiektu? Kod ten możemy ustawić za pomocą <code class="codecolorer lisp default"><span class="lisp">set-funcallable-instance-<span style="color: #b1b100;">function</span></span></code>. Wygodnie jest zrobić to w konstruktorze. W Lispie, konstruktor klasy tworzymy dodając metodę <em>after</em> o nazwie <code class="codecolorer lisp default"><span class="lisp">initialize-instance</span></code>.</p>
<div class="codecolorer-container lisp default" style="overflow:auto;white-space:nowrap;border:1px solid #9F9F9F;width:435px;"><div class="lisp codecolorer" style="padding:5px;font:normal 12px/1.4em Monaco, Lucida Console, monospace;white-space:nowrap"><span style="color: #66cc66;">&#40;</span>defmethod initialize-instance <span style="color: #66cc66;">:</span><span style="color: #555;">after</span> <span style="color: #66cc66;">&#40;</span><span style="color: #66cc66;">&#40;</span>f math-<span style="color: #b1b100;">function</span><span style="color: #66cc66;">&#41;</span> <span style="color: #66cc66;">&amp;</span>key code<span style="color: #66cc66;">&#41;</span><br />
&nbsp; <span style="color: #66cc66;">&#40;</span>set-funcallable-instance-<span style="color: #b1b100;">function</span> f code<span style="color: #66cc66;">&#41;</span><span style="color: #66cc66;">&#41;</span></div></div>
<p>Dodaliśmy parametr kluczowy <code class="codecolorer lisp default"><span class="lisp">code</span></code>, który pozwala nam tworzyć obiekty w następujący sposób:</p>
<div class="codecolorer-container lisp default" style="overflow:auto;white-space:nowrap;border:1px solid #9F9F9F;width:435px;"><div class="lisp codecolorer" style="padding:5px;font:normal 12px/1.4em Monaco, Lucida Console, monospace;white-space:nowrap"><span style="color: #808080; font-style: italic;">; stworzony obiekt zapisujemy do zmiennej square</span><br />
<span style="color: #66cc66;">&#40;</span><span style="color: #b1b100;">setq</span> square <span style="color: #66cc66;">&#40;</span>make-instance 'math-<span style="color: #b1b100;">function</span> <span style="color: #66cc66;">:</span><span style="color: #555;">code</span> <span style="color: #66cc66;">&#40;</span><span style="color: #b1b100;">lambda</span> <span style="color: #66cc66;">&#40;</span>x<span style="color: #66cc66;">&#41;</span> <span style="color: #66cc66;">&#40;</span>* x x<span style="color: #66cc66;">&#41;</span><span style="color: #66cc66;">&#41;</span><span style="color: #66cc66;">&#41;</span><span style="color: #66cc66;">&#41;</span><br />
<br />
<span style="color: #808080; font-style: italic;">; uzycie:</span><br />
<span style="color: #66cc66;">&#40;</span><span style="color: #b1b100;">funcall</span> square <span style="color: #cc66cc;">3</span><span style="color: #66cc66;">&#41;</span><br />
<span style="color: #808080; font-style: italic;">;wynik: 9</span></div></div>
<p>Jeżeli chcemy, aby nasz funktor był widziany jak funkcja globalna i używany ze składnią normalnego wywołania funkcji, możemy napisać:</p>
<div class="codecolorer-container lisp default" style="overflow:auto;white-space:nowrap;border:1px solid #9F9F9F;width:435px;"><div class="lisp codecolorer" style="padding:5px;font:normal 12px/1.4em Monaco, Lucida Console, monospace;white-space:nowrap"><span style="color: #66cc66;">&#40;</span><span style="color: #b1b100;">setf</span> <span style="color: #66cc66;">&#40;</span>fdefinition 'square<span style="color: #66cc66;">&#41;</span> square<span style="color: #66cc66;">&#41;</span><br />
<br />
<span style="color: #808080; font-style: italic;">; ponizszy kod teraz bedzie dzialal:</span><br />
<span style="color: #66cc66;">&#40;</span>square <span style="color: #cc66cc;">3</span><span style="color: #66cc66;">&#41;</span><br />
<span style="color: #808080; font-style: italic;">; wynik: 9</span></div></div>
<p>Wydaje się, że konieczność zaprzęgania Metaobject Protocol sprawia, iż stworzenie funktora jest czymś skomplikowanym w stosunku do np. C++. Należy jednak pamiętać, funktory w Lispie zwykle nie są potrzebne &#8211; same funkcje są <em>first-class</em> i można je przekazywać oraz zwracać jak każdy inny typ. Konieczność łączenia z funkcjami dodatkowych danych i operacji jest &#8211; wydaje mi się &#8211; czymś rzadkim. I nawet nie jestem pewien, czy nie znalazłaby się lepsza abstrakcja dla tego problemu.</p>
<p><strong>Przypisy</strong><br />
<a href="#POST_CL_FUNCTOR_MT_1" name="POST_CL_FUNCTOR_REF_1">*</a> &#8211; problem nie jest wcale taki błahy ani wzięty z powietrza &#8211; w tym semestrze miałem na studiach cały przedmiot poświęcony znajdywaniu minimum funkcji na różne, niekiedy <a href="http://www.kmg.ps.pl/opt/wyklad/bezgrad/rosen.html">dość dziwne</a> sposoby.<br />
<a href="#POST_CL_FUNCTOR_MT_2" name="POST_CL_FUNCTOR_REF_2">**</a> &#8211; składnia <code class="codecolorer lisp default"><span class="lisp"><span style="color: #66cc66;">&#40;</span><span style="color: #b1b100;">funcall</span> funkcja argumenty<span style="color: #66cc66;">&#41;</span></span></code> jest naturalnym sposobem wywoływania funkcji przekazanej w zmiennej w Common Lisp. Język ten, w przeciwieństwie do Scheme, pozwala funkcjom i zmiennym nosić te same nazwy &#8211; dlatego nie możemy napisać po prostu <code class="codecolorer lisp default"><span class="lisp"><span style="color: #66cc66;">&#40;</span>przekazana-funkcja argumenty<span style="color: #66cc66;">&#41;</span></span></code> (tak jak zrobilibyśmy w Scheme), gdyż Lisp będzie szukał symbolu <code class="codecolorer lisp default"><span class="lisp">przekazana-funkcja</span></code> w przestrzeni nazw funkcji.<br />
<a href="#POST_CL_FUNCTOR_MT_3" name="POST_CL_FUNCTOR_REF_3">***</a> &#8211; jest trochę zamieszania z Metaobject Protocol w różnych implementacjach Common Lispu. Sam symbol <code class="codecolorer lisp default"><span class="lisp">funcallable-standard-class</span></code> znajduje się w pakiecie specyficznym dla danej implementacji. Dla Clozure Common Lisp jest to pakiet CCL (tak jak w przykładzie), w SBCL prawdopodobnie SB-MOP. Powstał projekt <a href="http://common-lisp.net/project/closer/index.html">Closer</a> mający na celu ujednolicenie Metaobject Protocol pomiędzy różnymi implementacjami Common Lispu, ale nie miałem okazji jeszcze z niego korzystać.</p>
]]></content:encoded>
			<wfw:commentRss>http://temporal.pr0.pl/devblog/2010/06/14/funktory-traktowanie-obiektow-jak-funkcje-w-common-lisp/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Case-sensitive search w Google</title>
		<link>http://temporal.pr0.pl/devblog/2010/06/06/case-sensitive-serach-w-google/</link>
		<comments>http://temporal.pr0.pl/devblog/2010/06/06/case-sensitive-serach-w-google/#comments</comments>
		<pubDate>Sun, 06 Jun 2010 11:43:57 +0000</pubDate>
		<dc:creator>Jacek Złydach</dc:creator>
				<category><![CDATA[Informatyka]]></category>
		<category><![CDATA[Z życia]]></category>
		<category><![CDATA[Google]]></category>
		<category><![CDATA[porady]]></category>

		<guid isPermaLink="false">http://temporal.pr0.pl/devblog/?p=1237</guid>
		<description><![CDATA[Google domyślnie ignoruje wielkość liter wpisanych w zapytaniu. Zwykle to ma sens, ale czasem przeszkadza. Są wyrazy, których znaczenie zmienia się zależnie od tego, czy są pisane wielkimi czy małymi literami. O ile w języku potocznym nie jest to jeszcze taki wielki problem (zawsze możemy dorzucić dodatkowy wyraz, który doprecyzuje znaczenie, np. &#8220;polish shoes&#8221; vs. [...]]]></description>
			<content:encoded><![CDATA[<p>Google domyślnie ignoruje wielkość liter wpisanych w zapytaniu. Zwykle to ma sens, ale czasem przeszkadza. Są <a href="http://en.wikipedia.org/wiki/Capitonym">wyrazy, których znaczenie zmienia się zależnie od tego, czy są pisane wielkimi czy małymi literami</a>. O ile w języku potocznym nie jest to jeszcze taki wielki problem (zawsze możemy dorzucić dodatkowy wyraz, który doprecyzuje znaczenie, np. <em>&#8220;polish shoes&#8221;</em> vs. <em>&#8220;Polish language&#8221;</em>), o tyle w słownictwie informatycznym tworzy to pewien kłopot. Widać to dobrze na języku SQL, którego polecenia odpowiadają bardzo popularnym wyrazom potocznego angielskiego.</p>
<p>Powiedzmy, że chcę znaleźć fragment dokumentacji opisujący składnię <code class="codecolorer sql default"><span class="sql"><span style="color: #993333; font-weight: bold;">BETWEEN</span></span></code>. Proste zapytanie postaci: <code class="codecolorer text default"><span class="text">BETWEEN site:http://www.postgresql.org/docs/</span></code> nie zwróci nic przydatnego, gdyż wyraz <em>&#8216;between&#8217;</em> pojawia się wielokrotnie w tekstach jako zwykłe angielskie słowo. Przydałby się sposób na wytłumaczenie Google&#8217;owi, że chodzi nam konkretnie o <code class="codecolorer text default"><span class="text">BETWEEN</span></code>, a nie o <code class="codecolorer text default"><span class="text">between</span></code>. Ktoś na szczęście o tym problemie pomyślał i powstała aplikacja <strong><a href="http://case-sensitive-search.appspot.com/">Case sensitive (CS) Google search</a></strong>, która filtruje wyniki wyszukiwania pod kątem wielkości liter.</p>
<p>Jedna uwaga dotycząca samego wyszukiwania z pomocą tego narzędzia &#8211; w przypadku, gdy wpisujemy zapytanie z operatorami, typu <code class="codecolorer text default"><span class="text">BETWEEN site:http://www.postgresql.org/docs/</span></code>, trzeba sobie ręcznie poprawić filtr wyszukiwania tak, by nie próbował znaleźć operatora <em>site:</em> i dalszej części zapytania w wynikach wyszukiwania.</p>
<p><strong>Edit</strong><br />
Jak słusznie <a href="http://temporal.pr0.pl/devblog/2010/06/06/case-sensitive-serach-w-google/comment-page-1/#comment-17732">napisał w komentarzu Reg</a>, polecenia SQL nie muszą być pisane wielkimi literami. Niemniej jednak wiele osób tak czyni (w tym <a href="http://www.postgresql.org/docs/8.3/static/dml-insert.html">dokumentacja do Postgresa</a>) i dzięki temu możemy wykorzystać tę różnicę w zapisie (wielkie litery dla SQL vs. małe dla normalnego angielskiego) do odfiltrowania całej masy niepotrzebnych wyników. Oczywiście, najpierw trzeba zmusić Google do rozróżniania wielkości liter <img src='http://temporal.pr0.pl/devblog/wp-includes/images/smilies/icon_smile.gif' alt=':)' class='wp-smiley' /> .</p>
]]></content:encoded>
			<wfw:commentRss>http://temporal.pr0.pl/devblog/2010/06/06/case-sensitive-serach-w-google/feed/</wfw:commentRss>
		<slash:comments>2</slash:comments>
		</item>
		<item>
		<title>Game State Manager bez &#8220;Managera&#8221;</title>
		<link>http://temporal.pr0.pl/devblog/2010/05/29/game-state-manager-bez-managera/</link>
		<comments>http://temporal.pr0.pl/devblog/2010/05/29/game-state-manager-bez-managera/#comments</comments>
		<pubDate>Sat, 29 May 2010 13:34:26 +0000</pubDate>
		<dc:creator>Jacek Złydach</dc:creator>
				<category><![CDATA[Humor]]></category>
		<category><![CDATA[Informatyka]]></category>
		<category><![CDATA[Tworzenie gier]]></category>

		<guid isPermaLink="false">http://temporal.pr0.pl/devblog/?p=1217</guid>
		<description><![CDATA[Rafał Rozestwiński upomniał mnie ostatnio za nazwanie pewnej klasy Game State Manager-em. Są powody, dla których powinniśmy unikać słowa Manager przy nazywaniu klas. Rafał zaproponował mi więc kilka alternatyw:

Game State One Star General
Game State Supreme Commander
Game State Field Marshall
Marszałek Polny Stanu Gry

Teraz rola tak nazwanej klasy jest jasna  .
]]></description>
			<content:encoded><![CDATA[<p><a href="http://rozestwinski.com/">Rafał Rozestwiński</a> upomniał mnie ostatnio za nazwanie pewnej klasy <em>Game State Manager</em>-em. <a href="http://www.bright-green.com/blog/2003_02_25/naming_java_classes_without_a.html">Są powody, dla których powinniśmy unikać słowa <em>Manager</em> przy nazywaniu klas</a>. Rafał zaproponował mi więc kilka alternatyw:</p>
<ul>
<li>Game State One Star General</li>
<li>Game State Supreme Commander</li>
<li>Game State Field Marshall</li>
<li>Marszałek Polny Stanu Gry</li>
</ul>
<p>Teraz rola tak nazwanej klasy jest jasna <img src='http://temporal.pr0.pl/devblog/wp-includes/images/smilies/icon_smile.gif' alt=':)' class='wp-smiley' /> .</p>
]]></content:encoded>
			<wfw:commentRss>http://temporal.pr0.pl/devblog/2010/05/29/game-state-manager-bez-managera/feed/</wfw:commentRss>
		<slash:comments>1</slash:comments>
		</item>
		<item>
		<title>Sztuczka z QuickLaunch&#8217;em</title>
		<link>http://temporal.pr0.pl/devblog/2010/05/16/sztuczka-z-quicklaunchem/</link>
		<comments>http://temporal.pr0.pl/devblog/2010/05/16/sztuczka-z-quicklaunchem/#comments</comments>
		<pubDate>Sun, 16 May 2010 13:27:15 +0000</pubDate>
		<dc:creator>Jacek Złydach</dc:creator>
				<category><![CDATA[Informatyka]]></category>
		<category><![CDATA[porady]]></category>
		<category><![CDATA[QuickLaunch]]></category>
		<category><![CDATA[Windows]]></category>

		<guid isPermaLink="false">http://temporal.pr0.pl/devblog/?p=82</guid>
		<description><![CDATA[Systemy starsze od Windows 7 dysponują tak zwanym &#8220;paskiem szybkiego uruchamiania&#8221; (ang. quick launch) &#8211; to te ikonki zaraz obok menu start. Jeden z moich znajomych pokazał mi kiedyś, że jak do tego paska wsadzi się więcej ikonek niż da się wyświetlić jedna obok drugiej (przestrzeń dostępną dla paska szybkiego uruchamiania można regulować, trzeba kliknąć [...]]]></description>
			<content:encoded><![CDATA[<p>Systemy starsze od Windows 7 dysponują tak zwanym &#8220;paskiem szybkiego uruchamiania&#8221; (ang. quick launch) &#8211; to te ikonki zaraz obok menu start. Jeden z moich znajomych pokazał mi kiedyś, że jak do tego paska wsadzi się więcej ikonek niż da się wyświetlić jedna obok drugiej (przestrzeń dostępną dla paska szybkiego uruchamiania można regulować, trzeba kliknąć prawym przyciskiem na pasek zadań i go odblokować), to Windows &#8220;zwija je&#8221; do bardzo ciekawego rozwijanego menu. A ponieważ do paska można też dodawać foldery, to w połączeniu ze zwinięciem powstaje możliwość stworzenia ciekawego rozwijanego menu. Prezentuje to screen poniżej.</p>
<p><a href="http://temporal.pr0.pl/devblog/download/posts/QuickLaunch/trc_patent.png"><img src="http://temporal.pr0.pl/devblog/download/posts/QuickLaunch/trc_patent-450.png" alt="Drzewo folderów w pasku szybkiego uruchamiania" /></a></p>
<p>Tej sztuczki używałem pracując na Windows Vista &#8211; polecam spróbować <img src='http://temporal.pr0.pl/devblog/wp-includes/images/smilies/icon_smile.gif' alt=':)' class='wp-smiley' /> . Więcej szczegółów na temat samego paska QuickLaunch można też przeczytać na <a href="http://blogs.technet.com/plitpromicrosoftcom/archive/2007/02/19/quick-launch.aspx">blogu TechNet</a>.</p>
]]></content:encoded>
			<wfw:commentRss>http://temporal.pr0.pl/devblog/2010/05/16/sztuczka-z-quicklaunchem/feed/</wfw:commentRss>
		<slash:comments>1</slash:comments>
		</item>
		<item>
		<title>Cloze Call &#8211; postmortem</title>
		<link>http://temporal.pr0.pl/devblog/2010/05/13/cloze-call-postmortem/</link>
		<comments>http://temporal.pr0.pl/devblog/2010/05/13/cloze-call-postmortem/#comments</comments>
		<pubDate>Wed, 12 May 2010 23:41:02 +0000</pubDate>
		<dc:creator>Jacek Złydach</dc:creator>
				<category><![CDATA[Informatyka]]></category>
		<category><![CDATA[Tworzenie gier]]></category>
		<category><![CDATA[Cloze Call]]></category>
		<category><![CDATA[Common Lisp]]></category>
		<category><![CDATA[Compo]]></category>
		<category><![CDATA[Lisp]]></category>
		<category><![CDATA[postmortem]]></category>

		<guid isPermaLink="false">http://temporal.pr0.pl/devblog/?p=1203</guid>
		<description><![CDATA[
W końcu mój ostatni projekt &#8211; Cloze Call &#8211; doczekał się wpisu na blogu. Po sporej ilości zabaw udało mi się znaleźć popełniony błąd i ostatecznie przygotować binarkę pod Windows&#8217;a.
Po szczegóły, screeny, źródła i download &#8211; zapraszam na stronę projektu!
Postmortem
Jedną z sugestii na 2010LGDC było, by każdy na koniec napisał postmortem swojej gry. Poniżej zamieszczam [...]]]></description>
			<content:encoded><![CDATA[<p><center><img src="http://temporal.pr0.pl/devblog/download/projects/ClozeCall/logotype.png" alt="Cloze Call" /></center><br />
W końcu mój ostatni projekt &#8211; Cloze Call &#8211; doczekał się wpisu na blogu. Po sporej ilości zabaw udało mi się znaleźć popełniony błąd i ostatecznie przygotować <a href="http://temporal.pr0.pl/devblog/projekty/cloze-call/#PROJ_CLOZECALL_DOWNLOAD">binarkę pod Windows&#8217;a</a>.</p>
<p>Po szczegóły, screeny, źródła i download &#8211; <strong><a href="http://temporal.pr0.pl/devblog/projekty/cloze-call/">zapraszam na stronę projektu</a></strong>!</p>
<p><strong>Postmortem</strong></p>
<p>Jedną z sugestii na 2010LGDC było, by każdy na koniec napisał postmortem swojej gry. Poniżej zamieszczam tekst w oryginale (wzbogacony jedynie o linki i bez poprawiania błędów) &#8211; dla tych, którzy nie boją się czytać długiego tekstu po angielsku <img src='http://temporal.pr0.pl/devblog/wp-includes/images/smilies/icon_smile.gif' alt=':)' class='wp-smiley' /> .</p>
<p>Hi,</p>
<p>This is a postmortem for my 2010LGDC entry, called &#8220;Cloze-Call&#8221;. It derives its name from <a href="http://www.clozure.com/clozurecl.html">Clozure Common Lisp</a>, in which it was written (more on that topic in Section 2). It is also a reference to a phrase, &#8220;close call&#8221;, which means achieving something or escaping by a narrow margin, which corresponds to the ball maneuvering between planets.</p>
<p>The game itself is a very simple &#8220;Gravity Pong&#8221;. Your goal as a player is to shoot a ball into a hole. The ball must not collide with any of the planets that are on screen. To make things more fun, all planets attract the ball by means of gravity force.</p>
<p><strong>1. What did I learn?</strong><br />
Common Lisp, first of all. It is my first real project in Lisp. I started learning this language in summer 2009, but (thanks to university) I didn&#8217;t have much time to write some real programs.</p>
<p>Using <a href="http://en.wikipedia.org/wiki/Another_System_Definition_Facility">ASDF</a> &#8211; at least a little bit.</p>
<p>That my old design concept for Game State Manager code (which I used for years in at least three other languages) has flaws to get ????</p>
<p><strong>2. What went right?</strong><br />
Setting up the environment. I am working on 32-bit Windows 7. Even though I had to try out <a href="http://sbcl.sourceforge.net/">SBCL</a> (which crashed on SDL examples), <a href="http://clisp.cons.org/">CLISP</a> (too slow), <a href="http://ecls.sourceforge.net/">ECL</a> (also too slow) and SBCL on Ubuntu before ending up with well-working <a href="http://code.google.com/p/lispbuilder/wiki/LispbuilderSDL">lispbuilsder-sdl</a> and Clozure Common Lisp, I am surprised that the installation and setting up process wasn&#8217;t that complicated and things actually worked first-time. I spent two days before the Challenge on setting up <a href="http://www.libsdl.org/">SDL</a> and working environment.</p>
<p>Graphic Design. This project confirmed what I actually learned recently &#8211; it is important to sacrifice some time and get decent-looking graphics / media for your product (be it a game, or anything else) and make it look nice. I&#8217;d be very unhappy if this game had circles and squares instead of those pictures, which I found on <a href="http://opengameart.org/">OpenGameArt.org</a>.</p>
<p>Fixed-step physics. I am using <a href="http://www.gamedev.pl/articles.php?x=view&#038;id=370">and promoting</a> fixed time step approach to simulation in computer games, and it&#8217;s the first time I really saw how good it is. During first physics test I had a fixed initial velocity vector for the ball, and I could see how it always travels the same path and lands in the same place.</p>
<p>The game. It isn&#8217;t finished, but it is playable and has most of the game mechanics implemented. I had to cut down on features as I was running out of time, but I shipped.</p>
<p><strong>3. What went wrong?</strong><br />
Transparency in SDL &#8211; I made some little voodoo and made planets use alpha channel, but the same trick didn&#8217;t worked for any other image. I&#8217;m still confused why it&#8217;s not working, and this phenomena is responsible for ugly Victory/Defeat screens.</p>
<p>Watching movies &#8211; I&#8217;d have at least few more hours to work on my game if I haven&#8217;t found myself some stuff that I <a href="http://pl.wikipedia.org/wiki/Stargate_Universe">really</a>, <a href="http://pl.wikipedia.org/wiki/Fala_zbrodni">really</a> wanted to watch.</p>
<p>Bad naming conventions. I heard it&#8217;s hard to give names to vector-math library functions. I done it wrong, and had to look for a bug for almost an hour. My vector math library that I wrote for this game had two kinds of functions &#8211; some were returning a new vector with the result of an operation, and some modified their arguments. In particular, I had (negative-vector) which returned a new vector representing inversed input parameter. The complimentary function was (negate-vector), which just negated its parameter. I used the latter instead of the former in physics code, and spent almost an hour trying to discover why graphics was flickering.</p>
<p>6 days instead of 7. If I were more careful and wrote 2010-04-01 23:59GMT+1 instead of 2010-04-01 00:00GMT+1, I&#8217;d have one more day to work. I found my mistake about a day after signing up and decided not to change my initial declaration.</p>
<p><strong>4. What&#8217;s lispy about my entry?</strong><br />
It is in Lisp <img src='http://temporal.pr0.pl/devblog/wp-includes/images/smilies/icon_smile.gif' alt=':)' class='wp-smiley' /> . It is not that common to see a game in Lisp <img src='http://temporal.pr0.pl/devblog/wp-includes/images/smilies/icon_smile.gif' alt=':)' class='wp-smiley' /> .</p>
<p>Few lambdas and high-order functions here and there. I think that my code is more like C++ with Lisp-syntax. But I guess, as for a first Lisp project, it&#8217;s not that bad.</p>
<p><strong>5. What interesting algorithms or designs did I use?</strong><br />
My good, old Game State Manager abstraction that I use everywhere. It simplified managing different game screens. Apart from that, I guess everything else is typical stuff you&#8217;ll find in any computer game.</p>
<p>At first I wasn&#8217;t sure if I want to take part in the Contest. I have lot of stuff to do at university (and other places as well), I don&#8217;t know that much Common Lisp, ect. etd. But, I thought, it would be a good occasion to actually learn much Lisp in short time, and write another game. I decided to sacrifice some university lectures and now I&#8217;m happy I did it. I&#8217;d like to thank <a href="http://lispgamesdev.blogspot.com/">David O&#8217;Toole</a> for inviting me to #lispgames and encouraging me to take part in the Challenge. And I&#8217;d like to thank all of you #lispgames guys for support and nice time wasted (I should have been coding, not chatting <img src='http://temporal.pr0.pl/devblog/wp-includes/images/smilies/icon_razz.gif' alt=':P' class='wp-smiley' /> ) on IRC <img src='http://temporal.pr0.pl/devblog/wp-includes/images/smilies/icon_smile.gif' alt=':)' class='wp-smiley' /> .</p>
]]></content:encoded>
			<wfw:commentRss>http://temporal.pr0.pl/devblog/2010/05/13/cloze-call-postmortem/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Elementarne automaty komórkowe</title>
		<link>http://temporal.pr0.pl/devblog/2010/05/09/elementarne-automaty-komorkowe/</link>
		<comments>http://temporal.pr0.pl/devblog/2010/05/09/elementarne-automaty-komorkowe/#comments</comments>
		<pubDate>Sun, 09 May 2010 00:40:48 +0000</pubDate>
		<dc:creator>Jacek Złydach</dc:creator>
				<category><![CDATA[Informatyka]]></category>
		<category><![CDATA[Matematyka]]></category>
		<category><![CDATA[A New Kind of Science]]></category>
		<category><![CDATA[automaty komórkowe]]></category>
		<category><![CDATA[Common Lisp]]></category>
		<category><![CDATA[fraktale]]></category>
		<category><![CDATA[Lisp]]></category>
		<category><![CDATA[Mathematica]]></category>

		<guid isPermaLink="false">http://temporal.pr0.pl/devblog/?p=1150</guid>
		<description><![CDATA[Niedawno odkryłem dostępną darmowo w sieci książkę Stephena Wolframa (tego od programu Mathematica i wyszukiwarki Wolfram&#124;Alpha) &#8211; &#8220;A New Kind of Science&#8221;. Czytelnikom, którzy widzieli jego ostatnie wystąpienie na TED nie trzeba mówić o jego ciekawych poglądach na przyszłość współczesnej nauki oraz o tym, jak duże znaczenie przywiązuje do szukania złożonych zachowań w rzeczach prostych.
Przed [...]]]></description>
			<content:encoded><![CDATA[<p>Niedawno odkryłem dostępną darmowo w sieci książkę <a href="http://en.wikipedia.org/wiki/Stephen_Wolfram">Stephena Wolframa</a> (tego od programu <a href="http://en.wikipedia.org/wiki/Mathematica">Mathematica</a> i wyszukiwarki <a href="http://www.wolframalpha.com/">Wolfram|Alpha</a>) &#8211; <a href="http://www.wolframscience.com/nksonline/">&#8220;A New Kind of Science&#8221;</a>. Czytelnikom, którzy widzieli <a href="http://www.youtube.com/watch?v=60P7717-XOQ&#038;feature=player_embedded">jego ostatnie wystąpienie na TED</a> nie trzeba mówić o jego ciekawych poglądach na przyszłość współczesnej nauki oraz o tym, jak duże znaczenie przywiązuje do szukania złożonych zachowań w rzeczach prostych.</p>
<p>Przed lekturą drugiego rozdziału wspomnianej książki postanowiłem napisać sobie prosty, dwustanowy, jednowymiarowy automat komórkowy i wygenerować opisywane przez Wolframa obrazy. Implementacja zajęła piątkowe popołudnie i wieczór, a w rezultacie powstał program symulujący automat komórkowy z dowolną trójelementową regułą oraz renderujący obrazy.</p>
<p><center><strong><a href="http://temporal.pr0.pl/devblog/galerie/automaty-komorkowe-1d-nks">(Galeria automatów komórkowych)</a></strong></center></p>
<p>Poniżej chciałbym zaprezentować kilka najciekawszych przykładów tego, co potrafi stworzyć tak prosty automat komórkowy. Nieco dalej wyjaśnię, na czym polega numeracja reguł. Na samym końcu chciałbym też opowiedzieć o programie, który napisałem.</p>
<p><strong>Reguła 30</strong><br />
<center><a href="http://temporal.pr0.pl/devblog/wp-content/gallery/nks-cellular-automata-1d/wolfram%20rule%20030.png"><img src="http://temporal.pr0.pl/devblog/download/posts/NKS-CA1/wolfram%20rule%20030-450.png" alt="Reguła 30"></a></center><br />
Ulubiona reguła S. Wolframa, szeroko omówiona w jego książce. Z prawej strony tworzy się wzór nie mający żadnej widocznej struktury. Sekwencja kolorów bezpośrednio pod punktem startowym jest podobno losowa według wielu testów sprawdzających generatory liczb losowych &#8211; sam <strong>Wolfram użył reguły 30 jako generatora liczb losowych w programie Mathematica</strong>.</p>
<p><strong>Reguła 18</strong><br />
<center><a href="http://temporal.pr0.pl/devblog/wp-content/gallery/nks-cellular-automata-1d/wolfram%20rule%20018.png"><img src="http://temporal.pr0.pl/devblog/download/posts/NKS-CA1/wolfram%20rule%20018-450.png" alt="Reguła 18"></a></center><br />
Pierwsze pojawienie się <a href="http://pl.wikipedia.org/wiki/Tr%C3%B3jk%C4%85t_Sierpi%C5%84skiego">trójkąta Sierpińskiego</a>. Wiele reguł produkuje różnej postaci trójkąty Sierpińskiego. W całej galerii naliczyłem 24 wystąpienia tego wzoru: <a href="http://temporal.pr0.pl/devblog/wp-content/gallery/nks-cellular-automata-1d/wolfram%20rule%20018.png">18</a>, <a href="http://temporal.pr0.pl/devblog/wp-content/gallery/nks-cellular-automata-1d/wolfram%20rule%20022.png">22</a>, <a href="http://temporal.pr0.pl/devblog/wp-content/gallery/nks-cellular-automata-1d/wolfram%20rule%20026.png">26</a>, <a href="http://temporal.pr0.pl/devblog/wp-content/gallery/nks-cellular-automata-1d/wolfram%20rule%20060.png">60</a>, <a href="http://temporal.pr0.pl/devblog/wp-content/gallery/nks-cellular-automata-1d/wolfram%20rule%20082.png">82</a>, <a href="http://temporal.pr0.pl/devblog/wp-content/gallery/nks-cellular-automata-1d/wolfram%20rule%20090.png">90</a>, <a href="http://temporal.pr0.pl/devblog/wp-content/gallery/nks-cellular-automata-1d/wolfram%20rule%20102.png">102</a>, <a href="http://temporal.pr0.pl/devblog/wp-content/gallery/nks-cellular-automata-1d/wolfram%20rule%20105.png">105</a>, <a href="http://temporal.pr0.pl/devblog/wp-content/gallery/nks-cellular-automata-1d/wolfram%20rule%20126.png">126</a>, <a href="http://temporal.pr0.pl/devblog/wp-content/gallery/nks-cellular-automata-1d/wolfram%20rule%20129.png">129</a>, <a href="http://temporal.pr0.pl/devblog/wp-content/gallery/nks-cellular-automata-1d/wolfram%20rule%200146.png">146</a>, <a href="http://temporal.pr0.pl/devblog/wp-content/gallery/nks-cellular-automata-1d/wolfram%20rule%20150.png">150</a>, <a href="http://temporal.pr0.pl/devblog/wp-content/gallery/nks-cellular-automata-1d/wolfram%20rule%20151.png">151</a>, <a href="http://temporal.pr0.pl/devblog/wp-content/gallery/nks-cellular-automata-1d/wolfram%20rule%20153.png">153</a>, <a href="http://temporal.pr0.pl/devblog/wp-content/gallery/nks-cellular-automata-1d/wolfram%20rule%20154.png">154</a>, <a href="http://temporal.pr0.pl/devblog/wp-content/gallery/nks-cellular-automata-1d/wolfram%20rule%20161.png">161</a>, <a href="http://temporal.pr0.pl/devblog/wp-content/gallery/nks-cellular-automata-1d/wolfram%20rule%20165.png">165</a>, <a href="http://temporal.pr0.pl/devblog/wp-content/gallery/nks-cellular-automata-1d/wolfram%20rule%20167.png">167</a>, <a href="http://temporal.pr0.pl/devblog/wp-content/gallery/nks-cellular-automata-1d/wolfram%20rule%20181.png">181</a>, <a href="http://temporal.pr0.pl/devblog/wp-content/gallery/nks-cellular-automata-1d/wolfram%20rule%20182.png">182</a>, <a href="http://temporal.pr0.pl/devblog/wp-content/gallery/nks-cellular-automata-1d/wolfram%20rule%20183.png">183</a>, <a href="http://temporal.pr0.pl/devblog/wp-content/gallery/nks-cellular-automata-1d/wolfram%20rule%20195.png">195</a>, <a href="http://temporal.pr0.pl/devblog/wp-content/gallery/nks-cellular-automata-1d/wolfram%20rule%20210.png">210</a>, <a href="http://temporal.pr0.pl/devblog/wp-content/gallery/nks-cellular-automata-1d/wolfram%20rule%20218.png">218</a>.</p>
<p><strong>Reguła 151</strong><br />
<center><a href="http://temporal.pr0.pl/devblog/wp-content/gallery/nks-cellular-automata-1d/wolfram%20rule%20151.png"><img src="http://temporal.pr0.pl/devblog/download/posts/NKS-CA1/wolfram%20rule%20151-450.png" alt="Reguła 151"></a></center><br />
Reguła ta jest bardzo ciekawą wariacją wokół trójkąta Sierpińskiego. Powstaje z samych brzegów automatu &#8211; to krawędzie są źródłem wzoru, który przy górnej granicy przypomina wspomniany fraktal. Bardzo interesujący jest też wynik &#8220;interferencji&#8221; zbiegających się wzorców.</p>
<p><strong>Reguła 124</strong><br />
<center><a href="http://temporal.pr0.pl/devblog/wp-content/gallery/nks-cellular-automata-1d/wolfram%20rule%20124.png"><img src="http://temporal.pr0.pl/devblog/download/posts/NKS-CA1/wolfram%20rule%20124-450.png" alt="Reguła 124"></a></center><br />
Prawa krawędź tego wzoru pokazuje powtarzającą się sekwencję trójkątów. Na środku jednak pojawia się bardzo ciekawa struktura, która sprawia wrażenie zupełnie chaotycznej.</p>
<p><strong>Reguła 225</strong><br />
<center><a href="http://temporal.pr0.pl/devblog/wp-content/gallery/nks-cellular-automata-1d/wolfram%20rule%20225.png"><img src="http://temporal.pr0.pl/devblog/download/posts/NKS-CA1/wolfram%20rule%20225-450.png" alt="Reguła 225"></a></center><br />
Ciekawy, chaotyczny wzór powstaje z punktu początkowego. Tutaj jednak, podobnie jak przy regule 151, najciekawsze rzeczy tworzy sama krawędź.</p>
<p><strong>Numeracja Wolframa</strong><br />
Numeracja reguł, zaproponowana przez Wolframa w <em>A New Kind of Science</em>, jest bardzo prosta. Automat, na którym pracujemy oblicza stan nowej komórki z trzech innych &#8211; z tej bezpośrednio nad sobą, oraz z lewego i prawego sąsiada komórki nad sobą. Wystarczy zaobserwować, że mając do dyspozycji trzy komórki, z których każda może przyjąć dwa stany (zapalona albo zgaszona), uzyskujemy 8 możliwych układów. Dla każdego takiego układu definiujemy zasadę &#8211; czy nowa komórka ma zostać zgaszona, czy zapalona. Łącząc takie zasady dla wszystkich ośmiu stanów uzyskujemy jedną regułę opisującą wszystkie możliwe sytuacje spotkane w omawianym automacie komórkowym.</p>
<p>Łączenie zasad w numer reguły jest oparte o operacje bitowe. Jeżeli potraktujemy trójki komórek jako liczby binarne, gdzie stan &#8216;zapalona&#8217; oznacza 1, a stan &#8216;zgaszona&#8217; oznacza 0, uzyskujemy naturalną numerację od 0 do 7. I teraz jeżeli zasada oparta o daną trójkę mówi, ze nowa komórka ma być zapalona, to ustawiamy bit odpowiadający &#8216;numerowi&#8217; trójki komórek na 1, a jeżeli nowa komórka ma być zgaszona &#8211; to na 0. Uzyskany numer zasady jest liczbą ośmiobitową, a więc z zakresu od 0 do 255.</p>
<p><center><a href="http://temporal.pr0.pl/devblog/download/posts/NKS-CA1/numeration-800.jpg"><img src="http://temporal.pr0.pl/devblog/download/posts/NKS-CA1/numeration-450.jpg" alt="Numeracja Wolframa - objaśnienie" /></a></center></p>
<p>Jeżeli sam opis był zbyt zagmatwany, to mam nadzieję, że powyższe zdjęcie wyjaśniło sprawę <img src='http://temporal.pr0.pl/devblog/wp-includes/images/smilies/icon_wink.gif' alt=';)' class='wp-smiley' /> .</p>
<p><strong>Symulator automatu komórkowego</strong><br />
<a href="#POST_NKS_CA_DOWNLOAD">(Pobierz symulator)</a><br />
Sam symulator to prosty program w Common Lispie, który pisałem przez piątkowy wieczór. Trzon designu stanowiły schematy narysowane kredą na betonie przed pizzerią oraz kod rozpisany na pudełku od pizzy <img src='http://temporal.pr0.pl/devblog/wp-includes/images/smilies/icon_smile.gif' alt=':)' class='wp-smiley' /> . Program ten umie przeprowadzać symulacje dla jednowymiarowego, dwustanowego automatu komórkowego o dowolnej szerokości na podstawie reguł sprawdzających trzy sąsiadujące ze sobą komórki.</p>
<p><a href="http://temporal.pr0.pl/devblog/download/posts/NKS-CA1/screen.png"><img src="http://temporal.pr0.pl/devblog/download/posts/NKS-CA1/screen-450.png" alt="Screen z symulatora automatów komórkowych." /></a></p>
<p>Główny program wypisuje swoje wyniki w postaci tekstowej, jednak dopisałem też nakładkę, która umie generować obrazy i zapisywać je do plików. Korzysta ona ze znanej programistom gier biblioteki <a href="http://www.libsdl.org/">SDL</a> za pośrednictwem <a href="http://en.wikipedia.org/wiki/Language_binding">bindingów</a> <a href="http://code.google.com/p/lispbuilder/wiki/LispbuilderSDL">lispbuilder-sdl</a>.</p>
<p><strong>Krawędzie i warunki początkowe</strong><br />
Jest jedna ważna rzecz, o której na tym etapie trzeba wspomnieć. Jak w każdym automacie komórkowym, tak i w tym pojawia się problem krawędzi, czyli tego, jaką wartość ma przyjąć lewy sąsiad pierwszej komórki oraz prawy sąsiad ostatniej. W przypadku mojej implementacji, komórki &#8216;z poza planszy&#8217; przyjmują domyślnie stan &#8216;zgaszony&#8217;, pusty.</p>
<p>Uważny czytelnik zauważy, że wygenerowane przeze mnie obrazki różnią się miejscami od przykładów z książki Wolframa &#8211; wynika to z tego, że symulacja odbywała się na automacie o szerokości 800, gdzie bardzo szybko dochodziła do głosu obecność krawędzi. Zdjęcia zamieszczone w <em>A New Kind of Science</em> są wolne od wpływu krawędzi &#8211; najprawdopodobniej &#8216;krawędź&#8217; jest gdzieś bardzo daleko <img src='http://temporal.pr0.pl/devblog/wp-includes/images/smilies/icon_smile.gif' alt=':)' class='wp-smiley' /> .</p>
<p>Wszystkie obrazki zostały wygenerowane przy tych samych warunkach początkowych, jakie stosował Stephen Wolfram w <em>A New Kind of Science</em> &#8211; startujemy ze wszystkimi komórkami zgaszonymi, i zapalamy jedną dokładnie na środku.</p>
<p><strong>Symulator &#8211; pobieranie i użycie</strong><br />
<a href="http://temporal.pr0.pl/devblog/download/posts/NKS-CA1/ca1d.zip" name="POST_NKS_CA_DOWNLOAD">Pobierz symulator (źródła).</a><br />
Przykład użycia (za pomocą specjalnych funkcji do prostego testowania):</p>
<div class="codecolorer-container lisp default" style="overflow:auto;white-space:nowrap;border:1px solid #9F9F9F;width:435px;"><div class="lisp codecolorer" style="padding:5px;font:normal 12px/1.4em Monaco, Lucida Console, monospace;white-space:nowrap"><span style="color: #66cc66;">&#40;</span>load <span style="color: #66cc66;">&#40;</span>compile-file <span style="color: #ff0000;">&quot;ca1d.lisp&quot;</span><span style="color: #66cc66;">&#41;</span><span style="color: #66cc66;">&#41;</span><br />
<br />
<span style="color: #808080; font-style: italic;">;; wyswietlenie w konsoli 17 iteracji (16 + stan poczatkowy)</span><br />
<span style="color: #808080; font-style: italic;">;; automatu dlugosci 16 zgodnie z regula 30</span><br />
<span style="color: #66cc66;">&#40;</span>test-wolfram-rule <span style="color: #cc66cc;">16</span> <span style="color: #cc66cc;">30</span> <span style="color: #cc66cc;">16</span><span style="color: #66cc66;">&#41;</span><br />
<br />
<span style="color: #808080; font-style: italic;">;; zakladam, ze lispbuilder-sdl jest juz zaladowany</span><br />
<span style="color: #66cc66;">&#40;</span>load <span style="color: #66cc66;">&#40;</span>compile-file <span style="color: #ff0000;">&quot;ca1d-gfx.lisp&quot;</span><span style="color: #66cc66;">&#41;</span><span style="color: #66cc66;">&#41;</span><br />
<br />
<span style="color: #808080; font-style: italic;">;; wyswietlenie graficznie 600 iteracji (ze stanem poczatkowym wlacznie)</span><br />
<span style="color: #808080; font-style: italic;">;; automatu dlugosci 800 zgodnie z regula 30</span><br />
<span style="color: #66cc66;">&#40;</span>test-rule-800x600 <span style="color: #cc66cc;">30</span><span style="color: #66cc66;">&#41;</span><br />
<br />
<span style="color: #808080; font-style: italic;">;; j.w., ale celem wygenerowania samego obrazka:</span><br />
<span style="color: #66cc66;">&#40;</span>test-rule-800x600 <span style="color: #cc66cc;">30</span> t<span style="color: #66cc66;">&#41;</span></div></div>
]]></content:encoded>
			<wfw:commentRss>http://temporal.pr0.pl/devblog/2010/05/09/elementarne-automaty-komorkowe/feed/</wfw:commentRss>
		<slash:comments>1</slash:comments>
		</item>
		<item>
		<title>Używaj rzutowania w stylu C++</title>
		<link>http://temporal.pr0.pl/devblog/2010/05/07/uzywaj-rzutowania-w-stylu-c/</link>
		<comments>http://temporal.pr0.pl/devblog/2010/05/07/uzywaj-rzutowania-w-stylu-c/#comments</comments>
		<pubDate>Fri, 07 May 2010 10:44:21 +0000</pubDate>
		<dc:creator>Jacek Złydach</dc:creator>
				<category><![CDATA[Informatyka]]></category>
		<category><![CDATA[Pragmatyzm]]></category>
		<category><![CDATA[C]]></category>
		<category><![CDATA[porady]]></category>
		<category><![CDATA[rzutowania]]></category>

		<guid isPermaLink="false">http://temporal.pr0.pl/devblog/?p=1118</guid>
		<description><![CDATA[Chociaż temat ten był wałkowany m.in. przez Scotta Meyers&#8217;a w More Effective C++, to wciąż widzi się masę kodu pisanego z rzutowaniami w stylu C. Dla przypomnienia, w C++ mamy cztery rodzaje rzutowań:

static_cast
const_cast
dynamic_cast
reinterpret_cast

Rzutowania w stylu C wyglądają natomiast tak: &#40;typ&#41;argument, lub tak: typ&#40;argument&#41;.
Jeden z ciekawych problemów, który może się pojawić u programisty stosującego rzutowania w [...]]]></description>
			<content:encoded><![CDATA[<p>Chociaż temat ten był wałkowany m.in. przez Scotta Meyers&#8217;a w <a href="http://www.wnt.pl/product.php?action=0&#038;prod_id=55&#038;hot=1">More Effective C++</a>, to wciąż widzi się masę kodu pisanego z rzutowaniami w stylu C. Dla przypomnienia, w C++ mamy cztery rodzaje rzutowań:</p>
<ul>
<li><code class="codecolorer cpp default"><span class="cpp"><span style="color: #0000ff;">static_cast</span></span></code></li>
<li><code class="codecolorer cpp default"><span class="cpp"><span style="color: #0000ff;">const_cast</span></span></code></li>
<li><code class="codecolorer cpp default"><span class="cpp"><span style="color: #0000ff;">dynamic_cast</span></span></code></li>
<li><code class="codecolorer cpp default"><span class="cpp"><span style="color: #0000ff;">reinterpret_cast</span></span></code></li>
</ul>
<p>Rzutowania w stylu C wyglądają natomiast tak: <code class="codecolorer cpp default"><span class="cpp"><span style="color: #008000;">&#40;</span>typ<span style="color: #008000;">&#41;</span>argument</span></code>, lub tak: <code class="codecolorer cpp default"><span class="cpp">typ<span style="color: #008000;">&#40;</span>argument<span style="color: #008000;">&#41;</span></span></code>.</p>
<p>Jeden z ciekawych problemów, który może się pojawić u programisty stosującego rzutowania w stylu C ilustruje poniższy fragment kodu:</p>
<div class="codecolorer-container cpp default" style="overflow:auto;white-space:nowrap;border:1px solid #9F9F9F;width:435px;"><div class="cpp codecolorer" style="padding:5px;font:normal 12px/1.4em Monaco, Lucida Console, monospace;white-space:nowrap">Object Foo<span style="color: #008000;">&#40;</span> <span style="color: #0000ff;">int</span><span style="color: #008000;">&#40;</span>parameter<span style="color: #008000;">&#41;</span> <span style="color: #008000;">&#41;</span><span style="color: #008080;">;</span></div></div>
<p>Ten kod wbrew pozorom nie robi tego, na co wygląda. Nie jest to stworzenie obiektu Foo typu Object, z rzutowaniem parametru na typ <code class="codecolorer cpp default"><span class="cpp"><span style="color: #0000ff;">int</span></span></code>. <strong>C++ przyjmuje zasadę, że wszystko co wygląda jak deklaracja funkcji ma być w pierwszej kolejności potraktowane jak deklaracja funkcji</strong>. I w tym przypadku kod ten deklaruje nam funkcję o nazwie Foo, zwracającej obiekt typu Object i przyjmującej jeden parametr typu <code class="codecolorer cpp default"><span class="cpp"><span style="color: #0000ff;">int</span></span></code>.</p>
<p>Może na co dzień nie spotkamy się z takimi ekstremalnymi zjawiskami, ale rzutowania w stylu C++ mają kilka dobrych cech, o których warto wiedzieć:</p>
<ul>
<li>Są dużo bardziej przyjazne dla grep&#8217;a i innych narzędzi wyszukujących w tekście. O wiele łatwiej jest znaleźć wszystkie wystąpienia <code class="codecolorer cpp default"><span class="cpp"><span style="color: #0000ff;">static_cast</span></span></code> niż rzutowań opartych o nawiasy okrągłe, które czasem mogą przypominać np. wywołanie funkcji albo tworzenie nowego obiektu. Poza tym, w jaki sposób znaleźć wszystkie rzutowania <em>niezależnie od typu, na który się ono odbywa</em>? <img src='http://temporal.pr0.pl/devblog/wp-includes/images/smilies/icon_wink.gif' alt=';)' class='wp-smiley' /> </li>
<li>Są dużo bardziej przyjazne dla <a href="http://catb.org/jargon/html/V/vgrep.html">vgrep&#8217;a</a> (dla ludzkiego oka <img src='http://temporal.pr0.pl/devblog/wp-includes/images/smilies/icon_wink.gif' alt=';)' class='wp-smiley' />  ) &#8211; łatwiej je wypatrzeć w gąszczu nawiasów; z resztą w większości IDE są kolorowane jako słowa kluczowe. Weźmy przykład poniższego kodu:
<div class="codecolorer-container cpp default" style="overflow:auto;white-space:nowrap;border:1px solid #9F9F9F;width:435px;"><div class="cpp codecolorer" style="padding:5px;font:normal 12px/1.4em Monaco, Lucida Console, monospace;white-space:nowrap">&nbsp; &nbsp; <span style="color: #0000ff;">int</span> offset <span style="color: #000080;">=</span> <span style="color: #008000;">&#40;</span><span style="color: #0000ff;">int</span><span style="color: #008000;">&#41;</span><span style="color: #008000;">&#40;</span>T<span style="color: #000040;">*</span><span style="color: #008000;">&#41;</span><span style="color: #0000dd;">1</span> <span style="color: #000040;">-</span> <span style="color: #008000;">&#40;</span><span style="color: #0000ff;">int</span><span style="color: #008000;">&#41;</span><span style="color: #008000;">&#40;</span>Singleton <span style="color: #000080;">&lt;</span>T<span style="color: #000080;">&gt;</span><span style="color: #000040;">*</span><span style="color: #008000;">&#41;</span><span style="color: #008000;">&#40;</span>T<span style="color: #000040;">*</span><span style="color: #008000;">&#41;</span><span style="color: #0000dd;">1</span><br />
&nbsp; &nbsp; ms_singleton <span style="color: #000080;">=</span> <span style="color: #008000;">&#40;</span>T<span style="color: #000040;">*</span><span style="color: #008000;">&#41;</span><span style="color: #008000;">&#40;</span><span style="color: #008000;">&#40;</span><span style="color: #0000ff;">int</span><span style="color: #008000;">&#41;</span><span style="color: #0000dd;">this</span> <span style="color: #000040;">+</span> offset<span style="color: #008000;">&#41;</span><span style="color: #008080;">;</span></div></div>
<p>i porównajmy go z tym:</p>
<div class="codecolorer-container cpp default" style="overflow:auto;white-space:nowrap;border:1px solid #9F9F9F;width:435px;"><div class="cpp codecolorer" style="padding:5px;font:normal 12px/1.4em Monaco, Lucida Console, monospace;white-space:nowrap">&nbsp; &nbsp; <span style="color: #0000ff;">int</span> offset <span style="color: #000080;">=</span> <span style="color: #0000ff;">reinterpret_cast</span><span style="color: #000080;">&lt;</span><span style="color: #0000ff;">int</span><span style="color: #000080;">&gt;</span><span style="color: #008000;">&#40;</span><span style="color: #0000ff;">reinterpret_cast</span><span style="color: #000080;">&lt;</span>T<span style="color: #000040;">*</span><span style="color: #000080;">&gt;</span><span style="color: #008000;">&#40;</span><span style="color: #0000dd;">1</span><span style="color: #008000;">&#41;</span><span style="color: #008000;">&#41;</span> <span style="color: #000040;">-</span><br />
&nbsp; &nbsp; <span style="color: #0000ff;">reinterpret_cast</span><span style="color: #000080;">&lt;</span><span style="color: #0000ff;">int</span><span style="color: #000080;">&gt;</span><span style="color: #008000;">&#40;</span><span style="color: #0000ff;">static_cast</span><span style="color: #000080;">&lt;</span>Singleton <span style="color: #000080;">&lt;</span>T<span style="color: #000080;">&gt;</span><span style="color: #000040;">*</span><span style="color: #000080;">&gt;</span><span style="color: #008000;">&#40;</span><span style="color: #0000ff;">reinterpret_cast</span><span style="color: #000080;">&lt;</span>T<span style="color: #000040;">*</span><span style="color: #000080;">&gt;</span><span style="color: #008000;">&#40;</span><span style="color: #0000dd;">1</span><span style="color: #008000;">&#41;</span><span style="color: #008000;">&#41;</span><span style="color: #008000;">&#41;</span><span style="color: #008080;">;</span><br />
&nbsp; &nbsp; ms_singleton <span style="color: #000080;">=</span> <span style="color: #0000ff;">reinterpret_cast</span><span style="color: #000080;">&lt;</span>T<span style="color: #000040;">*</span><span style="color: #000080;">&gt;</span><span style="color: #008000;">&#40;</span><span style="color: #008000;">&#40;</span><span style="color: #0000ff;">reinterpret_cast</span><span style="color: #000080;">&lt;</span><span style="color: #0000ff;">int</span><span style="color: #000080;">&gt;</span><span style="color: #008000;">&#40;</span><span style="color: #0000dd;">this</span><span style="color: #008000;">&#41;</span> <span style="color: #000040;">+</span> offset<span style="color: #008000;">&#41;</span><span style="color: #008000;">&#41;</span><span style="color: #008080;">;</span></div></div>
<p>Wariant C++ nie jest ani trochę piękniejszy, ale przynajmniej można od razu policzyć ile jest rzutowań i jakiego rodzaju. Poza tym, składnia wywołania funkcji pozwala od razu ogarnąć, które wyrażenia są rzutowane.
</li>
<li>Jak widać powyżej, są długie, rozwlekłe i brzydkie. I bardzo dobrze. Rzutowania to coś, czego nie powinno się stosować bez wyraźnej potrzeby, więc jeśli programiście <em>przeszkadza</em> pisanie takiego kodu, to tym lepiej dla projektu.</li>
<li>Lepiej rozdzielają odpowiedzialność &#8211; każdy z rodzajów rzutowania w C++ jest odpowiedzialny za inne zadanie. Dzięki temu kod lepiej wyraża intencje autora (np. widząc w kodzie <code class="codecolorer cpp default"><span class="cpp"><span style="color: #0000ff;">const_cast</span></span></code> masz pewność, że programista chciał jedynie zdjąć lub założyć modyfikator <code class="codecolorer cpp default"><span class="cpp"><span style="color: #0000ff;">const</span></span></code> albo <code class="codecolorer cpp default"><span class="cpp"><span style="color: #0000ff;">volatile</span></span></code>).</li>
<li>Mają spójną składnię. Rzutowania w stylu C mogą występować w dwóch wariantach &#8211; z typem w nawiasie oraz w składni &#8220;konstruktora&#8221;, z rzutowanym argumentem w nawiasie. Sam fakt, że w tym samym programie możemy natknąć się na oba warianty powoduje, że myśl o wyszukiwaniu ich w kodzie jest przerażająca.</li>
</ul>
<p>Zainteresowanych tematem rzutowania odsyłam do <a href="http://regedit.gamedev.pl/productions/artykuly/rzutowanie_typow_w_cpp.php5">świetnego artykułu Reg&#8217;a</a> poświęconego temu tematowi. Chciałbym zaznaczyć jednak, że nie zgadzam się z jego wnioskiem numer 2, tj.</p>
<blockquote><p>Nie ma praktycznych przesłanek, by rezygnować ze stosowania eleganckiego, zwięzłego rzutowania w stylu C na rzecz rozwlekłych operatorów static_cast i reinterpret_cast.</p></blockquote>
<p>Wydaje mi się, że w tym poście zawarłem wiele praktycznych przesłanek za rezygnacją z rzutowania w stylu C.</p>
]]></content:encoded>
			<wfw:commentRss>http://temporal.pr0.pl/devblog/2010/05/07/uzywaj-rzutowania-w-stylu-c/feed/</wfw:commentRss>
		<slash:comments>2</slash:comments>
		</item>
		<item>
		<title>CLOS jedynym słusznym systemem obiektowym? ;)</title>
		<link>http://temporal.pr0.pl/devblog/2010/05/04/clos-jedynym-slusznym-systemem-obiektowym/</link>
		<comments>http://temporal.pr0.pl/devblog/2010/05/04/clos-jedynym-slusznym-systemem-obiektowym/#comments</comments>
		<pubDate>Tue, 04 May 2010 09:59:21 +0000</pubDate>
		<dc:creator>Jacek Złydach</dc:creator>
				<category><![CDATA[Informatyka]]></category>
		<category><![CDATA[CLOS]]></category>
		<category><![CDATA[Common Lisp]]></category>
		<category><![CDATA[Lisp]]></category>

		<guid isPermaLink="false">http://temporal.pr0.pl/devblog/?p=1017</guid>
		<description><![CDATA[&#8220;o ile w ciągu zeszłego (2005) roku nic się nie zmieniło to ANSI Common Lisp jest jedynym  językiem obiektowym spełniającym wymagania organizacji &#8216;Object Managment Group&#8217; (tej od CORBY i UML-a). &#8220;
Szymon
]]></description>
			<content:encoded><![CDATA[<blockquote><p>&#8220;o ile w ciągu zeszłego (2005) roku nic się nie zmieniło to ANSI Common Lisp jest jedynym  językiem obiektowym spełniającym wymagania organizacji &#8216;Object Managment Group&#8217; (tej od CORBY i UML-a). &#8220;</p></blockquote>
<p><a href="http://binboy.sphere.pl/index.php?show=163">Szymon</a></p>
]]></content:encoded>
			<wfw:commentRss>http://temporal.pr0.pl/devblog/2010/05/04/clos-jedynym-slusznym-systemem-obiektowym/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Lisp, domknięcia i Pokemony</title>
		<link>http://temporal.pr0.pl/devblog/2010/05/01/lisp-domkniecia-i-pokemony/</link>
		<comments>http://temporal.pr0.pl/devblog/2010/05/01/lisp-domkniecia-i-pokemony/#comments</comments>
		<pubDate>Sat, 01 May 2010 20:02:07 +0000</pubDate>
		<dc:creator>Jacek Złydach</dc:creator>
				<category><![CDATA[Informatyka]]></category>
		<category><![CDATA[C]]></category>
		<category><![CDATA[Common Lisp]]></category>
		<category><![CDATA[domknięcia]]></category>
		<category><![CDATA[lambda expressions]]></category>
		<category><![CDATA[Lisp]]></category>
		<category><![CDATA[pokemony]]></category>
		<category><![CDATA[STL]]></category>

		<guid isPermaLink="false">http://temporal.pr0.pl/devblog/?p=1060</guid>
		<description><![CDATA[Ostatnio na Warsztacie pojawił się problem PoKeMoNizacji tekstu. Przykładowe rozwiązanie tego problemu w Common Lispie można zawrzeć w następujących funkcjach:
&#40;defun get-pokemonizer &#40;&#41;
&#160; &#40;let &#40;&#40;upkemonize nil&#41;&#41;
&#160; &#160; &#40;lambda &#40;letter&#41;
&#160; &#160; &#160; &#40;setf upkemonize &#40;not upkemonize&#41;&#41;
&#160; &#160; &#160; &#40;if upkemonize
&#160; &#160; &#160; &#160; &#160; &#40;char-upcase letter&#41;
&#160; &#160; &#160; &#160; &#160; &#40;char-downcase letter&#41;&#41;&#41;&#41;&#41;

&#40;defun pokemonize-string &#40;string-to-pokemonize&#41;
&#160; &#40;map 'string &#40;get-pokemonizer&#41; [...]]]></description>
			<content:encoded><![CDATA[<p>Ostatnio na Warsztacie <a href="http://forum.gamedev.pl/index.php/topic,16676.0.html">pojawił się</a> problem <a href="http://nonsensopedia.wikia.com/wiki/Pokemoniaste_pismo">PoKeMoNizacji tekstu</a>. Przykładowe rozwiązanie tego problemu w Common Lispie można zawrzeć w następujących funkcjach:</p>
<div class="codecolorer-container lisp default" style="overflow:auto;white-space:nowrap;border:1px solid #9F9F9F;width:435px;"><div class="lisp codecolorer" style="padding:5px;font:normal 12px/1.4em Monaco, Lucida Console, monospace;white-space:nowrap"><span style="color: #66cc66;">&#40;</span><span style="color: #b1b100;">defun</span> get-pokemonizer <span style="color: #66cc66;">&#40;</span><span style="color: #66cc66;">&#41;</span><br />
&nbsp; <span style="color: #66cc66;">&#40;</span><span style="color: #b1b100;">let</span> <span style="color: #66cc66;">&#40;</span><span style="color: #66cc66;">&#40;</span>upkemonize <span style="color: #b1b100;">nil</span><span style="color: #66cc66;">&#41;</span><span style="color: #66cc66;">&#41;</span><br />
&nbsp; &nbsp; <span style="color: #66cc66;">&#40;</span><span style="color: #b1b100;">lambda</span> <span style="color: #66cc66;">&#40;</span>letter<span style="color: #66cc66;">&#41;</span><br />
&nbsp; &nbsp; &nbsp; <span style="color: #66cc66;">&#40;</span><span style="color: #b1b100;">setf</span> upkemonize <span style="color: #66cc66;">&#40;</span><span style="color: #b1b100;">not</span> upkemonize<span style="color: #66cc66;">&#41;</span><span style="color: #66cc66;">&#41;</span><br />
&nbsp; &nbsp; &nbsp; <span style="color: #66cc66;">&#40;</span><span style="color: #b1b100;">if</span> upkemonize<br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #66cc66;">&#40;</span>char-upcase letter<span style="color: #66cc66;">&#41;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #66cc66;">&#40;</span>char-downcase letter<span style="color: #66cc66;">&#41;</span><span style="color: #66cc66;">&#41;</span><span style="color: #66cc66;">&#41;</span><span style="color: #66cc66;">&#41;</span><span style="color: #66cc66;">&#41;</span><br />
<br />
<span style="color: #66cc66;">&#40;</span><span style="color: #b1b100;">defun</span> pokemonize-string <span style="color: #66cc66;">&#40;</span>string-to-pokemonize<span style="color: #66cc66;">&#41;</span><br />
&nbsp; <span style="color: #66cc66;">&#40;</span>map 'string <span style="color: #66cc66;">&#40;</span>get-pokemonizer<span style="color: #66cc66;">&#41;</span> string-to-pokemonize<span style="color: #66cc66;">&#41;</span><span style="color: #66cc66;">&#41;</span></div></div>
<p>Problem pokemonizacji tekstu sam w sobie <a href="http://forum.gamedev.pl/index.php/topic,16676.msg199119.html#msg199119">nie jest wart poświęcania mu miejsca</a>, ale chciałbym wykorzystać tę okazję by pokazać kilka ciekawych rzeczy w Common Lispie.</p>
<p>Zacznijmy od końca. Funkcja</p>
<div class="codecolorer-container lisp default" style="overflow:auto;white-space:nowrap;border:1px solid #9F9F9F;width:435px;"><div class="lisp codecolorer" style="padding:5px;font:normal 12px/1.4em Monaco, Lucida Console, monospace;white-space:nowrap"><span style="color: #66cc66;">&#40;</span><span style="color: #b1b100;">defun</span> pokemonize-string <span style="color: #66cc66;">&#40;</span>string-to-pokemonize<span style="color: #66cc66;">&#41;</span><br />
&nbsp; <span style="color: #66cc66;">&#40;</span>map 'string <span style="color: #66cc66;">&#40;</span>get-pokemonizer<span style="color: #66cc66;">&#41;</span> string-to-pokemonize<span style="color: #66cc66;">&#41;</span><span style="color: #66cc66;">&#41;</span></div></div>
<p>mogłaby w C++ być napisana jako:</p>
<div class="codecolorer-container cpp default" style="overflow:auto;white-space:nowrap;border:1px solid #9F9F9F;width:435px;"><div class="cpp codecolorer" style="padding:5px;font:normal 12px/1.4em Monaco, Lucida Console, monospace;white-space:nowrap"><span style="color: #339900;">#include &lt;algorithm&gt;</span><br />
<br />
std<span style="color: #008080;">::</span><span style="color: #007788;">string</span> pokemonize_string<span style="color: #008000;">&#40;</span>std<span style="color: #008080;">::</span><span style="color: #007788;">string</span> input<span style="color: #008000;">&#41;</span><br />
<span style="color: #008000;">&#123;</span><br />
&nbsp; &nbsp; std<span style="color: #008080;">::</span><span style="color: #007788;">string</span> outStr<span style="color: #008000;">&#40;</span>input<span style="color: #008000;">&#41;</span><span style="color: #008080;">;</span><br />
&nbsp; &nbsp; std<span style="color: #008080;">::</span><span style="color: #007788;">transform</span><span style="color: #008000;">&#40;</span>input.<span style="color: #007788;">begin</span><span style="color: #008000;">&#40;</span><span style="color: #008000;">&#41;</span>, input.<span style="color: #007788;">end</span><span style="color: #008000;">&#40;</span><span style="color: #008000;">&#41;</span>, outStr.<span style="color: #007788;">begin</span><span style="color: #008000;">&#40;</span><span style="color: #008000;">&#41;</span>, pokemonize_letter<span style="color: #008000;">&#41;</span><span style="color: #008080;">;</span><br />
&nbsp; &nbsp; <span style="color: #0000ff;">return</span> outStr<span style="color: #008080;">;</span><br />
<span style="color: #008000;">&#125;</span></div></div>
<p><code class="codecolorer cpp default"><span class="cpp">std<span style="color: #008080;">::</span><span style="color: #007788;">transform</span></span></code> z C++ i <code class="codecolorer lisp default"><span class="lisp">map</span></code> z Common Lispu to przykłady tak zwanych <strong><a href="http://en.wikipedia.org/wiki/Higher-order_function">funkcji wyższego rzędu</a></strong><a name="POST_POKEMON_MT_1" href="#POST_POKEMON_REF_1">*</a>. Jak nietrudno się domyśleć, zadaniem użytych przez nas funkcji jest przejście przez cały napis znak po znaku i zastosowanie na każdym elemencie funkcji przekazanej jako parametr. Zauważmy, że nie napisaliśmy tutaj żadnej iteracji, żadnej pętli <code class="codecolorer cpp default"><span class="cpp"><span style="color: #0000ff;">for</span></span></code> &#8211; myślimy w kategoriach &#8220;przejścia funkcją po napisie&#8221;. Taki przeskok myślowy jest bardzo cenny; w C++ zalecane jest (mniej błędów się robi) używanie algorytmów z biblioteki STL, które umieją w różny sposób stosować przekazane funkcje na elementach pojemników (polecam przeglądnąć <a href="http://www.cplusplus.com/reference/algorithm/">nagłówek &lt;algorithm&gt;</a>).</p>
<p>Skoro mamy już trzon naszego rozwiązania, warto pomyśleć nad samą funkcją pokemonizującą. Według <a href="http://forum.gamedev.pl/index.php/topic,16676.msg198983.html#msg198983">oryginalnej definicji problemu</a> funkcja ma sprawiać, że wynikowy tekst będzie miał co drugą literę wielką. Przyjmijmy automatycznie, że pozostałe litery mają być małe. W naszym rozwiązaniu funkcja pokemonizująca musi więc zmieniać swoje zachowanie w kolejnych wywołaniach &#8211; powinna zamieniać litery raz na małe, a raz na duże. <strong>Musimy więc w funkcji ukryć stan</strong>. Dla przypomnienia, w Common Lispie mieliśmy funkcję:</p>
<div class="codecolorer-container lisp default" style="overflow:auto;white-space:nowrap;border:1px solid #9F9F9F;width:435px;"><div class="lisp codecolorer" style="padding:5px;font:normal 12px/1.4em Monaco, Lucida Console, monospace;white-space:nowrap"><span style="color: #66cc66;">&#40;</span><span style="color: #b1b100;">defun</span> get-pokemonizer <span style="color: #66cc66;">&#40;</span><span style="color: #66cc66;">&#41;</span><br />
&nbsp; <span style="color: #66cc66;">&#40;</span><span style="color: #b1b100;">let</span> <span style="color: #66cc66;">&#40;</span><span style="color: #66cc66;">&#40;</span>upkemonize <span style="color: #b1b100;">nil</span><span style="color: #66cc66;">&#41;</span><span style="color: #66cc66;">&#41;</span><br />
&nbsp; &nbsp; <span style="color: #66cc66;">&#40;</span><span style="color: #b1b100;">lambda</span> <span style="color: #66cc66;">&#40;</span>letter<span style="color: #66cc66;">&#41;</span><br />
&nbsp; &nbsp; &nbsp; <span style="color: #66cc66;">&#40;</span><span style="color: #b1b100;">setf</span> upkemonize <span style="color: #66cc66;">&#40;</span><span style="color: #b1b100;">not</span> upkemonize<span style="color: #66cc66;">&#41;</span><span style="color: #66cc66;">&#41;</span><br />
&nbsp; &nbsp; &nbsp; <span style="color: #66cc66;">&#40;</span><span style="color: #b1b100;">if</span> upkemonize<br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #66cc66;">&#40;</span>char-upcase letter<span style="color: #66cc66;">&#41;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #66cc66;">&#40;</span>char-downcase letter<span style="color: #66cc66;">&#41;</span><span style="color: #66cc66;">&#41;</span><span style="color: #66cc66;">&#41;</span><span style="color: #66cc66;">&#41;</span><span style="color: #66cc66;">&#41;</span></div></div>
<p>Zadaniem funkcji <code class="codecolorer lisp default"><span class="lisp"><span style="color: #66cc66;">&#40;</span>get-pokemonizer<span style="color: #66cc66;">&#41;</span></span></code> jest <strong>zbudowanie funkcji</strong> pokemonizującej pojedynczy znak. Sama funkcja pokemonizująca zaczyna się od wyrażenia <code class="codecolorer lisp default"><span class="lisp"><span style="color: #66cc66;">&#40;</span><span style="color: #b1b100;">lambda</span> <span style="color: #66cc66;">...</span></span></code>, które oznacza po prostu stworzenie <strong>funkcji anonimowej</strong> (nienazwanej). Zanim uzasadnię, dlaczego potrzebny jest generator takich funkcji, chciałbym znów odnieść się do kodu z C++ i porównać kody odpowiedzialne za samą zmianę znaku.</p>
<div class="codecolorer-container cpp default" style="overflow:auto;white-space:nowrap;border:1px solid #9F9F9F;width:435px;"><div class="cpp codecolorer" style="padding:5px;font:normal 12px/1.4em Monaco, Lucida Console, monospace;white-space:nowrap"><span style="color: #339900;">#include &lt;cctype&gt; &nbsp; //potrzebne do std::tolower() i std::toupper()</span><br />
<span style="color: #0000ff;">bool</span> g_upCase <span style="color: #000080;">=</span> <span style="color: #0000ff;">false</span><span style="color: #008080;">;</span><br />
<span style="color: #0000ff;">char</span> pokemonize_letter<span style="color: #008000;">&#40;</span><span style="color: #0000ff;">char</span> input<span style="color: #008000;">&#41;</span>&nbsp; <span style="color: #666666;">//(lambda (letter)</span><br />
<span style="color: #008000;">&#123;</span><br />
&nbsp; &nbsp; g_upCase <span style="color: #000080;">=</span> <span style="color: #000040;">!</span>g_upCase<span style="color: #008080;">;</span> &nbsp; &nbsp; &nbsp; <span style="color: #666666;">//(setf upkemonize (not upkemonize))</span><br />
<br />
&nbsp; &nbsp; <span style="color: #0000ff;">return</span> <span style="color: #008000;">&#40;</span>g_upCase<span style="color: #008000;">&#41;</span> <span style="color: #008080;">?</span> <span style="color: #666666;">//(if upkemonize</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; std<span style="color: #008080;">::</span><span style="color: #0000dd;">toupper</span><span style="color: #008000;">&#40;</span>input<span style="color: #008000;">&#41;</span> <span style="color: #008080;">:</span> &nbsp; <span style="color: #666666;">//(char-upcase letter)</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; std<span style="color: #008080;">::</span><span style="color: #0000dd;">tolower</span><span style="color: #008000;">&#40;</span>input<span style="color: #008000;">&#41;</span><span style="color: #008080;">;</span> &nbsp; &nbsp;<span style="color: #666666;">//(char-downcase letter)))</span><br />
<span style="color: #008000;">&#125;</span></div></div>
<p>W komentarzach zawarty jest odpowiadający kod w Common Lispie. Czytelniku, zastanów się przez chwilkę &#8211; co z powyższą funkcją w C++ jest nie tak?</p>
<p>Odpowiedź: stan jest globalny. Wyobraźmy sobie, że chcielibyśmy używać tej samej funkcji wielokrotnie. Do tego jeszcze czasem w osobnych wątkach. Widać wyraźnie, że wiele wywołań funkcji <code class="codecolorer cpp default"><span class="cpp">pokemonize_char<span style="color: #008000;">&#40;</span><span style="color: #008000;">&#41;</span></span></code> będzie pracowało na tej samej zmiennej globalnej, która trzyma stan. Przejście na zmienną statyczną nie rozwiąże problemu &#8211; jedynie ograniczy widoczność stanu (co jest dobrą rzeczą). W C++ wypracowano jednak rozwiązanie &#8211; jest nim stworzenie <strong><a href="http://en.wikipedia.org/wiki/Function_object">obiektu funkcyjnego</a></strong> (inaczej funktora). Jest to obiekt przeciążający <code class="codecolorer cpp default"><span class="cpp">operator<span style="color: #008000;">&#40;</span><span style="color: #008000;">&#41;</span></span></code>, czyli operator wywołania funkcji. Taki obiekt może skutecznie udawać prawdziwą funkcję, a jednocześnie trzymać w sobie stan. Lepsze rozwiązanie naszego problemu w języku C++ wyglądałoby więc tak:</p>
<div class="codecolorer-container cpp default" style="overflow:auto;white-space:nowrap;border:1px solid #9F9F9F;width:435px;height:300px;"><div class="cpp codecolorer" style="padding:5px;font:normal 12px/1.4em Monaco, Lucida Console, monospace;white-space:nowrap"><span style="color: #339900;">#include &lt;algorithm&gt;</span><br />
<span style="color: #339900;">#include &lt;cctype&gt; &nbsp; //potrzebne do std::tolower() i std::toupper()</span><br />
<span style="color: #666666;">//dziedziczenie po std::unary_function ze wzgledu na STL</span><br />
<span style="color: #0000ff;">class</span> Pokemonizer <span style="color: #008080;">:</span> <span style="color: #0000ff;">public</span> std<span style="color: #008080;">::</span><span style="color: #007788;">unary_function</span><span style="color: #000080;">&lt;</span><span style="color: #0000ff;">char</span>, <span style="color: #0000ff;">char</span><span style="color: #000080;">&gt;</span><br />
<span style="color: #008000;">&#123;</span><br />
<span style="color: #0000ff;">protected</span><span style="color: #008080;">:</span><br />
&nbsp; &nbsp; <span style="color: #0000ff;">bool</span> upCase<span style="color: #008080;">;</span><br />
<span style="color: #0000ff;">public</span><span style="color: #008080;">:</span><br />
&nbsp; &nbsp; Pokemonizer<span style="color: #008000;">&#40;</span><span style="color: #008000;">&#41;</span> <span style="color: #008080;">:</span> upCase<span style="color: #008000;">&#40;</span><span style="color: #0000ff;">false</span><span style="color: #008000;">&#41;</span> <span style="color: #008000;">&#123;</span><span style="color: #008000;">&#125;</span><br />
&nbsp; &nbsp; <span style="color: #0000ff;">char</span> operator<span style="color: #008000;">&#40;</span><span style="color: #008000;">&#41;</span><span style="color: #008000;">&#40;</span><span style="color: #0000ff;">char</span> input<span style="color: #008000;">&#41;</span><br />
&nbsp; &nbsp; <span style="color: #008000;">&#123;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; upCase <span style="color: #000080;">=</span> <span style="color: #000040;">!</span>upCase<span style="color: #008080;">;</span><br />
<br />
&nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #0000ff;">return</span> <span style="color: #008000;">&#40;</span>upCase<span style="color: #008000;">&#41;</span> <span style="color: #008080;">?</span> &nbsp; <br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; std<span style="color: #008080;">::</span><span style="color: #0000dd;">toupper</span><span style="color: #008000;">&#40;</span>input<span style="color: #008000;">&#41;</span> <span style="color: #008080;">:</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; std<span style="color: #008080;">::</span><span style="color: #0000dd;">tolower</span><span style="color: #008000;">&#40;</span>input<span style="color: #008000;">&#41;</span><span style="color: #008080;">;</span><br />
&nbsp; &nbsp; <span style="color: #008000;">&#125;</span><br />
<span style="color: #008000;">&#125;</span><span style="color: #008080;">;</span><br />
<br />
std<span style="color: #008080;">::</span><span style="color: #007788;">string</span> pokemonize_string<span style="color: #008000;">&#40;</span>std<span style="color: #008080;">::</span><span style="color: #007788;">string</span> input<span style="color: #008000;">&#41;</span><br />
<span style="color: #008000;">&#123;</span><br />
&nbsp; &nbsp; std<span style="color: #008080;">::</span><span style="color: #007788;">string</span> outStr<span style="color: #008000;">&#40;</span>input<span style="color: #008000;">&#41;</span><span style="color: #008080;">;</span><br />
&nbsp; &nbsp; std<span style="color: #008080;">::</span><span style="color: #007788;">transform</span><span style="color: #008000;">&#40;</span>input.<span style="color: #007788;">begin</span><span style="color: #008000;">&#40;</span><span style="color: #008000;">&#41;</span>, input.<span style="color: #007788;">end</span><span style="color: #008000;">&#40;</span><span style="color: #008000;">&#41;</span>, outStr.<span style="color: #007788;">begin</span><span style="color: #008000;">&#40;</span><span style="color: #008000;">&#41;</span>, Pokemonizer<span style="color: #008000;">&#40;</span><span style="color: #008000;">&#41;</span><span style="color: #008000;">&#41;</span><span style="color: #008080;">;</span><br />
&nbsp; &nbsp; <span style="color: #0000ff;">return</span> outStr<span style="color: #008080;">;</span><br />
<span style="color: #008000;">&#125;</span></div></div>
<p>W tym momencie wywołania <code class="codecolorer cpp default"><span class="cpp">pokemonize_string<span style="color: #008000;">&#40;</span><span style="color: #008000;">&#41;</span></span></code> są już <a href="http://en.wikipedia.org/wiki/Thread_safety">thread-safe</a>. Musieliśmy w tym celu napisać kod tak, by przy każdym wywołaniu pokemonizacji napisu tworzony był <strong>nowy</strong> obiekt funkcyjny <strong>z własnym stanem</strong>.</p>
<p>Wróćmy teraz do Common Lispu. Powyższy kod C++ jest odpowiednikiem rozwiązania w Lispie, więc możemy je ze sobą dokładnie porównać. Dla przypomnienia:</p>
<div class="codecolorer-container lisp default" style="overflow:auto;white-space:nowrap;border:1px solid #9F9F9F;width:435px;"><div class="lisp codecolorer" style="padding:5px;font:normal 12px/1.4em Monaco, Lucida Console, monospace;white-space:nowrap"><span style="color: #66cc66;">&#40;</span><span style="color: #b1b100;">defun</span> get-pokemonizer <span style="color: #66cc66;">&#40;</span><span style="color: #66cc66;">&#41;</span><br />
&nbsp; <span style="color: #66cc66;">&#40;</span><span style="color: #b1b100;">let</span> <span style="color: #66cc66;">&#40;</span><span style="color: #66cc66;">&#40;</span>upkemonize <span style="color: #b1b100;">nil</span><span style="color: #66cc66;">&#41;</span><span style="color: #66cc66;">&#41;</span><br />
&nbsp; &nbsp; <span style="color: #66cc66;">&#40;</span><span style="color: #b1b100;">lambda</span> <span style="color: #66cc66;">&#40;</span>letter<span style="color: #66cc66;">&#41;</span><br />
&nbsp; &nbsp; &nbsp; <span style="color: #66cc66;">&#40;</span><span style="color: #b1b100;">setf</span> upkemonize <span style="color: #66cc66;">&#40;</span><span style="color: #b1b100;">not</span> upkemonize<span style="color: #66cc66;">&#41;</span><span style="color: #66cc66;">&#41;</span><br />
&nbsp; &nbsp; &nbsp; <span style="color: #66cc66;">&#40;</span><span style="color: #b1b100;">if</span> upkemonize<br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #66cc66;">&#40;</span>char-upcase letter<span style="color: #66cc66;">&#41;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #66cc66;">&#40;</span>char-downcase letter<span style="color: #66cc66;">&#41;</span><span style="color: #66cc66;">&#41;</span><span style="color: #66cc66;">&#41;</span><span style="color: #66cc66;">&#41;</span><span style="color: #66cc66;">&#41;</span><br />
<br />
<span style="color: #66cc66;">&#40;</span><span style="color: #b1b100;">defun</span> pokemonize-string <span style="color: #66cc66;">&#40;</span>string-to-pokemonize<span style="color: #66cc66;">&#41;</span><br />
&nbsp; <span style="color: #66cc66;">&#40;</span>map 'string <span style="color: #66cc66;">&#40;</span>get-pokemonizer<span style="color: #66cc66;">&#41;</span> string-to-pokemonize<span style="color: #66cc66;">&#41;</span><span style="color: #66cc66;">&#41;</span></div></div>
<p>Wspomniałem wcześniej, że zadaniem funkcji <code class="codecolorer lisp default"><span class="lisp"><span style="color: #66cc66;">&#40;</span>get-pokemonizer<span style="color: #66cc66;">&#41;</span></span></code> jest stworzenie funkcji pokemonizującej pojedynczy znak. Odpowiednikiem tej funkcji w C++ jest <strong>konstruktor funktora Pokemonizer</strong>. Jest jednak zasadnicza różnica między funkcjami C++ i Common Lispu &#8211; w tym drugim języku <strong>funkcję są tzw. <a href="http://en.wikipedia.org/wiki/First-class_object">obiektami first-class</a></strong>. Oznacza to między innymi, że taką funkcję można przechowywać w zmiennej, przypisywać i zwracać z innych funkcji. Dlatego nasz generator pokemonizerów po prostu <strong>zwraca funkcję</strong>. Innymi słowy, <strong>funkcje w Lispie posiadają te cechy, które w C++ musimy symulować za pomocą obiektów funkcyjnych</strong>.</p>
<p>Pozostaje jeszcze powiedzieć, w jaki sposób osadzamy stan w naszej funkcji pokemonizującej. W Lispie możemy zastosować tak zwane <a href="http://en.wikipedia.org/wiki/Closure_%28computer_science%29">domknięcia</a>. Jest to bardzo interesująca technika programistyczna. Zauważmy, że przed stworzeniem samej funkcji pokemonizującej (wyrażenie <code class="codecolorer lisp default"><span class="lisp"><span style="color: #66cc66;">&#40;</span><span style="color: #b1b100;">lambda</span> <span style="color: #66cc66;">...</span></span></code>) definiujemy zmienną (<code class="codecolorer lisp default"><span class="lisp"><span style="color: #66cc66;">&#40;</span><span style="color: #b1b100;">let</span> <span style="color: #66cc66;">&#40;</span><span style="color: #66cc66;">&#40;</span>upkemonize <span style="color: #b1b100;">nil</span><span style="color: #66cc66;">&#41;</span><span style="color: #66cc66;">&#41;</span> <span style="color: #66cc66;">...</span></span></code>). Mówiąc językiem C++, nasza anonimowa funkcja znajduje się <em>w zakresie</em> zmiennej <code class="codecolorer lisp default"><span class="lisp">upkemonize</span></code>. Co więcej, ona <strong>korzysta z tej zmiennej</strong>.</p>
<p>Powtórzę jeszcze raz &#8211; anonimowa funkcja, która ma zaraz zostać zwrócona z generatora używa zmiennej, która została stworzona w tym generatorze w momencie jego wywołania. <code class="codecolorer lisp default"><span class="lisp">upkemonize</span></code> to zwykła zmienna lokalna. Nowy pokemonizer pracuje na obiekcie, który &#8211; według C++&#8217;owej intuicji &#8211; przestał istnieć tak szybko, jak tylko swoje działanie skończył generator. To może być lekko mind-blowing na początku. Dla mnie było.</p>
<p>Ilekroć generator zostanie wywołany, powstanie nowa zmienna <code class="codecolorer lisp default"><span class="lisp">upkemonize</span></code>, która na stałe zostanie związana ze zwróconym pokemonizerem. Ten ostatni trzyma w niej swój stan; z jego punktu widzenia ta zmienna jest zewnętrzna, &#8216;globalna&#8217;. Taką technikę programistyczną nazywamy domknięciem &#8211; funkcja &#8220;domyka się&#8221; nad zmienną zadeklarowaną na zewnątrz niej.</p>
<p>Kilka wniosków, które wynikają z powyższych rozważań:</p>
<ul>
<li><strong>Funkcje wyższego rzędu są bardzo eleganckim sposobem krótkiego zapisywania algorytmów dotyczących całego zbioru danych</strong>. Zamiast ręcznie pisać pętle kopiujące, zmieniające czy dzielące duże grupy danych możemy użyć funkcji przyjmujących funkcje jako parametr, by w jednym wyrażeniu zapisać nasze rozwiązanie. W C++ spotykamy się z nimi często w STLu.</li>
<li><strong>Funktory to sposób emulacji mechanizmu funkcji jako obiektów first-class</strong> &#8211; czyli czegoś, co jest fundamentalną właściwością Lispu. Możliwość traktowania funkcji jak każdego innego typu danych jest bardzo przydatna.</li>
<li><strong>Common Lisp zawiera mnóstwo cech, które w C++ wymagają strasznego kombinowania</strong> &#8211; funkcje jako obiekty first-class, wyrażenia Lambda<a name="POST_POKEMON_MT_2" href="#POST_POKEMON_REF_2">**</a> i domknięcia to tylko niektóre z nich.</li>
<li><strong>Można pisać bardzo, bardzo długie elaboraty o prostych problemach <img src='http://temporal.pr0.pl/devblog/wp-includes/images/smilies/icon_wink.gif' alt=';)' class='wp-smiley' /> </strong></li>
</ul>
<p><a name="POST_POKEMON_REF_1" href="#POST_POKEMON_MT_1">*</a> &#8211; Ściślej mówiąc, C++ tylko sprytnie <a href="http://en.wikipedia.org/wiki/Higher-order_function#Alternatives">emuluje</a> funkcje wyższego rzędu &#8211; taka funkcjonalność nie jest wbudowana w język.<br />
<a name="POST_POKEMON_REF_2" href="#POST_POKEMON_MT_2">**</a> &#8211; Wyrażenia Lambda, czyli tworzenie funkcji anonimowych, są elementem nowego standardu języka C++ o nazwie roboczej <a href="http://pl.wikipedia.org/wiki/C%2B%2B0x">C++0x</a>.</p>
]]></content:encoded>
			<wfw:commentRss>http://temporal.pr0.pl/devblog/2010/05/01/lisp-domkniecia-i-pokemony/feed/</wfw:commentRss>
		<slash:comments>7</slash:comments>
		</item>
		<item>
		<title>IGK i artykuł o fizyce</title>
		<link>http://temporal.pr0.pl/devblog/2010/04/18/igk-i-artykul-o-fizyce/</link>
		<comments>http://temporal.pr0.pl/devblog/2010/04/18/igk-i-artykul-o-fizyce/#comments</comments>
		<pubDate>Sat, 17 Apr 2010 22:39:56 +0000</pubDate>
		<dc:creator>Jacek Złydach</dc:creator>
				<category><![CDATA[Informatyka]]></category>
		<category><![CDATA[Tworzenie gier]]></category>
		<category><![CDATA[artykuły]]></category>
		<category><![CDATA[IGK]]></category>
		<category><![CDATA[porady]]></category>

		<guid isPermaLink="false">http://temporal.pr0.pl/devblog/?p=1051</guid>
		<description><![CDATA[W zeszły weekend brałem udział w VII Ogólnopolskiej Konferencji Inżynierii Gier Komputerowych (w skrócie &#8211; IGK). Było to niezapomniane i długo wyczekiwane przeżycie &#8211; w końcu na tę konferencję usiłowałem się wybrać już siódmy raz, i dopiero teraz się to udało! W szczególności cieszę się z możliwości spotkania na żywo kolegów z Warsztatu.
Z samego IGK [...]]]></description>
			<content:encoded><![CDATA[<p>W zeszły weekend brałem udział w <a href="http://igk.ap.siedlce.pl">VII Ogólnopolskiej Konferencji Inżynierii Gier Komputerowych</a> (w skrócie &#8211; IGK). Było to niezapomniane i długo wyczekiwane przeżycie &#8211; w końcu na tę konferencję usiłowałem się wybrać już siódmy raz, i dopiero teraz się to udało! W szczególności cieszę się z możliwości spotkania na żywo kolegów z <a href="http://www.gamedev.pl/">Warsztatu</a>.</p>
<p>Z samego IGK relacji i zdjęć jest już <a href="http://www.gamedev.pl/news,724.html">dość sporo</a>, więc póki co nie będę się dokładał <img src='http://temporal.pr0.pl/devblog/wp-includes/images/smilies/icon_smile.gif' alt=':)' class='wp-smiley' /> . Na konferencji brałem też udział w Compo, ale ponieważ nasz projekt konkursowy jest w trakcie modyfikacji (postanowiliśmy w swoim zespole opublikować go jako skończoną grę), to wrócę do niego gdy prace dobiegną końca.</p>
<p>Pobyt na IGK (a konkretniej, rozmowy z Warsztatowiczami) uświadomił mi, że wielu koderów nie zdaje sobie sprawy, iż tradycyjna (gimnazjalna <img src='http://temporal.pr0.pl/devblog/wp-includes/images/smilies/icon_smile.gif' alt=':)' class='wp-smiley' /> ) metoda pisania pętli głównej nie jest zbyt dobra. Inni boją się przejścia na tak zwaną symulacje stałokrokową, ponieważ wydaje im się, że jest ona bardzo złożona i niewiele wnosi. <strong>Prawda jest jednak taka, że stały krok czasowy jest konieczny, jeżeli na dłuższą metę chcemy mieć jakąkolwiek sensowną fizykę w grze!</strong> Z tego powodu postanowiłem napisać artykuł, który został wczoraj <a href="http://www.gamedev.pl/articles.php?x=view&#038;id=370">opublikowany na Warsztacie</a>. Artykuł ten, zatytułowany <a href="http://temporal.pr0.pl/devblog/artykuly/jak-nalezy-pisac-aktualizacje-stanu-gry/">&#8220;Jak należy pisać aktualizację stanu gry&#8221;</a>, poświęcony jest całkowicie tematowi symulacji stałokrokowej. Mam nadzieję, że przyda się on zarówno początkującym jak i zaawansowanym programistom gier. Zapraszam do lektury i komentarzy!</p>
]]></content:encoded>
			<wfw:commentRss>http://temporal.pr0.pl/devblog/2010/04/18/igk-i-artykul-o-fizyce/feed/</wfw:commentRss>
		<slash:comments>3</slash:comments>
		</item>
		<item>
		<title>COS &#8211; C Object System</title>
		<link>http://temporal.pr0.pl/devblog/2010/04/13/cos-c-object-system/</link>
		<comments>http://temporal.pr0.pl/devblog/2010/04/13/cos-c-object-system/#comments</comments>
		<pubDate>Tue, 13 Apr 2010 18:35:58 +0000</pubDate>
		<dc:creator>Jacek Złydach</dc:creator>
				<category><![CDATA[Informatyka]]></category>
		<category><![CDATA[C]]></category>
		<category><![CDATA[CLOS]]></category>
		<category><![CDATA[Common Lisp]]></category>
		<category><![CDATA[Lisp]]></category>

		<guid isPermaLink="false">http://temporal.pr0.pl/devblog/?p=1014</guid>
		<description><![CDATA[Piotr Matuszkiewicz znalazł ostatnio link do dokumentu opisującego bibliotekę COS. Projekt C Object System aktualnie rozwijany jest na SourceForge dzięki Laurentowi Deniau, pracownikowi CERN. Cytując wypowiedź Pawła Laska na kanale #lisp, &#8220;this is, IMHO, awesome case of CLOS being translated to C&#8221;.
Opis dokumentu (a zarazem biblioteki) głosi:
The C Object System (Cos) is a small C [...]]]></description>
			<content:encoded><![CDATA[<p>Piotr Matuszkiewicz znalazł ostatnio <a href="http://arxiv.org/PS_cache/arxiv/pdf/1003/1003.2547v1.pdf">link do dokumentu</a> opisującego bibliotekę COS. Projekt <strong><a href="http://sourceforge.net/projects/cos/">C Object System</a></strong> aktualnie <a href="http://ldeniau.web.cern.ch/ldeniau/cos.html">rozwijany jest</a> na SourceForge dzięki Laurentowi Deniau, pracownikowi <a href="http://pl.wikipedia.org/wiki/CERN">CERN</a>. Cytując wypowiedź <a href="http://unya.wordpress.com">Pawła Laska</a> na kanale #lisp, &#8220;this is, IMHO, awesome case of <a href="http://en.wikipedia.org/wiki/Common_Lisp_Object_System">CLOS</a> being translated to C&#8221;.</p>
<p><a href="http://arxiv.org/abs/1003.2547">Opis dokumentu</a> (a zarazem biblioteki) głosi:</p>
<blockquote><p>The C Object System (Cos) is a small C library which implements high-level concepts available in Clos, Objc and other object-oriented programming languages: uniform object model (class, meta-class and property-metaclass), generic functions, multi-methods, delegation, properties, exceptions, contracts and closures.</p></blockquote>
<p>Oparta o Common Lisp Object System architektura COS&#8217;a pozwala nam więc używać technik obiektowych <strong>daleko wykraczających poza te zaimplementowane w C++ czy Javie</strong>.</p>
<p>Poniżej zamieszczam kodu oparty o jeden z przykładów w bibliotece, deklarujący klasę string z metodami do jej tworzenia i usuwania. Widać wyraźnie wpływy CLOS&#8217;u.</p>
<div class="codecolorer-container c default" style="overflow:auto;white-space:nowrap;border:1px solid #9F9F9F;width:435px;height:300px;"><div class="c codecolorer" style="padding:5px;font:normal 12px/1.4em Monaco, Lucida Console, monospace;white-space:nowrap">defclass<span style="color: #009900;">&#40;</span>File<span style="color: #339933;">,</span> Stream<span style="color: #009900;">&#41;</span><br />
&nbsp; FILE <span style="color: #339933;">*</span>file<span style="color: #339933;">;</span><br />
endclass<br />
<br />
<span style="color: #808080; font-style: italic;">/* ... */</span><br />
<br />
makclass<span style="color: #009900;">&#40;</span>String<span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span><br />
<br />
defmethod<span style="color: #009900;">&#40;</span>OBJ<span style="color: #339933;">,</span> ginitWithStr<span style="color: #339933;">,</span> String<span style="color: #339933;">,</span> <span style="color: #009900;">&#40;</span>STR<span style="color: #009900;">&#41;</span>str<span style="color: #009900;">&#41;</span><br />
&nbsp; useclass<span style="color: #009900;">&#40;</span>ExBadAlloc<span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span><br />
<br />
&nbsp; self<span style="color: #339933;">-&gt;</span>str <span style="color: #339933;">=</span> strdup<span style="color: #009900;">&#40;</span>str<span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span><br />
&nbsp; <span style="color: #b1b100;">if</span> <span style="color: #009900;">&#40;</span><span style="color: #339933;">!</span>self<span style="color: #339933;">-&gt;</span>str<span style="color: #009900;">&#41;</span><br />
&nbsp; &nbsp; THROW<span style="color: #009900;">&#40;</span>ExBadAlloc<span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span><br />
&nbsp; <br />
&nbsp; retmethod<span style="color: #009900;">&#40;</span>_1<span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span><br />
endmethod<br />
<br />
defmethod<span style="color: #009900;">&#40;</span>OBJ<span style="color: #339933;">,</span> gdeinit<span style="color: #339933;">,</span> String<span style="color: #009900;">&#41;</span><br />
&nbsp; free<span style="color: #009900;">&#40;</span>self<span style="color: #339933;">-&gt;</span>str<span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span><br />
&nbsp; retmethod<span style="color: #009900;">&#40;</span>_1<span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span><br />
endmethod</div></div>
]]></content:encoded>
			<wfw:commentRss>http://temporal.pr0.pl/devblog/2010/04/13/cos-c-object-system/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>#include to jest Copy-Paste</title>
		<link>http://temporal.pr0.pl/devblog/2010/04/06/include-to-jest-copy-paste/</link>
		<comments>http://temporal.pr0.pl/devblog/2010/04/06/include-to-jest-copy-paste/#comments</comments>
		<pubDate>Tue, 06 Apr 2010 00:07:03 +0000</pubDate>
		<dc:creator>Jacek Złydach</dc:creator>
				<category><![CDATA[Informatyka]]></category>
		<category><![CDATA[C]]></category>
		<category><![CDATA[porady]]></category>
		<category><![CDATA[preprocesor]]></category>

		<guid isPermaLink="false">http://temporal.pr0.pl/devblog/?p=980</guid>
		<description><![CDATA[Dzisiaj o rzeczy, która początkującym (a nawet i średnio zaawansowanym) programistom C/C++ zdaje się czasem umykać &#8211; jak działa dyrektywa #include w języku C++.
Cytując z MSDN:
The #include directive tells the preprocessor to treat the contents of a specified file as if those contents had appeared in the source program at the point where the directive [...]]]></description>
			<content:encoded><![CDATA[<p>Dzisiaj o rzeczy, która początkującym (a nawet i średnio zaawansowanym) programistom C/C++ zdaje się czasem umykać &#8211; jak działa dyrektywa <code class="codecolorer cpp default"><span class="cpp"><span style="color: #339900;">#include</span></span></code> w języku C++.</p>
<p><a href="http://msdn.microsoft.com/en-us/library/36k2cdd4%28VS.71%29.aspx">Cytując z MSDN</a>:</p>
<blockquote><p>The #include directive tells the preprocessor to treat the contents of a specified file as if those contents had appeared in the source program at the point where the directive appears.</p></blockquote>
<p>Tak. <code class="codecolorer cpp default"><span class="cpp"><span style="color: #339900;">#include</span></span></code> <strong>to jest copy-paste</strong>. Ta dyrektywa nie robi nic innego, tylko zwyczajnie wkleja podany plik w miejsce siebie samej. Nie ma w tym żadnej dodatkowej magii &#8211; kompilator będzie widział dołączony plik dokładnie tak, jakby programista <strong>ręcznie wpisał jego zawartość w miejscu dyrektywy <code class="codecolorer cpp default"><span class="cpp"><span style="color: #339900;">#include</span></span></code></strong>. Z tego faktu wypływa kilka istotnych wniosków:</p>
<ol>
<li>Pliki nagłówkowe nie są niczym specjalnym. Nie muszą mieć rozszerzenia .h/.hpp, mogą mieć rozszerzenie .kolorowe-kredki &#8211; nikomu to nie robi różnicy, ponieważ <strong>pliki nagłówkowe nie są kompilowane</strong>.</li>
<li>Użycie <code class="codecolorer cpp default"><span class="cpp"><span style="color: #339900;">#include</span></span></code> nie ogranicza się do &#8220;dołączania plików nagłówkowych&#8221;. Ponieważ jest to tylko i wyłącznie <em>kopiuj-wklej zawartość podanego pliku</em>, można napisać na przykład coś takiego:
<div class="codecolorer-container cpp default" style="overflow:auto;white-space:nowrap;border:1px solid #9F9F9F;width:435px;"><div class="cpp codecolorer" style="padding:5px;font:normal 12px/1.4em Monaco, Lucida Console, monospace;white-space:nowrap"><span style="color: #0000ff;">float</span> dane<span style="color: #008000;">&#91;</span><span style="color: #008000;">&#93;</span> <span style="color: #000080;">=</span> <span style="color: #008000;">&#123;</span><br />
<span style="color: #339900;">#include &quot;dane.txt&quot;</span><br />
<span style="color: #008000;">&#125;</span><span style="color: #008080;">;</span></div></div>
<p>W praktyce, taka konstrukcja jest nawet dość mądra &#8211; dane, zwłaszcza generowane automatycznie, <a href="http://pl.wikipedia.org/wiki/DRY">lepiej trzymać na zewnątrz niż bezpośrednio w kodzie</a>.
</li>
<li>O plikach nagłówkowych należy myśleć jak o kopiowaniu-wklejaniu kodu. Przyjęcie takiego punktu widzenia pozwala łatwo zrozumieć i wyczuć, dlaczego stosujemy deklaracje <code class="codecolorer cpp default"><span class="cpp"><span style="color: #339900;">#ifndef</span></span></code>/<code class="codecolorer cpp default"><span class="cpp"><span style="color: #339900;">#endif</span></span></code> oraz dlaczego nie umieszczamy w nagłówkach kodu funkcji innych niż <em>inline</em>.</li>
</ol>
<p>Jak widać, w <code class="codecolorer cpp default"><span class="cpp"><span style="color: #339900;">#include</span></span></code> nie ma żadnej magii. Trzeba tylko na tę dyrektywę patrzeć we właściwy sposób. Preprocesor C/C++ jest bardzo prostym narzędziem. A <code class="codecolorer cpp default"><span class="cpp"><span style="color: #339900;">#include</span></span></code> jest bardzo prostym copy-paste&#8217;m.</p>
]]></content:encoded>
			<wfw:commentRss>http://temporal.pr0.pl/devblog/2010/04/06/include-to-jest-copy-paste/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Makra w Lispie &#8211; mały przykład</title>
		<link>http://temporal.pr0.pl/devblog/2010/04/04/makra-w-lispie-maly-przyklad/</link>
		<comments>http://temporal.pr0.pl/devblog/2010/04/04/makra-w-lispie-maly-przyklad/#comments</comments>
		<pubDate>Sat, 03 Apr 2010 23:36:11 +0000</pubDate>
		<dc:creator>Jacek Złydach</dc:creator>
				<category><![CDATA[Informatyka]]></category>
		<category><![CDATA[Ada]]></category>
		<category><![CDATA[analizator leksykalny]]></category>
		<category><![CDATA[Cloze Call]]></category>
		<category><![CDATA[Common Lisp]]></category>
		<category><![CDATA[Lisp]]></category>
		<category><![CDATA[makra]]></category>

		<guid isPermaLink="false">http://temporal.pr0.pl/devblog/?p=954</guid>
		<description><![CDATA[Czasem słyszę pytania o to, co takiego ciekawego i przydatnego jest w Lispie. Niech ten post będzie pierwszym, małym przykładem mocy tego języka.
Wyobraźmy sobie, że pracujemy ze skanerem do kodu źródłowego. To takie małe ustrojstwo, które czyta wyrażenie typu: x = a+3; i rozpoznaje składowe: identyfikator, operator=, identyfikator, operator+, liczba. W szczególności chcemy podać do [...]]]></description>
			<content:encoded><![CDATA[<p>Czasem słyszę pytania o to, co takiego ciekawego i przydatnego jest w Lispie. Niech ten post będzie pierwszym, małym przykładem mocy tego języka.</p>
<p>Wyobraźmy sobie, że pracujemy ze <a href="http://en.wikipedia.org/wiki/Lexical_analysis">skanerem</a> do kodu źródłowego. To takie małe ustrojstwo, które czyta wyrażenie typu: <code class="codecolorer cpp default"><span class="cpp">x <span style="color: #000080;">=</span> a<span style="color: #000040;">+</span><span style="color: #0000dd;">3</span><span style="color: #008080;">;</span></span></code> i rozpoznaje składowe: <code class="codecolorer text default"><span class="text">identyfikator, operator=, identyfikator, operator+, liczba</span></code>. W szczególności chcemy podać do tego skanera własne słowa kluczowe. Autorzy skanera przygotowali do tego specjalną funkcję:</p>
<div class="codecolorer-container lisp default" style="overflow:auto;white-space:nowrap;border:1px solid #9F9F9F;width:435px;"><div class="lisp codecolorer" style="padding:5px;font:normal 12px/1.4em Monaco, Lucida Console, monospace;white-space:nowrap"><span style="color: #66cc66;">&#40;</span>add-special-identifier <span style="color: #66cc66;">&#40;</span><span style="color: #66cc66;">&amp;</span>key identifier string<span style="color: #66cc66;">&#41;</span><span style="color: #66cc66;">&#41;</span></div></div>
<p>Funkcja przyjmuje dwa argumenty &#8211; <em>identyfikator</em>, jakim chcemy nazywać nasze słowo kluczowe w kodzie oraz <em>string</em> ze słowem kluczowym. Przykładowo, gdybyśmy chcieli skanować kod języka Ada, moglibyśmy dodać następujące słowo kluczowe:</p>
<div class="codecolorer-container lisp default" style="overflow:auto;white-space:nowrap;border:1px solid #9F9F9F;width:435px;"><div class="lisp codecolorer" style="padding:5px;font:normal 12px/1.4em Monaco, Lucida Console, monospace;white-space:nowrap"><span style="color: #66cc66;">&#40;</span>add-special-identifier <span style="color: #66cc66;">:</span><span style="color: #555;">identifier</span> <span style="color: #66cc66;">:</span><span style="color: #555;">begin</span> <span style="color: #66cc66;">:</span><span style="color: #555;">string</span> <span style="color: #ff0000;">&quot;begin&quot;</span><span style="color: #66cc66;">&#41;</span></div></div>
<p>Od teraz kiedy skaner rozpozna słowo kluczowe <code class="codecolorer ada default"><span class="ada"><span style="color: #00007f;">begin</span></span></code> w analizowanym pliku, my dostaniemy <a href="http://en.wikipedia.org/wiki/Lexical_analysis#Token">token</a> o identyfikatorze <code class="codecolorer lisp default"><span class="lisp"><span style="color: #66cc66;">:</span><span style="color: #555;">begin</span></span></code>.<br />
Wszystko wygląda super; zaczynamy dodawać kolejne słowa kluczowe:</p>
<div class="codecolorer-container lisp default" style="overflow:auto;white-space:nowrap;border:1px solid #9F9F9F;width:435px;"><div class="lisp codecolorer" style="padding:5px;font:normal 12px/1.4em Monaco, Lucida Console, monospace;white-space:nowrap"><span style="color: #66cc66;">&#40;</span>add-special-identifier <span style="color: #66cc66;">:</span><span style="color: #555;">identifier</span> <span style="color: #66cc66;">:</span><span style="color: #555;">end</span> <span style="color: #66cc66;">:</span><span style="color: #555;">string</span> <span style="color: #ff0000;">&quot;end&quot;</span><span style="color: #66cc66;">&#41;</span><br />
<span style="color: #66cc66;">&#40;</span>add-special-identifier <span style="color: #66cc66;">:</span><span style="color: #555;">identifier</span> <span style="color: #66cc66;">:</span><span style="color: #b1b100;">if</span> <span style="color: #66cc66;">:</span><span style="color: #555;">string</span> <span style="color: #ff0000;">&quot;if&quot;</span><span style="color: #66cc66;">&#41;</span><br />
<span style="color: #66cc66;">&#40;</span>add-special-identifier <span style="color: #66cc66;">:</span><span style="color: #555;">identifier</span> <span style="color: #66cc66;">:</span><span style="color: #555;">loop</span> <span style="color: #66cc66;">:</span><span style="color: #555;">string</span> <span style="color: #ff0000;">&quot;loop&quot;</span><span style="color: #66cc66;">&#41;</span><br />
<span style="color: #808080; font-style: italic;">; ...</span></div></div>
<p>Programistę uczulonego na <a href="http://pl.wikipedia.org/wiki/DRY">powtarzanie się</a> może zacząć powoli denerwować, że przekazujemy dwa nazwane argumenty do funkcji, chociaż de-facto wyglądają one tak samo &#8211; identyfikator nosi taką samą nazwę jak słowo kluczowe. Pytanie, czy nie dałoby podać tego identyfikatora tylko raz?</p>
<p>Oczywiście da się. Możemy napisać funkcję, która nas wyręczy w pisaniu. Ale w Lispie możemy też poprosić kompilator, żeby wygenerował odpowiedni kod za nas. Napiszmy <strong>makro</strong>:</p>
<div class="codecolorer-container lisp default" style="overflow:auto;white-space:nowrap;border:1px solid #9F9F9F;width:435px;"><div class="lisp codecolorer" style="padding:5px;font:normal 12px/1.4em Monaco, Lucida Console, monospace;white-space:nowrap"><span style="color: #66cc66;">&#40;</span><span style="color: #b1b100;">defmacro</span> add-keyword <span style="color: #66cc66;">&#40;</span>what<span style="color: #66cc66;">&#41;</span><br />
&nbsp; `<span style="color: #66cc66;">&#40;</span>add-special-identifier <span style="color: #66cc66;">:</span><span style="color: #555;">identifier</span> <span style="color: #66cc66;">,</span>what <span style="color: #66cc66;">:</span><span style="color: #555;">string</span> <span style="color: #66cc66;">,</span><span style="color: #66cc66;">&#40;</span>string what<span style="color: #66cc66;">&#41;</span><span style="color: #66cc66;">&#41;</span><span style="color: #66cc66;">&#41;</span></div></div>
<p>Teraz słowa kluczowe możemy dodawać tak:</p>
<div class="codecolorer-container lisp default" style="overflow:auto;white-space:nowrap;border:1px solid #9F9F9F;width:435px;"><div class="lisp codecolorer" style="padding:5px;font:normal 12px/1.4em Monaco, Lucida Console, monospace;white-space:nowrap"><span style="color: #66cc66;">&#40;</span>add-keyword <span style="color: #66cc66;">:</span><span style="color: #555;">begin</span><span style="color: #66cc66;">&#41;</span><br />
<span style="color: #66cc66;">&#40;</span>add-keyword <span style="color: #66cc66;">:</span><span style="color: #555;">end</span><span style="color: #66cc66;">&#41;</span><br />
<span style="color: #808080; font-style: italic;">; ...</span></div></div>
<p>Prawda, że mniej pisania? <img src='http://temporal.pr0.pl/devblog/wp-includes/images/smilies/icon_smile.gif' alt=':)' class='wp-smiley' /> .</p>
<p>Nie wchodząc w szczegóły, w powyższej definicji makra rzeczy poprzedzone znaczkiem <code class="codecolorer lisp default"><span class="lisp">`</span></code> zostaną wstawione bezpośrednio do kodu źródłowego, a wewnątrz nich rzeczy poprzedzone znaczkiem <code class="codecolorer lisp default"><span class="lisp"><span style="color: #66cc66;">,</span></span></code> zostaną obliczone w czasie kompilacji (dokładniej w tzw. fazie ekspansji makr), a w kodzie znajdzie się wartość tych obliczeń. Przykładowo, wyraźenie <code class="codecolorer lisp default"><span class="lisp"><span style="color: #66cc66;">,</span><span style="color: #66cc66;">&#40;</span>string what<span style="color: #66cc66;">&#41;</span></span></code> <strong>w czasie kompilacji</strong> zamieni identyfikator na odpowiadający mu string. Powyższe linijki rozwiną się więc do:</p>
<div class="codecolorer-container lisp default" style="overflow:auto;white-space:nowrap;border:1px solid #9F9F9F;width:435px;"><div class="lisp codecolorer" style="padding:5px;font:normal 12px/1.4em Monaco, Lucida Console, monospace;white-space:nowrap"><span style="color: #66cc66;">&#40;</span>add-special-identifier <span style="color: #66cc66;">:</span><span style="color: #555;">identifier</span> <span style="color: #66cc66;">:</span><span style="color: #555;">begin</span><span style="color: #66cc66;">:</span><span style="color: #555;">string</span> <span style="color: #ff0000;">&quot;BEGIN&quot;</span><span style="color: #66cc66;">&#41;</span><br />
<span style="color: #66cc66;">&#40;</span>add-special-identifier <span style="color: #66cc66;">:</span><span style="color: #555;">identifier</span> <span style="color: #66cc66;">:</span><span style="color: #555;">end</span> <span style="color: #66cc66;">:</span><span style="color: #555;">string</span> <span style="color: #ff0000;">&quot;END&quot;</span><span style="color: #66cc66;">&#41;</span><br />
<span style="color: #808080; font-style: italic;">; ...</span></div></div>
<p><em>Ładny mi bajer&#8230;</em>, ktoś powie &#8211; <em>Przecież preprocesor w C też coś takiego umie!</em>.<br />
Tak, to prawda &#8211; nasze makro jedynie &#8220;rozmnożyło&#8221; ten sam argument przekazywany do funkcji w dość prosty sposób. Ale &#8211; wracając do problemu &#8211; wciąż piszemy ręcznie wywołania funkcji dodających pojedyncze słowo kluczowe. Takie wypisywanie wywołań funkcji nie jest do końca tym samym, co zadeklarowanie: <em>chcę dodać następujące słowa kluczowe: &#8230;</em>. Dużo lepiej byłoby móc po prostu napisać:</p>
<div class="codecolorer-container lisp default" style="overflow:auto;white-space:nowrap;border:1px solid #9F9F9F;width:435px;"><div class="lisp codecolorer" style="padding:5px;font:normal 12px/1.4em Monaco, Lucida Console, monospace;white-space:nowrap"><span style="color: #66cc66;">&#40;</span>add-keywords <span style="color: #66cc66;">:</span><span style="color: #555;">abort</span> <span style="color: #66cc66;">:</span><span style="color: #b1b100;">abs</span> <span style="color: #66cc66;">:</span><span style="color: #555;">abstract</span> <span style="color: #66cc66;">:</span><span style="color: #555;">accept</span> <span style="color: #66cc66;">:</span><span style="color: #555;">access</span> <span style="color: #66cc66;">:</span><span style="color: #555;">aliased</span> <span style="color: #66cc66;">:</span><span style="color: #555;">all</span> <span style="color: #66cc66;">:</span><span style="color: #b1b100;">array</span> <span style="color: #66cc66;">:</span><span style="color: #555;">at</span> <span style="color: #66cc66;">:</span><span style="color: #555;">begin</span> <span style="color: #66cc66;">:</span><span style="color: #555;">body</span> <span style="color: #66cc66;">:</span><span style="color: #b1b100;">case</span> <span style="color: #66cc66;">:</span><span style="color: #555;">constant</span> <span style="color: #66cc66;">:</span><span style="color: #555;">declare</span> <span style="color: #66cc66;">:</span><span style="color: #555;">delay</span> <span style="color: #66cc66;">:</span><span style="color: #555;">delta</span> <span style="color: #66cc66;">:</span><span style="color: #555;">digits</span> <span style="color: #66cc66;">:</span><span style="color: #b1b100;">do</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #66cc66;">:</span><span style="color: #555;">else</span> <span style="color: #66cc66;">:</span><span style="color: #555;">elsif</span> <span style="color: #66cc66;">:</span><span style="color: #555;">end</span> <span style="color: #66cc66;">:</span><span style="color: #555;">entry</span> <span style="color: #66cc66;">:</span><span style="color: #555;">exception</span> <span style="color: #66cc66;">:</span><span style="color: #555;">exit</span> <span style="color: #66cc66;">:</span><span style="color: #555;">for</span> <span style="color: #66cc66;">:</span><span style="color: #b1b100;">function</span> <span style="color: #66cc66;">:</span><span style="color: #555;">generic</span> <span style="color: #66cc66;">:</span><span style="color: #555;">goto</span> <span style="color: #66cc66;">:</span><span style="color: #b1b100;">if</span> <span style="color: #66cc66;">:</span><span style="color: #555;">in</span> <span style="color: #66cc66;">:</span><span style="color: #555;">interface</span> <span style="color: #66cc66;">:</span><span style="color: #555;">is</span> <span style="color: #66cc66;">:</span><span style="color: #555;">limited</span> <span style="color: #66cc66;">:</span><span style="color: #555;">loop</span> <span style="color: #66cc66;">:</span><span style="color: #555;">mod</span> <span style="color: #66cc66;">:</span><span style="color: #555;">new</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #66cc66;">:</span><span style="color: #b1b100;">not</span> <span style="color: #66cc66;">:</span><span style="color: #b1b100;">null</span> <span style="color: #66cc66;">:</span><span style="color: #555;">of</span> <span style="color: #66cc66;">:</span><span style="color: #b1b100;">or</span> <span style="color: #66cc66;">:</span><span style="color: #555;">others</span> <span style="color: #66cc66;">:</span><span style="color: #555;">out</span> <span style="color: #66cc66;">:</span><span style="color: #555;">overriding</span> <span style="color: #66cc66;">:</span><span style="color: #555;">package</span> <span style="color: #66cc66;">:</span><span style="color: #555;">pragma</span> <span style="color: #66cc66;">:</span><span style="color: #555;">private</span> <span style="color: #66cc66;">:</span><span style="color: #555;">procedure</span> <span style="color: #66cc66;">:</span><span style="color: #555;">protected</span> <span style="color: #66cc66;">:</span><span style="color: #555;">raise</span> <span style="color: #66cc66;">:</span><span style="color: #555;">range</span> <span style="color: #66cc66;">:</span><span style="color: #555;">record</span> <span style="color: #66cc66;">:</span><span style="color: #b1b100;">rem</span> <span style="color: #66cc66;">:</span><span style="color: #555;">renames</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #66cc66;">:</span><span style="color: #555;">requeue</span> <span style="color: #66cc66;">:</span><span style="color: #b1b100;">return</span> <span style="color: #66cc66;">:</span><span style="color: #b1b100;">reverse</span> <span style="color: #66cc66;">:</span><span style="color: #555;">select</span> <span style="color: #66cc66;">:</span><span style="color: #555;">separate</span> <span style="color: #66cc66;">:</span><span style="color: #555;">subtype</span> <span style="color: #66cc66;">:</span><span style="color: #555;">synchronized</span> <span style="color: #66cc66;">:</span><span style="color: #555;">tagged</span> <span style="color: #66cc66;">:</span><span style="color: #555;">task</span> <span style="color: #66cc66;">:</span><span style="color: #555;">terminate</span> <span style="color: #66cc66;">:</span><span style="color: #555;">then</span> <span style="color: #66cc66;">:</span><span style="color: #555;">type</span> <span style="color: #66cc66;">:</span><span style="color: #555;">until</span> <span style="color: #66cc66;">:</span><span style="color: #555;">use</span> <span style="color: #66cc66;">:</span><span style="color: #b1b100;">when</span> <span style="color: #66cc66;">:</span><span style="color: #555;">while</span> <span style="color: #66cc66;">:</span><span style="color: #555;">with</span> <span style="color: #66cc66;">:</span><span style="color: #555;">xor</span><span style="color: #66cc66;">&#41;</span></div></div>
<p>i za jednym zamachem zdefiniować <a href="http://en.wikibooks.org/wiki/Ada_Programming/Keywords#List_of_keywords">wszystkie słowa kluczowe Ady</a> <img src='http://temporal.pr0.pl/devblog/wp-includes/images/smilies/icon_wink.gif' alt=';)' class='wp-smiley' /> . Znów, możemy napisać funkcję, która w pętli wywoła dodawanie słowa kluczowego, ale pisanie takiej pętli za każdym razem, gdy chcemy dodać nowe rzeczy nie jest tym samym, co powiedzenie: <em>chcę dodać następujące słowa: &#8230;</em>. Poza tym, dlaczego to kompilator nie mógłby tego wszystkiego zrobić za nas?&#8230;</p>
<p>&#8230; Otóż może. Oto definicja makra <code class="codecolorer lisp default"><span class="lisp">add-keywords</span></code>:</p>
<div class="codecolorer-container lisp default" style="overflow:auto;white-space:nowrap;border:1px solid #9F9F9F;width:435px;"><div class="lisp codecolorer" style="padding:5px;font:normal 12px/1.4em Monaco, Lucida Console, monospace;white-space:nowrap"><span style="color: #66cc66;">&#40;</span><span style="color: #b1b100;">defmacro</span> add-keywords <span style="color: #66cc66;">&#40;</span><span style="color: #66cc66;">&amp;</span>rest keyword-<span style="color: #b1b100;">list</span><span style="color: #66cc66;">&#41;</span><br />
&nbsp; `<span style="color: #66cc66;">&#40;</span><span style="color: #b1b100;">progn</span><br />
&nbsp; &nbsp; &nbsp;<span style="color: #66cc66;">,</span>@<span style="color: #66cc66;">&#40;</span>loop for word in keyword-<span style="color: #b1b100;">list</span> collect `<span style="color: #66cc66;">&#40;</span>add-keyword <span style="color: #66cc66;">,</span>word<span style="color: #66cc66;">&#41;</span><span style="color: #66cc66;">&#41;</span><span style="color: #66cc66;">&#41;</span><span style="color: #66cc66;">&#41;</span></div></div>
<p>Bez wchodzenia w szczegóły &#8211; bo nie to jest celem tego wpisu. Powyższe makro wykona <strong>w czasie kompilacji</strong> pętlę po wszystkich swoich argumentach, która zwróci w formie listy wyrażenia <code class="codecolorer lisp default"><span class="lisp"><span style="color: #66cc66;">&#40;</span>add-keyword <span style="color: #66cc66;">,</span>word<span style="color: #66cc66;">&#41;</span></span></code>, a które &#8211; jak pamiętamy &#8211; same są makrami, i chwilę później zostaną rozwinięte w wywołania naszej skomplikowanej funkcji dodającej słowa kluczowe do skanera. Mając takie dwa makra, pojedyncze wywołanie dodające wszystkie słowa kluczowe zostanie w czasie kompilacji rozbite na odpowiednie wywołania funkcji zaprezentowanej na początku. <strong>Zamieniliśmy dużo wpisanych ręcznie pojedynczych wywołań funkcji na dwa makra i jedno wywołanie!</strong> Tego już tak łatwo w C nie zrobimy <img src='http://temporal.pr0.pl/devblog/wp-includes/images/smilies/icon_smile.gif' alt=':)' class='wp-smiley' /> .</p>
<p>Ten mały i stosunkowo prosty przykład makr Lispu miał pokazać ważną cechę tego języka &#8211; ponieważ można w nim wykonać dowolny kod w czasie kompilacji i przerabiać w ten sposób sam kompilowany kod, to <strong>można łatwo rozszerzać język i dopasowywać go do rozwiązywanego problemu</strong>. Dwoma prostymi makrami stworzyliśmy narzędzie dodające hurtem słowa kluczowe. A to już doskonale odpowiada wyrażeniu: <em>Chcę dodać te słowa: &#8230;</em>.</p>
<p>Dwa słowa na koniec. Windowsowej binarki do <a href="http://temporal.pr0.pl/devblog/2010/04/01/2010-lisp-game-design-challenge-koncowka/">ClozeCall</a> na razie nie będzie &#8211; mam na razie z tym małe problemy <img src='http://temporal.pr0.pl/devblog/wp-includes/images/smilies/icon_smile.gif' alt=':)' class='wp-smiley' /> . Ale każdy, kto ma u siebie zainstalowaną implementację Common Lisp, może sobie pograć <img src='http://temporal.pr0.pl/devblog/wp-includes/images/smilies/icon_smile.gif' alt=':)' class='wp-smiley' /> .</p>
]]></content:encoded>
			<wfw:commentRss>http://temporal.pr0.pl/devblog/2010/04/04/makra-w-lispie-maly-przyklad/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>2010 Lisp Game Design Challenge &#8211; końcówka</title>
		<link>http://temporal.pr0.pl/devblog/2010/04/01/2010-lisp-game-design-challenge-koncowka/</link>
		<comments>http://temporal.pr0.pl/devblog/2010/04/01/2010-lisp-game-design-challenge-koncowka/#comments</comments>
		<pubDate>Wed, 31 Mar 2010 23:04:37 +0000</pubDate>
		<dc:creator>Jacek Złydach</dc:creator>
				<category><![CDATA[Kategoria nie przypisana]]></category>
		<category><![CDATA[Cloze Call]]></category>
		<category><![CDATA[Common Lisp]]></category>
		<category><![CDATA[Compo]]></category>
		<category><![CDATA[Lisp]]></category>
		<category><![CDATA[Tworzenie gier]]></category>

		<guid isPermaLink="false">http://temporal.pr0.pl/devblog/?p=950</guid>
		<description><![CDATA[Konkurs 2010 Lisp Game Design Challenge, o którym niedawno pisałem, powoli dobiega końca. Ostatni zawodnicy kończą swoje prace; część z nich jest już dostępna do pogrania. Nie miałem jak dotąd czasu zagrać w żadną z nich, gdyż&#8230; przed chwilą skończyłem swoją własną. Mój projekt, zatytułowany Cloze Call (od Clozure Common Lisp, na którym pracowałem), jest [...]]]></description>
			<content:encoded><![CDATA[<p>Konkurs <a href="http://www.cliki.net/LispGameDesignChallenge">2010 Lisp Game Design Challenge</a>, o którym <a href="http://temporal.pr0.pl/devblog/2010/03/20/2010-lisp-game-design-challenge/">niedawno pisałem</a>, powoli dobiega końca. Ostatni zawodnicy kończą swoje prace; część z nich jest już dostępna do pogrania. Nie miałem jak dotąd czasu zagrać w żadną z nich, gdyż&#8230; przed chwilą skończyłem swoją własną. Mój projekt, zatytułowany <strong>Cloze Call</strong> (od Clozure Common Lisp, na którym pracowałem), jest już dostępny do pobrania w formie źródeł i zasobów (dla osób umiejących obsłużyć implementację Lispa) na stronie <a href="http://code.google.com/p/cloze-call/">Google Project Hosting</a>. Postaram się niedługo przygotować paczkę i binarki dla użytkowników Windowsa. Na razie pozwolę sobie zaprezentować screen z gry:<br />
<center><a href="http://temporal.pr0.pl/devblog/download/projects/ClozeCall/screenshot.png"><img src="http://temporal.pr0.pl/devblog/download/projects/ClozeCall/screenshot-450.png" alt="Cloze Call - screen z rozgrywki" /></a></center></p>
<p>Wahałem się, czy wziąć udział w konkursie &#8211; przecież i tak jest sporo innych rzeczy na głowie. Teraz stwierdzam, że było warto. W czasie prac nad grą nauczyłem się bardzo wielu rzeczy o Lispie. I zaprzyjaźniłem się z <a href="http://pl.wikipedia.org/wiki/Emacs">Emacsem</a> <img src='http://temporal.pr0.pl/devblog/wp-includes/images/smilies/icon_smile.gif' alt=':)' class='wp-smiley' /> .</p>
]]></content:encoded>
			<wfw:commentRss>http://temporal.pr0.pl/devblog/2010/04/01/2010-lisp-game-design-challenge-koncowka/feed/</wfw:commentRss>
		<slash:comments>1</slash:comments>
		</item>
		<item>
		<title>2010 Lisp Game Design Challenge</title>
		<link>http://temporal.pr0.pl/devblog/2010/03/20/2010-lisp-game-design-challenge/</link>
		<comments>http://temporal.pr0.pl/devblog/2010/03/20/2010-lisp-game-design-challenge/#comments</comments>
		<pubDate>Sat, 20 Mar 2010 17:29:20 +0000</pubDate>
		<dc:creator>Jacek Złydach</dc:creator>
				<category><![CDATA[Informatyka]]></category>
		<category><![CDATA[Tworzenie gier]]></category>
		<category><![CDATA[Compo]]></category>
		<category><![CDATA[Lisp]]></category>

		<guid isPermaLink="false">http://temporal.pr0.pl/devblog/?p=941</guid>
		<description><![CDATA[
Przedwczoraj wystartował konkurs 2010 Lisp Game Design Challenge. Zasady są bardzo proste &#8211; wystarczy zadeklarować termin startu, wziąć swojego ulubionego Lispa i zacząć klepać  . Zapisy i dodatkowe informacje znajdują się na stronie głównej oraz stronie rejestracji.
Osobiście poważnie zastanawiam się jeszcze nad wzięciem udziału. Jedynym sensownym terminem startu byłby 24 lub 25 marca. Pomimo [...]]]></description>
			<content:encoded><![CDATA[<p><center><img src="http://dto.github.com/images/lgdc.png" alt="2010 Lisp Game Design Challenge banner" /></center><br />
Przedwczoraj wystartował konkurs <strong>2010 Lisp Game Design Challenge</strong>. Zasady są bardzo proste &#8211; wystarczy zadeklarować termin startu, wziąć swojego ulubionego Lispa i zacząć klepać <img src='http://temporal.pr0.pl/devblog/wp-includes/images/smilies/icon_smile.gif' alt=':)' class='wp-smiley' /> . Zapisy i dodatkowe informacje znajdują się na <a href="http://dto.github.com/notebook/lgdc.html">stronie głównej</a> oraz <a href="http://www.cliki.net/LispGameDesignChallenge">stronie rejestracji</a>.</p>
<p>Osobiście poważnie zastanawiam się jeszcze nad wzięciem udziału. Jedynym sensownym terminem startu byłby 24 lub 25 marca. Pomimo tego, że uczelnia przyciska to jednak konkurs ten jest bardzo kuszącą propozycją <img src='http://temporal.pr0.pl/devblog/wp-includes/images/smilies/icon_smile.gif' alt=':)' class='wp-smiley' /> .</p>
]]></content:encoded>
			<wfw:commentRss>http://temporal.pr0.pl/devblog/2010/03/20/2010-lisp-game-design-challenge/feed/</wfw:commentRss>
		<slash:comments>1</slash:comments>
		</item>
		<item>
		<title>J2ME PacMan</title>
		<link>http://temporal.pr0.pl/devblog/2010/03/19/j2me-pacman/</link>
		<comments>http://temporal.pr0.pl/devblog/2010/03/19/j2me-pacman/#comments</comments>
		<pubDate>Fri, 19 Mar 2010 14:30:55 +0000</pubDate>
		<dc:creator>Jacek Złydach</dc:creator>
				<category><![CDATA[Informatyka]]></category>
		<category><![CDATA[Projekty studenckie]]></category>
		<category><![CDATA[Gry]]></category>
		<category><![CDATA[J2ME]]></category>
		<category><![CDATA[Java]]></category>
		<category><![CDATA[Tworzenie gier]]></category>

		<guid isPermaLink="false">http://temporal.pr0.pl/devblog/?p=935</guid>
		<description><![CDATA[Opublikowałem kolejny projekt robiony w czasie poprzedniego semestru, tym razem jest to PacMan na komórkę pisana w Javie. Starałem się stylizować go na oryginał z lat 80-tych. Rezultat wygląda tak:

Szczegóły projektu. Miłej zabawy  .
]]></description>
			<content:encoded><![CDATA[<p>Opublikowałem kolejny projekt robiony w czasie poprzedniego semestru, tym razem jest to <a href="http://pl.wikipedia.org/wiki/Pac-Man">PacMan</a> na komórkę pisana w Javie. Starałem się stylizować go <a href="http://en.wikipedia.org/wiki/File:Pac-man.png">na oryginał z lat 80-tych</a>. Rezultat wygląda tak:</p>
<p><center><a href="http://temporal.pr0.pl/devblog/download/projects/TRCPacMan/scr-gameplay.png"><img src="http://temporal.pr0.pl/devblog/download/projects/TRCPacMan/scr-gameplay.png" alt="PacMan - rozgrywka" style="width: 200px; padding-right: 20px;" /></a><a href="http://temporal.pr0.pl/devblog/download/projects/TRCPacMan/scr-ghosteater.png"><img src="http://temporal.pr0.pl/devblog/download/projects/TRCPacMan/scr-ghosteater.png" alt="PacMan - polowanie na potwory" style="width: 200px; padding-left: 20px" /></a></center></p>
<p><a href="http://temporal.pr0.pl/devblog/projekty/j2me-pacman/">Szczegóły projektu</a>. Miłej zabawy <img src='http://temporal.pr0.pl/devblog/wp-includes/images/smilies/icon_smile.gif' alt=':)' class='wp-smiley' /> .</p>
]]></content:encoded>
			<wfw:commentRss>http://temporal.pr0.pl/devblog/2010/03/19/j2me-pacman/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Test Management w VS 2010 / Design i nowe technologie</title>
		<link>http://temporal.pr0.pl/devblog/2010/03/15/test-management-w-vs-2010-design-i-nowe-technologie/</link>
		<comments>http://temporal.pr0.pl/devblog/2010/03/15/test-management-w-vs-2010-design-i-nowe-technologie/#comments</comments>
		<pubDate>Mon, 15 Mar 2010 18:38:17 +0000</pubDate>
		<dc:creator>Jacek Złydach</dc:creator>
				<category><![CDATA[Z życia]]></category>

		<guid isPermaLink="false">http://temporal.pr0.pl/devblog/2010/03/15/test-management-w-vs-2010-design-i-nowe-technologie/</guid>
		<description><![CDATA[Serdecznie pozdrawiam wszystkich Uczestników wspomnianych w tytule konferencji, którzy kliknęli na link w podpisie maila. Tak, pocztę też trzeba umieć wysyłać &#8211; Organizatorze, jest takie pole jak UDW (ang. BCC). Do zobaczenia  .
]]></description>
			<content:encoded><![CDATA[<p>Serdecznie pozdrawiam wszystkich Uczestników wspomnianych w tytule konferencji, którzy kliknęli na link w podpisie maila. Tak, pocztę też trzeba umieć wysyłać &#8211; Organizatorze, jest takie pole jak <acronym title="Ukryte Do Wiadomości">UDW</acronym> (ang. <a href="http://pl.wikipedia.org/wiki/Ukryte_do_wiadomo%C5%9Bci"><acronym title="Blind Carbon Copy">BCC</acronym></a>). Do zobaczenia <img src='http://temporal.pr0.pl/devblog/wp-includes/images/smilies/icon_wink.gif' alt=';)' class='wp-smiley' /> .</p>
]]></content:encoded>
			<wfw:commentRss>http://temporal.pr0.pl/devblog/2010/03/15/test-management-w-vs-2010-design-i-nowe-technologie/feed/</wfw:commentRss>
		<slash:comments>1</slash:comments>
		</item>
		<item>
		<title>QED &#8211; UNIX API w wersji trochę bardziej przyjaznej</title>
		<link>http://temporal.pr0.pl/devblog/2010/02/25/qed-unix-api-w-wersji-troche-bardziej-przyjaznej/</link>
		<comments>http://temporal.pr0.pl/devblog/2010/02/25/qed-unix-api-w-wersji-troche-bardziej-przyjaznej/#comments</comments>
		<pubDate>Thu, 25 Feb 2010 19:25:56 +0000</pubDate>
		<dc:creator>Jacek Złydach</dc:creator>
				<category><![CDATA[Informatyka]]></category>
		<category><![CDATA[Projekty studenckie]]></category>
		<category><![CDATA[C++]]></category>
		<category><![CDATA[Linux]]></category>
		<category><![CDATA[narzędzia]]></category>
		<category><![CDATA[QED]]></category>
		<category><![CDATA[Unix]]></category>

		<guid isPermaLink="false">http://temporal.pr0.pl/devblog/?p=864</guid>
		<description><![CDATA[Chciałbym opublikować kawałek kodu, który napisałem pod wpływem emocji w ramach nauki na końcowe kolokwium z systemów operacyjnych. Zadania, które dostawaliśmy tam były niemożliwe do zrobienia bez dobrej znajomości API UNIXa dotyczącego komunikacji międzyprocesowej i przygotowania sobie jakiegoś kodu wcześniej. Teoretycznie można było korzystać z Internetu i dowolnych własnych zasobów, ale bez wstępnego przygotowania nie [...]]]></description>
			<content:encoded><![CDATA[<p><a href="http://temporal.pr0.pl/devblog/projekty/qed/">Chciałbym opublikować kawałek kodu</a>, który napisałem pod wpływem emocji w ramach nauki na końcowe kolokwium z systemów operacyjnych. Zadania, które dostawaliśmy tam były niemożliwe do zrobienia bez dobrej znajomości API UNIXa dotyczącego <a href="http://pl.wikipedia.org/wiki/Komunikacja_mi%C4%99dzyprocesowa">komunikacji międzyprocesowej</a> i przygotowania sobie jakiegoś kodu wcześniej. Teoretycznie można było korzystać z Internetu i dowolnych własnych zasobów, ale bez wstępnego przygotowania nie było szans <img src='http://temporal.pr0.pl/devblog/wp-includes/images/smilies/icon_wink.gif' alt=';)' class='wp-smiley' /> . Większość znajomych przygotowywała więc sobie rozwiązania dotychczasowych zadań z laboratorium w nadziei, że będą się dały zaadaptować do kolokwium.</p>
<p>QED, bo tak nazywa się biblioteka, powstała jako wynik frustracji po słabym zaliczeniu pierwszego terminu. Opakowuje ona całe to przykre i bolesne w użyciu API <a href="http://pl.wikipedia.org/wiki/Komunikacja_mi%C4%99dzyprocesowa">IPC</a> UNIX&#8217;a do postaci prostych klas i funkcji C++. Większość zadań da się zrobić bez ani jednej linii kodu w czystym UNIXowym API <img src='http://temporal.pr0.pl/devblog/wp-includes/images/smilies/icon_smile.gif' alt=':)' class='wp-smiley' /> .</p>
<p><a href="http://temporal.pr0.pl/devblog/projekty/qed/"><strong>Biblioteka QED oraz przykładowe zadania z laboratoriów / kolokwium.</strong></a></p>
<p>Biblioteczka ta zawiera:</p>
<ul>
<li>Uproszczony <a href="http://www.boost.org/doc/libs/1_42_0/libs/conversion/lexical_cast.htm"><code class="codecolorer cpp default"><span class="cpp">lexical_cast</span></code></a></li>
<li>Obiekty do łatwego synchronizowania operacji na <code class="codecolorer cpp default"><span class="cpp">std<span style="color: #008080;">::</span><span style="color: #007788;">ostream</span></span></code>(tak, na <code class="codecolorer cpp default"><span class="cpp">std<span style="color: #008080;">::</span><span style="color: #0000dd;">cout</span></span></code> też!) w programach wielowątkowych</li>
<li>Funkcję do pobierania czasu z milisekundową rozdzielczością</li>
<li>Pomocnicze makra zastępujące powtarzający się w kółko kod</li>
<li>Pomocnicze funkcje do <strong>wygodnego</strong> <code class="codecolorer cpp default"><span class="cpp">fork<span style="color: #008000;">&#40;</span><span style="color: #008000;">&#41;</span></span></code> (łącznie z przepinaniem STDIN i STDOUT dziecka); <a href="http://en.wikipedia.org/wiki/Fork-exec">fork-exec idiom</a> trzeba sobie zrobić samemu, ale co to za problem wywołać sobie funkcję <code class="codecolorer cpp default"><span class="cpp">exec<span style="color: #008000;">&#40;</span><span style="color: #008000;">&#41;</span></span></code> <img src='http://temporal.pr0.pl/devblog/wp-includes/images/smilies/icon_razz.gif' alt=':P' class='wp-smiley' /> .</li>
<li>Klasy izolujące <a href="http://beej.us/guide/bgipc/output/html/singlepage/bgipc.html#pipes">nienazwane</a> i nazwane <a href="http://beej.us/guide/bgipc/output/html/singlepage/bgipc.html#fifos">pipe&#8217;y (FIFO)</a>, <a href="http://beej.us/guide/bgipc/output/html/singlepage/bgipc.html#semaphores">semafory</a>, <a href="http://beej.us/guide/bgipc/output/html/singlepage/bgipc.html#shm">pamięć współdzieloną</a> i <a href="http://beej.us/guide/bgipc/output/html/singlepage/bgipc.html#mq">kolejki komunikatów</a></li>
<li>Inne pomocnicze funkcje</li>
</ul>
<p>Mam szczerą nadzieję, że kod ten przyda się przynajmniej tym z Czytelników, którzy już za rok (albo i wcześniej) zmierzą się z Systemami Operacyjnymi na IS <img src='http://temporal.pr0.pl/devblog/wp-includes/images/smilies/icon_smile.gif' alt=':)' class='wp-smiley' /> .</p>
<p>Dlaczego taka nazwa? QED oznacza <a href="http://pl.wikipedia.org/wiki/Elektrodynamika_kwantowa">elektrodynamikę kwantową</a> &#8211; bardzo pokręconą dziedzinę fizyki, o której czytałem sobie &#8220;do obiadu&#8221; w okresie prac nad powyższą biblioteką. <a href="http://pl.wikipedia.org/wiki/Q.e.d.">Q.E.D.</a> to też łaciński skrót oznaczający <em>Quod erat demonstrandum</em> (&#8220;Co było do udowodnienia&#8221;) &#8211; co dobrze współgrało z moją frustracją po pierwszym terminie (na zasadzie: &#8220;no, na drugim pokażę!&#8221;).</p>
<p>Dla niewystarczająco przekonanych, przykład kodu:</p>
<div class="codecolorer-container cpp default" style="overflow:auto;white-space:nowrap;border:1px solid #9F9F9F;width:435px;height:300px;"><div class="cpp codecolorer" style="padding:5px;font:normal 12px/1.4em Monaco, Lucida Console, monospace;white-space:nowrap"><span style="color: #666666;">//================================================================</span><br />
<span style="color: #666666;">//Beta section</span><br />
<span style="color: #666666;">//================================================================</span><br />
<span style="color: #0000ff;">int</span> process_beta<span style="color: #008000;">&#40;</span><span style="color: #0000ff;">void</span><span style="color: #000040;">*</span> data<span style="color: #008000;">&#41;</span><br />
<span style="color: #008000;">&#123;</span><br />
&nbsp; &nbsp; betaQueue.<span style="color: #007788;">attach</span><span style="color: #008000;">&#40;</span><span style="color: #008000;">&#41;</span><span style="color: #008080;">;</span><br />
&nbsp; &nbsp; alphaSharedQueue.<span style="color: #007788;">attach</span><span style="color: #008000;">&#40;</span><span style="color: #008000;">&#41;</span><span style="color: #008080;">;</span><br />
<br />
&nbsp; &nbsp; <span style="color: #0000ff;">char</span> buffer<span style="color: #008000;">&#91;</span><span style="color: #0000dd;">1024</span><span style="color: #008000;">&#93;</span><span style="color: #008080;">;</span><br />
<br />
&nbsp; &nbsp; <span style="color: #0000ff;">while</span><span style="color: #008000;">&#40;</span><span style="color: #0000ff;">true</span><span style="color: #008000;">&#41;</span><br />
&nbsp; &nbsp; <span style="color: #008000;">&#123;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; std<span style="color: #008080;">::</span><span style="color: #0000dd;">memset</span><span style="color: #008000;">&#40;</span>buffer, <span style="color: #0000dd;">0</span>, <span style="color: #0000dd;">1024</span><span style="color: #000040;">*</span><span style="color: #0000dd;">sizeof</span><span style="color: #008000;">&#40;</span><span style="color: #0000ff;">char</span><span style="color: #008000;">&#41;</span><span style="color: #008000;">&#41;</span><span style="color: #008080;">;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; <br />
&nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #666666;">//get data from msg queue</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; betaQueue.<span style="color: #007788;">receive_message</span><span style="color: #008000;">&#40;</span>buffer<span style="color: #008000;">&#41;</span><span style="color: #008080;">;</span><br />
<br />
&nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #666666;">//cut out last two letters</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; buffer<span style="color: #008000;">&#91;</span>std<span style="color: #008080;">::</span><span style="color: #007788;">max</span><span style="color: #008000;">&#40;</span><span style="color: #0000ff;">static_cast</span><span style="color: #000080;">&lt;</span><span style="color: #0000ff;">int</span><span style="color: #000080;">&gt;</span><span style="color: #008000;">&#40;</span>std<span style="color: #008080;">::</span><span style="color: #0000dd;">strlen</span><span style="color: #008000;">&#40;</span>buffer<span style="color: #008000;">&#41;</span><span style="color: #008000;">&#41;</span> <span style="color: #000040;">-</span> <span style="color: #0000dd;">2</span>, <span style="color: #0000dd;">0</span><span style="color: #008000;">&#41;</span><span style="color: #008000;">&#93;</span> <span style="color: #000080;">=</span> <span style="color: #FF0000;">'<span style="color: #006699; font-weight: bold;">\0</span>'</span><span style="color: #008080;">;</span><br />
<br />
&nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #666666;">//send data via message queue to P1</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; alphaSharedQueue.<span style="color: #007788;">send_message</span><span style="color: #008000;">&#40;</span>buffer<span style="color: #008000;">&#41;</span><span style="color: #008080;">;</span><br />
&nbsp; &nbsp; <span style="color: #008000;">&#125;</span><br />
<br />
&nbsp; &nbsp; <span style="color: #0000ff;">return</span> <span style="color: #0000dd;">0</span><span style="color: #008080;">;</span><br />
<span style="color: #008000;">&#125;</span></div></div>
<p>Oto kod procesu, który odbiera informacje z kolejki komunikatów, obcina im dwa ostatnie znaki i wysyła je inną kolejką komunikatów.<br />
Teraz, wyobraź sobie, że piszesz w czystym UNIX API <img src='http://temporal.pr0.pl/devblog/wp-includes/images/smilies/icon_razz.gif' alt=':P' class='wp-smiley' /> .</p>
]]></content:encoded>
			<wfw:commentRss>http://temporal.pr0.pl/devblog/2010/02/25/qed-unix-api-w-wersji-troche-bardziej-przyjaznej/feed/</wfw:commentRss>
		<slash:comments>1</slash:comments>
		</item>
		<item>
		<title>Czy &#8220;czujesz&#8221; rekurencję?</title>
		<link>http://temporal.pr0.pl/devblog/2010/02/20/czy-czujesz-rekurencje/</link>
		<comments>http://temporal.pr0.pl/devblog/2010/02/20/czy-czujesz-rekurencje/#comments</comments>
		<pubDate>Sat, 20 Feb 2010 19:22:40 +0000</pubDate>
		<dc:creator>Jacek Złydach</dc:creator>
				<category><![CDATA[Informatyka]]></category>
		<category><![CDATA[Ackermann]]></category>
		<category><![CDATA[C]]></category>
		<category><![CDATA[Lisp]]></category>
		<category><![CDATA[Matematyka]]></category>
		<category><![CDATA[Scheme]]></category>
		<category><![CDATA[SICP]]></category>
		<category><![CDATA[wyzwania]]></category>

		<guid isPermaLink="false">http://temporal.pr0.pl/devblog/?p=855</guid>
		<description><![CDATA[Proponuję małe wyzwanie dla sprawdzenia samego siebie. Zachęcam do podjęcia się go i nie korzystania z Google&#8217;i do odkrycia rozwiązań. Zadanie to ma swoje źródło w książce &#8220;Structure and Implementation of Computer Programs&#8221;, jednak &#8211; żeby nie straszyć publiczności   &#8211; przedstawię je w C++, nie w Scheme.
Poniższy kawałek kodu oblicza funkcję Ackermanna:
int ackermann&#40;int [...]]]></description>
			<content:encoded><![CDATA[<p>Proponuję małe wyzwanie dla sprawdzenia samego siebie. Zachęcam do podjęcia się go i nie korzystania z Google&#8217;i do odkrycia rozwiązań. Zadanie to ma <a href="http://mitpress.mit.edu/sicp/full-text/book/book-Z-H-11.html#%_sec_1.2.1">swoje źródło</a> w książce<a href="http://mitpress.mit.edu/sicp/full-text/book/book.html"> &#8220;Structure and Implementation of Computer Programs&#8221;</a>, jednak &#8211; żeby nie straszyć publiczności <img src='http://temporal.pr0.pl/devblog/wp-includes/images/smilies/icon_wink.gif' alt=';)' class='wp-smiley' />  &#8211; przedstawię je w C++, nie w Scheme.</p>
<p>Poniższy kawałek kodu oblicza <a href="http://en.wikipedia.org/wiki/Ackermann_function">funkcję Ackermanna</a>:</p>
<div class="codecolorer-container cpp default" style="overflow:auto;white-space:nowrap;border:1px solid #9F9F9F;width:435px;"><div class="cpp codecolorer" style="padding:5px;font:normal 12px/1.4em Monaco, Lucida Console, monospace;white-space:nowrap"><span style="color: #0000ff;">int</span> ackermann<span style="color: #008000;">&#40;</span><span style="color: #0000ff;">int</span> x, <span style="color: #0000ff;">int</span> y<span style="color: #008000;">&#41;</span><br />
<span style="color: #008000;">&#123;</span><br />
&nbsp; &nbsp; <span style="color: #0000ff;">if</span><span style="color: #008000;">&#40;</span>y <span style="color: #000080;">==</span> <span style="color: #0000dd;">0</span><span style="color: #008000;">&#41;</span><br />
&nbsp; &nbsp; <span style="color: #008000;">&#123;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #0000ff;">return</span> <span style="color: #0000dd;">0</span><span style="color: #008080;">;</span><br />
&nbsp; &nbsp; <span style="color: #008000;">&#125;</span><br />
&nbsp; &nbsp; <span style="color: #0000ff;">if</span><span style="color: #008000;">&#40;</span>x <span style="color: #000080;">==</span> <span style="color: #0000dd;">0</span><span style="color: #008000;">&#41;</span><br />
&nbsp; &nbsp; <span style="color: #008000;">&#123;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #0000ff;">return</span> <span style="color: #0000dd;">2</span><span style="color: #000040;">*</span>y<span style="color: #008080;">;</span><br />
&nbsp; &nbsp; <span style="color: #008000;">&#125;</span><br />
&nbsp; &nbsp; <span style="color: #0000ff;">if</span><span style="color: #008000;">&#40;</span>y <span style="color: #000080;">==</span> <span style="color: #0000dd;">1</span><span style="color: #008000;">&#41;</span><br />
&nbsp; &nbsp; <span style="color: #008000;">&#123;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #0000ff;">return</span> <span style="color: #0000dd;">2</span><span style="color: #008080;">;</span><br />
&nbsp; &nbsp; <span style="color: #008000;">&#125;</span><br />
&nbsp; &nbsp; <span style="color: #0000ff;">return</span> ackermann<span style="color: #008000;">&#40;</span>x<span style="color: #000040;">-</span><span style="color: #0000dd;">1</span>, ackermann<span style="color: #008000;">&#40;</span>x, y<span style="color: #000040;">-</span><span style="color: #0000dd;">1</span><span style="color: #008000;">&#41;</span><span style="color: #008000;">&#41;</span><span style="color: #008080;">;</span><br />
<span style="color: #008000;">&#125;</span></div></div>
<p>Zadanie na rozgrzewkę: jaką wartość przyjmą poniższe wyrażenia?</p>
<div class="codecolorer-container cpp default" style="overflow:auto;white-space:nowrap;border:1px solid #9F9F9F;width:435px;"><div class="cpp codecolorer" style="padding:5px;font:normal 12px/1.4em Monaco, Lucida Console, monospace;white-space:nowrap">ackermann<span style="color: #008000;">&#40;</span><span style="color: #0000dd;">1</span>, <span style="color: #0000dd;">10</span><span style="color: #008000;">&#41;</span><span style="color: #008080;">;</span><br />
ackermann<span style="color: #008000;">&#40;</span><span style="color: #0000dd;">2</span>, <span style="color: #0000dd;">4</span><span style="color: #008000;">&#41;</span><span style="color: #008080;">;</span><br />
ackermann<span style="color: #008000;">&#40;</span><span style="color: #0000dd;">3</span>, <span style="color: #0000dd;">3</span><span style="color: #008000;">&#41;</span><span style="color: #008080;">;</span></div></div>
<p>Prawdziwe wyzwanie: rozważmy poniższe funkcje:</p>
<div class="codecolorer-container cpp default" style="overflow:auto;white-space:nowrap;border:1px solid #9F9F9F;width:435px;"><div class="cpp codecolorer" style="padding:5px;font:normal 12px/1.4em Monaco, Lucida Console, monospace;white-space:nowrap"><span style="color: #0000ff;">int</span> f<span style="color: #008000;">&#40;</span><span style="color: #0000ff;">int</span> n<span style="color: #008000;">&#41;</span><br />
<span style="color: #008000;">&#123;</span><br />
&nbsp; &nbsp; <span style="color: #0000ff;">return</span> ackermann<span style="color: #008000;">&#40;</span><span style="color: #0000dd;">0</span>, n<span style="color: #008000;">&#41;</span><span style="color: #008080;">;</span><br />
<span style="color: #008000;">&#125;</span><br />
<span style="color: #0000ff;">int</span> g<span style="color: #008000;">&#40;</span><span style="color: #0000ff;">int</span> n<span style="color: #008000;">&#41;</span><br />
<span style="color: #008000;">&#123;</span><br />
&nbsp; &nbsp; <span style="color: #0000ff;">return</span> ackermann<span style="color: #008000;">&#40;</span><span style="color: #0000dd;">1</span>, n<span style="color: #008000;">&#41;</span><span style="color: #008080;">;</span><br />
<span style="color: #008000;">&#125;</span><br />
<span style="color: #0000ff;">int</span> h<span style="color: #008000;">&#40;</span><span style="color: #0000ff;">int</span> n<span style="color: #008000;">&#41;</span><br />
<span style="color: #008000;">&#123;</span><br />
&nbsp; &nbsp; <span style="color: #0000ff;">return</span> ackermann<span style="color: #008000;">&#40;</span><span style="color: #0000dd;">2</span>, n<span style="color: #008000;">&#41;</span><span style="color: #008080;">;</span><br />
<span style="color: #008000;">&#125;</span><br />
<span style="color: #0000ff;">int</span> k<span style="color: #008000;">&#40;</span><span style="color: #0000ff;">int</span> n<span style="color: #008000;">&#41;</span><br />
<span style="color: #008000;">&#123;</span><br />
&nbsp; &nbsp; <span style="color: #0000ff;">return</span> <span style="color: #0000dd;">5</span><span style="color: #000040;">*</span>n<span style="color: #000040;">*</span>n<span style="color: #008080;">;</span><br />
<span style="color: #008000;">&#125;</span></div></div>
<p>Jaką matematyczną definicję posiadają powyższe funkcje? Na przykład, funkcję k(n) można zdefiniować jako: k(n) = 5n<sup>2</sup>.</p>
<p>Do rozwiązywania powyższych zadań nie trzeba nic kompilować &#8211; wystarczy kartka papieru i trochę cierpliwości <img src='http://temporal.pr0.pl/devblog/wp-includes/images/smilies/icon_smile.gif' alt=':)' class='wp-smiley' /> . Kompilator może się przydać do sprawdzenia wyników.</p>
<p>Życzę powodzenia!</p>
]]></content:encoded>
			<wfw:commentRss>http://temporal.pr0.pl/devblog/2010/02/20/czy-czujesz-rekurencje/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Piosenki o językach programowania</title>
		<link>http://temporal.pr0.pl/devblog/2010/02/17/piosenki-o-jezykach-programowania/</link>
		<comments>http://temporal.pr0.pl/devblog/2010/02/17/piosenki-o-jezykach-programowania/#comments</comments>
		<pubDate>Wed, 17 Feb 2010 10:25:13 +0000</pubDate>
		<dc:creator>Jacek Złydach</dc:creator>
				<category><![CDATA[Humor]]></category>
		<category><![CDATA[Informatyka]]></category>
		<category><![CDATA[C]]></category>
		<category><![CDATA[Lisp]]></category>

		<guid isPermaLink="false">http://temporal.pr0.pl/devblog/?p=852</guid>
		<description><![CDATA[Dwie ciekawe piosenki; pierwsza bardziej znana, druga trochę mniej:
Write in C

The Eternal Flame AKA God Wrote in Lisp Code

]]></description>
			<content:encoded><![CDATA[<p>Dwie ciekawe piosenki; pierwsza bardziej znana, druga trochę mniej:</p>
<p><strong>Write in C</strong><br />
<object width="425" height="344"><param name="movie" value="http://www.youtube.com/v/XHosLhPEN3k&#038;hl=pl_PL&#038;fs=1&#038;color1=0x3a3a3a&#038;color2=0x999999"></param><param name="allowFullScreen" value="true"></param><param name="allowscriptaccess" value="always"></param><embed src="http://www.youtube.com/v/XHosLhPEN3k&#038;hl=pl_PL&#038;fs=1&#038;color1=0x3a3a3a&#038;color2=0x999999" type="application/x-shockwave-flash" allowscriptaccess="always" allowfullscreen="true" width="425" height="344"></embed></object></p>
<p><strong>The Eternal Flame <a href="http://en.wikipedia.org/wiki/Aka">AKA</a> God Wrote in Lisp Code</strong><br />
<object width="425" height="344"><param name="movie" value="http://www.youtube.com/v/5-OjTPj7K54&#038;hl=pl_PL&#038;fs=1&#038;color1=0x3a3a3a&#038;color2=0x999999"></param><param name="allowFullScreen" value="true"></param><param name="allowscriptaccess" value="always"></param><embed src="http://www.youtube.com/v/5-OjTPj7K54&#038;hl=pl_PL&#038;fs=1&#038;color1=0x3a3a3a&#038;color2=0x999999" type="application/x-shockwave-flash" allowscriptaccess="always" allowfullscreen="true" width="425" height="344"></embed></object></p>
]]></content:encoded>
			<wfw:commentRss>http://temporal.pr0.pl/devblog/2010/02/17/piosenki-o-jezykach-programowania/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Back. Finally.</title>
		<link>http://temporal.pr0.pl/devblog/2010/02/16/back-finally/</link>
		<comments>http://temporal.pr0.pl/devblog/2010/02/16/back-finally/#comments</comments>
		<pubDate>Tue, 16 Feb 2010 17:42:32 +0000</pubDate>
		<dc:creator>Jacek Złydach</dc:creator>
				<category><![CDATA[Informatyka]]></category>
		<category><![CDATA[devBlog - Techniczne]]></category>
		<category><![CDATA[Common Lisp]]></category>
		<category><![CDATA[devBlog]]></category>
		<category><![CDATA[Lisp]]></category>
		<category><![CDATA[pr0.pl]]></category>
		<category><![CDATA[Scheme]]></category>

		<guid isPermaLink="false">http://temporal.pr0.pl/devblog/?p=829</guid>
		<description><![CDATA[Przenosiny zakończone, problemy z kodowaniem usunięte*. Blog, chociaż pod tą samą domeną, stoi już na zupełnie innym serwerze. Mam nadzieję, że będzie trochę spokoju z awariami przez jakiś czas.
Przez ostatnie miesiące sporo się działo. Głównie były to rzeczy związane z bardzo zajmującym semestrem na studiach. Do wielu z tych spraw będę chciał wrócić &#8211; w [...]]]></description>
			<content:encoded><![CDATA[<p><a href="http://temporal.pr0.pl/devblog/2010/01/11/evac/">Przenosiny</a> zakończone, <a href="http://temporal.pr0.pl/devblog/2010/01/02/problem-z-kodowaniem/">problemy z kodowaniem</a> usunięte<a name="POST_BACKFINALLY_MT_1" href="#POST_BACKFINALLY_REF_1">*</a>. Blog, chociaż pod tą samą domeną, stoi już na zupełnie innym serwerze. Mam nadzieję, że będzie trochę spokoju z awariami przez jakiś czas.</p>
<p>Przez ostatnie miesiące sporo się działo. Głównie były to rzeczy związane z bardzo zajmującym semestrem na studiach. Do wielu z tych spraw będę chciał wrócić &#8211; w tym do nowych projektów oraz ciekawych języków i technologii, jak na przykład <a href="http://pl.wikipedia.org/wiki/Erlang_%28j%C4%99zyk_programowania%29">Erlang</a>.</p>
<p>Jak nietrudno się zorientować, zwariowałem. Zakochałem się. Dostałem po głowie<a name="POST_BACKFINALLY_MT_2" href="#POST_BACKFINALLY_REF_2">**</a>. Zacząłem się uczyć języka <strong><a href="http://pl.wikipedia.org/wiki/Lisp">Lisp</a></strong> <img src='http://temporal.pr0.pl/devblog/wp-includes/images/smilies/icon_wink.gif' alt=';)' class='wp-smiley' /> . Dokładniej poznaję dialekt <a href="http://pl.wikipedia.org/wiki/Common_Lisp">Common Lisp</a>, aczkolwiek ze <a href="http://pl.wikipedia.org/wiki/Scheme">Scheme</a> też mam czasem do czynienia. Lisp jest w tej chwili moim głównym kierunkiem rozwoju, więc będzie stale odwiedzał ten blog (a już teraz na dobre zamieszkał w jego designie <img src='http://temporal.pr0.pl/devblog/wp-includes/images/smilies/icon_wink.gif' alt=';)' class='wp-smiley' /> ).</p>
<p><strong>Zmiany techniczne</strong><br />
Główna zmiana (z tych wyraźnie widocznych) dotyczy sposobu wyświetlania kodu. W końcu wyrzuciłem <a href="http://blog.igeek.info/still-fresh/category/wp-plugins/igsyntax-hiliter/">iG:Syntax Hiliter</a>; w tej chwili wpięty jest plugin <a href="http://wordpress.org/extend/plugins/codecolorer/">CodeColorer</a>. Oprócz tego, że jest nowszy i ładniejszy, to wspiera też więcej języków niż jego poprzednik (przede wszystkim Common Lisp i Scheme <img src='http://temporal.pr0.pl/devblog/wp-includes/images/smilies/icon_smile.gif' alt=':)' class='wp-smiley' />  ).</p>
<p><strong>Umarło pr0.pl, niech żyje pr0.pl</strong><br />
Na koniec chciałbym bardzo podziękować Paszczakowi za około pięć lat prawie bezawaryjnego hostingu na własnym, domowym &#8220;szafoserwerze&#8221;. Była to bardzo cenna przysługa, zwłaszcza, że parę lat temu o darmowy hosting wysokiej jakości było trudno. Mam jednak nadzieję, że ta zmiana wyjdzie wszystkim (w tym temu blogowi) na dobre.</p>
<p><a name="POST_BACKFINALLY_REF_1" href="#POST_BACKFINALLY_MT_1">*</a> &#8211; to jest temat na osobną historię.<br />
<a name="POST_BACKFINALLY_REF_2" href="#POST_BACKFINALLY_MT_2">**</a> &#8211; niektórzy powiedzą, że przysłowiowym jabłkiem Newtona. Inni, że cegłą.</p>
]]></content:encoded>
			<wfw:commentRss>http://temporal.pr0.pl/devblog/2010/02/16/back-finally/feed/</wfw:commentRss>
		<slash:comments>1</slash:comments>
		</item>
		<item>
		<title>EVAC</title>
		<link>http://temporal.pr0.pl/devblog/2010/01/11/evac/</link>
		<comments>http://temporal.pr0.pl/devblog/2010/01/11/evac/#comments</comments>
		<pubDate>Mon, 11 Jan 2010 12:33:22 +0000</pubDate>
		<dc:creator>Jacek Złydach</dc:creator>
				<category><![CDATA[devBlog - Techniczne]]></category>

		<guid isPermaLink="false">http://temporal.pr0.pl/devblog/?p=794</guid>
		<description><![CDATA[To już jest pewne &#8211; niedługo zmiana serwera. Obecne problemy z kodowaniem spowodowane są awarią w bazie danych. Więcej szczegółów niedługo.
]]></description>
			<content:encoded><![CDATA[<p>To już jest pewne &#8211; niedługo zmiana serwera. Obecne problemy z kodowaniem spowodowane są awarią w bazie danych. Więcej szczegółów niedługo.</p>
]]></content:encoded>
			<wfw:commentRss>http://temporal.pr0.pl/devblog/2010/01/11/evac/feed/</wfw:commentRss>
		<slash:comments>1</slash:comments>
		</item>
		<item>
		<title>Problem z kodowaniem</title>
		<link>http://temporal.pr0.pl/devblog/2010/01/02/problem-z-kodowaniem/</link>
		<comments>http://temporal.pr0.pl/devblog/2010/01/02/problem-z-kodowaniem/#comments</comments>
		<pubDate>Sat, 02 Jan 2010 15:25:01 +0000</pubDate>
		<dc:creator>Jacek Złydach</dc:creator>
				<category><![CDATA[devBlog - Techniczne]]></category>

		<guid isPermaLink="false">http://temporal.pr0.pl/devblog/?p=790</guid>
		<description><![CDATA[Tak, widzę, że jest. Nie, jeszcze nie jestem pewien, gdzie leży przyczyna. Możliwe, że coś z bazą danych &#8211; awaria jest &#8220;Wordpress-wide&#8221;. Postaram się naprawić naprawię wszystko ASAP.
]]></description>
			<content:encoded><![CDATA[<p>Tak, widzę, że jest. Nie, jeszcze nie jestem pewien, gdzie leży przyczyna. Możliwe, że coś z bazą danych &#8211; awaria jest &#8220;Wordpress-wide&#8221;. <del datetime="2010-01-02T15:25:09+00:00">Postaram się naprawić</del> naprawię wszystko <a href="http://pl.wikipedia.org/wiki/ASAP">ASAP</a>.</p>
]]></content:encoded>
			<wfw:commentRss>http://temporal.pr0.pl/devblog/2010/01/02/problem-z-kodowaniem/feed/</wfw:commentRss>
		<slash:comments>1</slash:comments>
		</item>
		<item>
		<title>Not yet dead.</title>
		<link>http://temporal.pr0.pl/devblog/2009/12/30/not-yet-dead/</link>
		<comments>http://temporal.pr0.pl/devblog/2009/12/30/not-yet-dead/#comments</comments>
		<pubDate>Wed, 30 Dec 2009 20:52:39 +0000</pubDate>
		<dc:creator>Jacek Złydach</dc:creator>
				<category><![CDATA[Informatyka]]></category>
		<category><![CDATA[Projekty studenckie]]></category>
		<category><![CDATA[devBlog - Techniczne]]></category>
		<category><![CDATA[artSea]]></category>

		<guid isPermaLink="false">http://temporal.pr0.pl/devblog/?p=788</guid>
		<description><![CDATA[Witajcie po długiej przerwie. Niedługo devBlog najprawdopodobniej zmieni serwer (fizycznie), co powoduje, że w ostatnim okresie nie pisałem za wiele oraz to, że w najbliższej przyszłości może pojawić się kolejna przerwa. Cierpliwości, gdy kwestie techniczne się unormują to sytuacja powinna się poprawić  .
Na dzień dzisiejszy chciałbym tylko ogłosić powstanie nowego projektu zespołowego &#8211; Artificial [...]]]></description>
			<content:encoded><![CDATA[<p>Witajcie po długiej przerwie. Niedługo devBlog najprawdopodobniej zmieni serwer (fizycznie), co powoduje, że w ostatnim okresie nie pisałem za wiele oraz to, że w najbliższej przyszłości może pojawić się kolejna przerwa. Cierpliwości, gdy kwestie techniczne się unormują to sytuacja powinna się poprawić <img src='http://temporal.pr0.pl/devblog/wp-includes/images/smilies/icon_wink.gif' alt=';)' class='wp-smiley' /> .</p>
<p>Na dzień dzisiejszy chciałbym tylko ogłosić powstanie nowego projektu zespołowego &#8211; <strong>Artificial Sea</strong>. Jest to praca zaliczeniowa z jednego z przedmiotów; powód, dla którego ogłaszam to teraz a nie przed skończeniem jest głównie psychologiczny &#8211; publiczne oświadczenie zwykle bardzo dobrze motywuje <img src='http://temporal.pr0.pl/devblog/wp-includes/images/smilies/icon_wink.gif' alt=';)' class='wp-smiley' /> . Aktualne prace można śledzić na <a href="http://code.google.com/p/art-sea/">stronie</a> i <a href="http://artificial-sea.blogspot.com/">blogu</a> projektu. Wyprzedzając ten ostatni mogę nadmienić, że projekt wykorzystuje silnik graficzny <a href="http://ogre3d.org/">OGRE 3D</a> <img src='http://temporal.pr0.pl/devblog/wp-includes/images/smilies/icon_wink.gif' alt=';)' class='wp-smiley' /> .</p>
]]></content:encoded>
			<wfw:commentRss>http://temporal.pr0.pl/devblog/2009/12/30/not-yet-dead/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>tv.roflcopter.pl</title>
		<link>http://temporal.pr0.pl/devblog/2009/11/27/tv-roflcopter-pl/</link>
		<comments>http://temporal.pr0.pl/devblog/2009/11/27/tv-roflcopter-pl/#comments</comments>
		<pubDate>Fri, 27 Nov 2009 19:37:13 +0000</pubDate>
		<dc:creator>Jacek Złydach</dc:creator>
				<category><![CDATA[Humor]]></category>
		<category><![CDATA[Varia]]></category>
		<category><![CDATA[Z życia]]></category>
		<category><![CDATA[roflcopter]]></category>

		<guid isPermaLink="false">http://temporal.pr0.pl/devblog/?p=784</guid>
		<description><![CDATA[Serwis Roflcopter.pl znany jest chyba wszystkim polskim koderom. Dawno, dawno temu, kiedy jeszcze na roflcopterze były faktycznie śmieszne cytaty, istniał też serwis tv.roflcopter.pl, który zbierał filmy na YouTube związane z klimatami strony. Właściwie, to ten serwis istnieje do dzisiaj &#8211; http://tv.roflcopter.pl/. Ciekawi mnie tylko, dlaczego link do niego tak po prostu &#8220;znikł&#8221; ze strony głównej? [...]]]></description>
			<content:encoded><![CDATA[<p>Serwis <a href="http://roflcopter.pl">Roflcopter.pl</a> znany jest chyba wszystkim polskim koderom. Dawno, dawno temu, kiedy jeszcze na roflcopterze były faktycznie śmieszne cytaty, istniał też serwis tv.roflcopter.pl, który zbierał filmy na YouTube związane z klimatami strony. Właściwie, to ten serwis istnieje do dzisiaj &#8211; <a href="http://tv.roflcopter.pl/">http://tv.roflcopter.pl/</a>. Ciekawi mnie tylko, dlaczego link do niego tak po prostu &#8220;znikł&#8221; ze strony głównej? Dlaczego go zarzucono? Jeśli ktoś wie, to proszę o informację w komentarzu <img src='http://temporal.pr0.pl/devblog/wp-includes/images/smilies/icon_smile.gif' alt=':)' class='wp-smiley' /> .</p>
]]></content:encoded>
			<wfw:commentRss>http://temporal.pr0.pl/devblog/2009/11/27/tv-roflcopter-pl/feed/</wfw:commentRss>
		<slash:comments>1</slash:comments>
		</item>
		<item>
		<title>The Graveyard</title>
		<link>http://temporal.pr0.pl/devblog/2009/11/17/the-graveyard/</link>
		<comments>http://temporal.pr0.pl/devblog/2009/11/17/the-graveyard/#comments</comments>
		<pubDate>Tue, 17 Nov 2009 20:07:40 +0000</pubDate>
		<dc:creator>Jacek Złydach</dc:creator>
				<category><![CDATA[Informatyka]]></category>
		<category><![CDATA[Tworzenie gier]]></category>
		<category><![CDATA[experiential gameplay]]></category>
		<category><![CDATA[projektowanie]]></category>
		<category><![CDATA[The Graveyard]]></category>
		<category><![CDATA[uczucia]]></category>

		<guid isPermaLink="false">http://temporal.pr0.pl/devblog/?p=340</guid>
		<description><![CDATA[Jakiś czas temu trafiłem w sieci na kolejnego &#8220;experientiala&#8220;, tym razem o zupełnie innym wykonaniu niż poprzednie, które pokazywałem. The Graveyard to krótka gra (a może &#8211; opowieść?) o starszej kobiecie odwiedzającej cmentarz. Stworzona przez grupę Tale of Tales, porusza temat śmierci w sposób nietypowy dla gier komputerowych, a bardziej kojarzący się z klasycznymi formami [...]]]></description>
			<content:encoded><![CDATA[<p>Jakiś czas temu trafiłem w sieci na kolejnego <a href="http://temporal.pr0.pl/devblog/2009/03/04/experiential-gameplay/">&#8220;<em>experientiala</em>&#8220;</a>, tym razem o zupełnie innym wykonaniu niż poprzednie, które pokazywałem. <a href="http://tale-of-tales.com/TheGraveyard/"><em>The Graveyard</em></a> to krótka gra (a może &#8211; opowieść?) o starszej kobiecie odwiedzającej cmentarz. Stworzona przez grupę <a href="http://tale-of-tales.com/blog/information/">Tale of Tales</a>, porusza temat śmierci w sposób nietypowy dla gier komputerowych, a bardziej kojarzący się z klasycznymi formami sztuki.</p>
<p><strong>UWAGA! SPOILER WARNING! <img src='http://temporal.pr0.pl/devblog/wp-includes/images/smilies/icon_smile.gif' alt=':)' class='wp-smiley' /> </strong><br />
<strong>Gorąco polecam <a href="http://tale-of-tales.com/TheGraveyard/#download">zagrać w tę grę</a> przed lekturą tego wpisu, gdyż dalej znajdują się informacje, które mogą wpłynąć na rozgrywkę.</strong></p>
<p>Rozgrywka w całości skupia się na starszej kobiecie odwiedzającej cmentarz. Z punktu widzenia klasycznych gier komputerowych nie ma w <em>The Graveyard</em> zbyt wiele do roboty. Cała gra streszcza się do przejścia fragmentu cmentarnej alejki, zatrzymania się na ławeczce, wysłuchania krótkiej piosenki i wyjścia z cmentarza; nie ma jako takiego celu gry. Całe sedno przekazu skupia się na środowisku oraz na osobie bohaterki &#8211; starszej kobiety, która do chwili przedstawionej w grze prawdopodobnie straciła już wszystkich, których znała bądź obchodziła.</p>
<p>Powiem szczerze, że z początku miałem problemy, żeby wczuć się w tę historię. W szczególności nie przemówiła do mnie zawarta w grze piosenka. Ale im dłużej myślałem o <em>The Graveyard</em>, tym bardziej ciągnęło mnie z powrotem i dwóch-trzech kolejnych podejściach złapałem klimat.</p>
<p>Niewątpliwie <em>The Graveyard</em> wymaga nieco więcej zaangażowania umysłowego niż typowa gra. Żeby dobrze odczuć przekaz trzeba się chwilkę zatrzymać, &#8216;pooddychać&#8217; światem gry, wsłuchać się w dźwięki, melodię i słowa.</p>
<p>Gra jest dostępna w darmowej wersji trial oraz pełnej, w cenie 5$. Nie kupiłem pełnej (ktoś mnie nauczy, jak się obsługuje PayPale i takie tam?), ale z tego co <a href="http://blog.wired.com/games/2008/03/the-graveyards.html">przeczytałem w Internecie</a> to jedyną różnicą jest bardzo specyficzne i zaskakujące jak na grę komputerową zakończenie.</p>
<p>Autorzy gry opublikowali <a href="http://tale-of-tales.com/blog/the-graveyard-post-mortem/">dość obszerny i ciekawy <em>post mortem</em></a>, który omawia nie tylko kwestie związane z projektowaniem gry i rozwojem pomysłu, ale także ze zdobyciem funduszy na realizację, z odbiorem gry przez graczy i z ostateczną sprzedażą. Polecam lekturę <img src='http://temporal.pr0.pl/devblog/wp-includes/images/smilies/icon_smile.gif' alt=':)' class='wp-smiley' />  .</p>
]]></content:encoded>
			<wfw:commentRss>http://temporal.pr0.pl/devblog/2009/11/17/the-graveyard/feed/</wfw:commentRss>
		<slash:comments>3</slash:comments>
		</item>
		<item>
		<title>GoTo &#8211; ciekawostka</title>
		<link>http://temporal.pr0.pl/devblog/2009/11/14/goto-ciekawostka/</link>
		<comments>http://temporal.pr0.pl/devblog/2009/11/14/goto-ciekawostka/#comments</comments>
		<pubDate>Sat, 14 Nov 2009 00:08:03 +0000</pubDate>
		<dc:creator>Jacek Złydach</dc:creator>
				<category><![CDATA[Informatyka]]></category>
		<category><![CDATA[FORTRAN]]></category>
		<category><![CDATA[goto]]></category>
		<category><![CDATA[Java]]></category>

		<guid isPermaLink="false">http://temporal.pr0.pl/devblog/?p=771</guid>
		<description><![CDATA[goto &#8211; chyba najbardziej kontrowersyjna konstrukcja programistyczna na świecie. Od czasu słynnego listu Dijkstry instrukcja ta wzbudza wiele kontrowersji i sprzecznych opinii. Panuje więc przekonanie, że instrukcja ta jest zła i nie należy jej stosować. Szanujące się profesjonalne języki wysokiego poziomu takie jak Java* nawet nie posiadają takiej konstrukcji. Right?&#8230;
Wrong.
Wiadomo, że słowo goto jest w [...]]]></description>
			<content:encoded><![CDATA[<p><em><strong>goto</strong></em> &#8211; chyba najbardziej kontrowersyjna konstrukcja programistyczna na świecie. Od czasu <a href="http://www.cs.utexas.edu/users/EWD/ewd02xx/EWD215.PDF">słynnego listu Dijkstry</a> instrukcja ta wzbudza wiele <a href="http://xion.org.pl/2008/06/24/bo-to-zla-instrukcja-byla/">kontrowersji</a> i sprzecznych opinii. Panuje więc przekonanie, że <a href="http://xkcd.com/292/">instrukcja ta jest zła i nie należy jej stosować</a>. Szanujące się profesjonalne języki wysokiego poziomu takie jak Java<a name="POST_GOTO_MT_1" href="#POST_GOTO_REF_1">*</a> nawet nie posiadają takiej konstrukcji. Right?&#8230;</p>
<p>Wrong.<br />
Wiadomo, że słowo <em>goto</em> jest w Javie zarezerwowane i nie może być użyte przez programistę. Na poziomie języka programowania nie ma dostępu do tej instrukcji, jednak jest ona dostępna bezpośrednio z poziomu <a href="http://en.wikipedia.org/wiki/Java_bytecode">bytecode&#8217;u</a>. Fakt ten został w ciekawy sposób wykorzystany przez programistów projektu <a href="http://icl.cs.utk.edu/f2j/overview/index.html">f2j</a> mającego na celu przetłumaczyć biblioteki FORTRANa na Javę.</p>
<p>FORTRAN jest językiem, w którym korzystanie z <em>goto</em> było na porządku dziennym. Brak omawianego mechanizmu w Javie stanowił poważne utrudnienie przy tłumaczeniu kodu FORTRANa na Javę. Programiści wymyślili więc bardzo sprytny sposób &#8211; generując kod Javy wstawiali w miejsce <em>goto</em> instrukcje zastępcze, które po skompilowaniu były na poziomie bytecode&#8217;u zamieniane na prawdziwe wywołania &#8220;złowrogiej instrukcji&#8221;. Swoje wysiłki <a href="http://icl.cs.utk.edu/news_pub/submissions/f2jreport.pdf">opisali w ciekawej publikacji</a>.</p>
<p><a name="POST_GOTO_REF_1" href="#POST_GOTO_MT_1">*</a> &#8211; Czytelnik słusznie dostrzeże tu nutkę sarkazmu.</p>
]]></content:encoded>
			<wfw:commentRss>http://temporal.pr0.pl/devblog/2009/11/14/goto-ciekawostka/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Ada &#8211; ciekawostki języka</title>
		<link>http://temporal.pr0.pl/devblog/2009/11/11/ada-ciekawostki-jezyka/</link>
		<comments>http://temporal.pr0.pl/devblog/2009/11/11/ada-ciekawostki-jezyka/#comments</comments>
		<pubDate>Wed, 11 Nov 2009 13:05:24 +0000</pubDate>
		<dc:creator>Jacek Złydach</dc:creator>
				<category><![CDATA[Informatyka]]></category>
		<category><![CDATA[Ada]]></category>
		<category><![CDATA[key params]]></category>
		<category><![CDATA[numeric_limits]]></category>

		<guid isPermaLink="false">http://temporal.pr0.pl/devblog/?p=756</guid>
		<description><![CDATA[W ramach przedmiotu &#8220;Programowanie Współbieżne i Rozproszone&#8221; zapoznaję się ostatnio z językiem Ada (dokładniej: Ada&#8217;95). Choć z początku mnie odpychała (głównie ze względu na nazwę i jej pochodzenie), to jednak po bliższym przyjrzeniu się jej dostrzegłem kilka co najmniej interesujących cech, o których warto wspomnieć.
Operatory and i or
Operatory logiczne and i or (odpowiedniki &#038;&#038; i [...]]]></description>
			<content:encoded><![CDATA[<p>W ramach przedmiotu <em>&#8220;Programowanie Współbieżne i Rozproszone&#8221;</em> zapoznaję się ostatnio z językiem Ada (dokładniej: Ada&#8217;95). Choć z początku mnie odpychała (głównie ze względu na nazwę i jej pochodzenie), to jednak po bliższym przyjrzeniu się jej dostrzegłem kilka co najmniej interesujących cech, o których warto wspomnieć.</p>
<p><strong>Operatory and i or</strong><br />
Operatory logiczne <em>and</em> i <em>or</em> (odpowiedniki &#038;&#038; i II z C++) NIE wchodzą w tzw. krótkie spięcie &#8211; to znaczy, że w przypadku wyrażeń logicznych postaci A or B czy A and B oba składniki obliczane są niezależnie od tego, jaka jest ich wynikowa wartość logiczna. Dla kontrastu przypomnę typowe zastosowanie &#8216;krótkiego spięcia&#8217; z języka C:</p>
<div class="codecolorer-container cpp default" style="overflow:auto;white-space:nowrap;border:1px solid #9F9F9F;width:435px;"><div class="cpp codecolorer" style="padding:5px;font:normal 12px/1.4em Monaco, Lucida Console, monospace;white-space:nowrap"><span style="color: #0000ff;">if</span><span style="color: #008000;">&#40;</span>napis <span style="color: #000040;">&amp;&amp;</span> <span style="color: #0000dd;">strlen</span><span style="color: #008000;">&#40;</span>napis<span style="color: #008000;">&#41;</span> <span style="color: #000040;">!</span><span style="color: #000080;">=</span> <span style="color: #0000dd;">0</span><span style="color: #008000;">&#41;</span></div></div>
<p>Ada posiada jednak operatory, które zachowują się jak odpowiedniki z C++ &#8211; są to <em>and then</em> i <em>or else</em>. Początkujący programiści Ady powinni zwrócić na ten fakt szczególną uwagę.</p>
<p><strong>max(), min() i numeric_limits<></strong><br />
W większości języków funkcje max() i min(), zwracające największy / najmniejszy element z podanych, zwykle umieszczane są w jakichś bibliotekach &#8211; w Adzie zostały osadzone bezpośrednio w typach. Dzięki temu piszemy np. <code class="codecolorer ada default"><span class="ada">Integer'Max<span style="color: #66cc66;">&#40;</span><span style="color: #ff0000;">123</span>, <span style="color: #ff0000;">256</span><span style="color: #66cc66;">&#41;</span></span></code>. Idea ta sięga głębiej &#8211; cechy liczb czyli coś, co w C wpisywaliśmy &#8220;z palca&#8221; a w C++ załatwialiśmy z pomocą <a href="http://temporal.pr0.pl/devblog/2007/07/03/stdnumeric_limitst/">std::numeric_limits<T></a> również jest osadzone w typach. Przykłady dostępnych wartości:</p>
<div class="codecolorer-container ada default" style="overflow:auto;white-space:nowrap;border:1px solid #9F9F9F;width:435px;"><div class="ada codecolorer" style="padding:5px;font:normal 12px/1.4em Monaco, Lucida Console, monospace;white-space:nowrap">Integer'First <span style="color: #adadad; font-style: italic;">-- najmniejsza liczba zapisywalna w tym typie</span><br />
Integer'Last <span style="color: #adadad; font-style: italic;">-- największa liczba zapisywalna w tym typie</span><br />
Short_Float'Size <span style="color: #adadad; font-style: italic;">-- rozmiar typu Short_Float w bitach</span><br />
Float'Model_Epsilon <span style="color: #adadad; font-style: italic;">-- różnica między 1.0 a następną reprezentowalną liczbą zmiennoprzecinkową</span><br />
Float'SafeFirst <span style="color: #adadad; font-style: italic;">-- dolne ograniczenie typu zmiennoprzecinkowego</span><br />
Float'SafeLast <span style="color: #adadad; font-style: italic;">-- górne ograniczenie typu zmiennoprzecinkowego</span><br />
Float'<span style="color: #46aa03; font-weight:bold;">Digits</span> <span style="color: #adadad; font-style: italic;">-- liczba cyfr znaczących w reprezentacji zmiennoprzecinkowej</span></div></div>
<p><del datetime="2010-02-15T11:41:46+00:00"><em>(przepraszam za byle jakie kolorowanie składni &#8211; czas poszukać lepszego pluginu)</em></del><br />
<ins datetime="2010-02-15T11:41:46+00:00">Lepszy plugin znaleziony <img src='http://temporal.pr0.pl/devblog/wp-includes/images/smilies/icon_wink.gif' alt=';)' class='wp-smiley' /> </ins></p>
<p>Ogólna koncepcja atrybutów typów jest w tym języku dość rozbudowana &#8211; z ciekawszych zastosowań:</p>
<div class="codecolorer-container ada default" style="overflow:auto;white-space:nowrap;border:1px solid #9F9F9F;width:435px;"><div class="ada codecolorer" style="padding:5px;font:normal 12px/1.4em Monaco, Lucida Console, monospace;white-space:nowrap">M : <span style="color: #46aa03; font-weight:bold;">array</span> <span style="color: #66cc66;">&#40;</span>Natural <span style="color: #46aa03; font-weight:bold;">range</span> <span style="color: #ff0000;">1</span>..16<span style="color: #66cc66;">&#41;</span> <span style="color: #46aa03; font-weight:bold;">of</span> Float;<br />
<span style="color: #adadad; font-style: italic;">--....</span><br />
<span style="color: #00007f;">for</span> i <span style="color: #46aa03; font-weight:bold;">in</span> M'<span style="color: #46aa03; font-weight:bold;">range</span> <span style="color: #00007f;">loop</span> <span style="color: #adadad; font-style: italic;">-- atrybut range zwraca przedzial indeksow tablicy</span><br />
<span style="color: #adadad; font-style: italic;">-- kod petli</span><br />
<span style="color: #00007f;">end</span> <span style="color: #00007f;">loop</span>;<br />
<br />
M'Length <span style="color: #adadad; font-style: italic;">--podaje ilosc elementow tablicy (dlugosc przedzialu)</span><br />
Put<span style="color: #66cc66;">&#40;</span>Integer'Image<span style="color: #66cc66;">&#40;</span><span style="color: #ff0000;">214</span><span style="color: #66cc66;">&#41;</span><span style="color: #66cc66;">&#41;</span>; <span style="color: #adadad; font-style: italic;">--atrybut Image konwertuje zmienna danego typu skalarnego (Integer, Float, etc.) na tekst.</span></div></div>
<p><strong>Instrukcja null</strong><br />
Interesującą koncepcją jest instrukcja pusta &#8211; <em>null</em>. Ada zmusza nas do użycia jej wszędzie tam, gdzie chcielibyśmy po prostu nie robić niczego &#8211; np. wewnątrz pustych funkcji.</p>
<p><strong>Switch</strong><br />
Ada wymusza, by instrukcja <em>case</em> (znana w C++ jako switch) obsługiwała wszystkie dopuszczalne możliwości  &#8211; w przypadku, gdy nie chcemy obsłużyć pewnych wartości, musimy odwołać się do do wariantu <em>others</em> (znanego w C++ jako <em>default</em>). Konstrukcja <em>case</em>&#8216;a jest też dużo wygodniejsza niż jej odpowiedniki w najbliższej rodzinie C++&#8217;a &#8211; niech zilustruje to przykład:</p>
<div class="codecolorer-container ada default" style="overflow:auto;white-space:nowrap;border:1px solid #9F9F9F;width:435px;height:300px;"><div class="ada codecolorer" style="padding:5px;font:normal 12px/1.4em Monaco, Lucida Console, monospace;white-space:nowrap">Get <span style="color: #66cc66;">&#40;</span>Znak<span style="color: #66cc66;">&#41;</span>;<br />
<span style="color: #00007f;">case</span> Znak <span style="color: #00007f;">is</span><br />
&nbsp; &nbsp; <span style="color: #46aa03; font-weight:bold;">when</span> '<span style="color: #ff0000;">0</span>' | '<span style="color: #ff0000;">1</span>' | '<span style="color: #ff0000;">2</span>' | '<span style="color: #ff0000;">3</span>' | '<span style="color: #ff0000;">4</span>' | '<span style="color: #ff0000;">5</span>' | '<span style="color: #ff0000;">6</span>' | '<span style="color: #ff0000;">7</span>' | '<span style="color: #ff0000;">8</span>' | '<span style="color: #ff0000;">9</span>' =&gt;<br />
&nbsp; &nbsp; &nbsp; &nbsp; Put<span style="color: #66cc66;">&#40;</span>'To jest cyfra dziesietna = '<span style="color: #66cc66;">&#41;</span>;<br />
&nbsp; &nbsp; &nbsp; &nbsp; Put<span style="color: #66cc66;">&#40;</span>Znak<span style="color: #66cc66;">&#41;</span>;<br />
&nbsp; &nbsp; &nbsp; &nbsp; New_Line;<br />
&nbsp; &nbsp; <span style="color: #46aa03; font-weight:bold;">when</span> 'A' .. 'Z' =&gt;<br />
&nbsp; &nbsp; &nbsp; &nbsp; Put<span style="color: #66cc66;">&#40;</span>'To jest wielka litera = '<span style="color: #66cc66;">&#41;</span>;<br />
&nbsp; &nbsp; &nbsp; &nbsp; Put<span style="color: #66cc66;">&#40;</span>Znak<span style="color: #66cc66;">&#41;</span>;<br />
&nbsp; &nbsp; &nbsp; &nbsp; New_Line;<br />
&nbsp; &nbsp; <span style="color: #46aa03; font-weight:bold;">when</span> 'a' .. 'z' =&gt;<br />
&nbsp; &nbsp; &nbsp; &nbsp; Put<span style="color: #66cc66;">&#40;</span>'To jest mala litera = '<span style="color: #66cc66;">&#41;</span>;<br />
&nbsp; &nbsp; &nbsp; &nbsp; Put<span style="color: #66cc66;">&#40;</span>Znak<span style="color: #66cc66;">&#41;</span>;<br />
&nbsp; &nbsp; &nbsp; &nbsp; New_Line;<br />
&nbsp; &nbsp; <span style="color: #46aa03; font-weight:bold;">when</span> '_' =&gt;<br />
&nbsp; &nbsp; &nbsp; &nbsp; Put<span style="color: #66cc66;">&#40;</span>'To jest podkreslnik = '<span style="color: #66cc66;">&#41;</span>;<br />
&nbsp; &nbsp; &nbsp; &nbsp; Put<span style="color: #66cc66;">&#40;</span>Znak<span style="color: #66cc66;">&#41;</span>;<br />
&nbsp; &nbsp; &nbsp; &nbsp; New_Line;<br />
&nbsp; &nbsp; <span style="color: #46aa03; font-weight:bold;">when</span> <span style="color: #46aa03; font-weight:bold;">others</span> =&gt;<br />
&nbsp; &nbsp; &nbsp; &nbsp; Put<span style="color: #66cc66;">&#40;</span>'To jest inny znak '<span style="color: #66cc66;">&#41;</span>;<br />
<span style="color: #00007f;">end</span> <span style="color: #00007f;">case</span>;</div></div>
<p>Warto zwrócić uwagę na sposób łączenia wariantów za pomocą znaku | oraz określania wariantów będących przedziałami.</p>
<p><strong>Key parameters</strong><br />
W różnych miejscach języka występują pod różnymi nazwami &#8211; chodzi oczywiście o powiązania pomiędzy nazwami zmiennych a wartościami. Dzięki temu możemy np. zwięźle inicjalizować obiekty:</p>
<div class="codecolorer-container ada default" style="overflow:auto;white-space:nowrap;border:1px solid #9F9F9F;width:435px;"><div class="ada codecolorer" style="padding:5px;font:normal 12px/1.4em Monaco, Lucida Console, monospace;white-space:nowrap"><span style="color: #46aa03; font-weight:bold;">type</span> Data <span style="color: #00007f;">is</span><br />
&nbsp; &nbsp; <span style="color: #46aa03; font-weight:bold;">record</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; Rok : Positive <span style="color: #46aa03; font-weight:bold;">range</span> <span style="color: #ff0000;">1</span> .. <span style="color: #ff0000;">2500</span>;<br />
&nbsp; &nbsp; &nbsp; &nbsp; Miesiac : Positive <span style="color: #46aa03; font-weight:bold;">range</span> <span style="color: #ff0000;">1</span> .. <span style="color: #ff0000;">12</span>;<br />
&nbsp; &nbsp; &nbsp; &nbsp; Dzien : Positive <span style="color: #46aa03; font-weight:bold;">range</span> <span style="color: #ff0000;">1</span> .. <span style="color: #ff0000;">31</span>;<br />
&nbsp; &nbsp; <span style="color: #00007f;">end</span> <span style="color: #46aa03; font-weight:bold;">record</span>;<br />
<span style="color: #adadad; font-style: italic;">--...</span><br />
<br />
<span style="color: #adadad; font-style: italic;">--tworzenie obiektu Data:</span><br />
Dzien := <span style="color: #66cc66;">&#40;</span>Miesiac =&gt; <span style="color: #ff0000;">6</span>, Dzien =&gt; <span style="color: #ff0000;">22</span>, Rok =&gt; <span style="color: #ff0000;">2000</span><span style="color: #66cc66;">&#41;</span>;</div></div>
<p>Lub czytelniej wywoływać procedury:</p>
<div class="codecolorer-container ada default" style="overflow:auto;white-space:nowrap;border:1px solid #9F9F9F;width:435px;"><div class="ada codecolorer" style="padding:5px;font:normal 12px/1.4em Monaco, Lucida Console, monospace;white-space:nowrap"><span style="color: #46aa03; font-weight:bold;">procedure</span> DotProduct <span style="color: #66cc66;">&#40;</span>A, B : <span style="color: #46aa03; font-weight:bold;">in</span> Vector; D: <span style="color: #46aa03; font-weight:bold;">out</span> Float<span style="color: #66cc66;">&#41;</span> <span style="color: #00007f;">is</span> <span style="color: #adadad; font-style: italic;">-- naglowek funkcji</span><br />
<span style="color: #adadad; font-style: italic;">--...</span><br />
DotProduct<span style="color: #66cc66;">&#40;</span>D =&gt; Iloczyn, B =&gt; Wektor1, A =&gt; Wektor2<span style="color: #66cc66;">&#41;</span>;</div></div>
<p>W obu tych przypadkach kolejność przekazywania zmiennych do wyrażenia jest inna niż kolejność, w której zostały one określone w strukturze / nagłówku procedury. W tym drugim przypadku daje to możliwość wygodnego przekazywania tylko części parametrów opcjonalnych. Jest to moim zdaniem jedna z lepszych cech tego języka.</p>
<p><strong>Zagnieżdżone funkcje</strong><br />
Ada pozwala zagnieżdżać funkcje i procedury wewnątrz innych funkcji i procedur. Tak naprawdę Ada rozdziela część deklaracyjną od samego ciała danej funkcji, dzięki czemu można tworzyć np. procedury lokalne dla innych procedur, typy danych lokalne dla procedur, etc. Powiem jednak szczerze, że nie miałem jeszcze okazji wykorzystywać w jakiś szczególny sposób tej funkcjonalności w żadnym z języków, w których się ona pojawiła. </p>
<p><strong>Funkcje a procedury</strong><br />
Z punktu widzenia Pascala &#8211; różnica słowa kluczowego. Z punktu widzenia C++ &#8211; kwestia nazewnictwa (procedurą nazywamy funkcję, która nie zwraca wartości). W Adzie jest inaczej &#8211; funkcja nie może wyprowadzać wartości na zewnątrz przy użyciu argumentów <em>out</em> i <em>inout</em>; ponadto musi zwracać wartość i wolno jej występować w kodzie tylko jako element wyrażenia. Przykład:</p>
<div class="codecolorer-container ada default" style="overflow:auto;white-space:nowrap;border:1px solid #9F9F9F;width:435px;"><div class="ada codecolorer" style="padding:5px;font:normal 12px/1.4em Monaco, Lucida Console, monospace;white-space:nowrap">A := Sin<span style="color: #66cc66;">&#40;</span>X<span style="color: #66cc66;">&#41;</span>; <span style="color: #adadad; font-style: italic;">-- legalne, funkcja wystepuje w wyrażeniu (w tym wypadku w przypisaniu)</span><br />
Sin<span style="color: #66cc66;">&#40;</span>X<span style="color: #66cc66;">&#41;</span>; <span style="color: #adadad; font-style: italic;">--nielegalne, funkcja nie jest skladnikiem wyrazenia</span></div></div>
<p>Innymi słowy, wartość zwracana nie może pójść donikąd.</p>
<p><strong>Operator /=</strong><br />
Operator /= (odpowiednik != z C++) jest generowany automatycznie, gdy przeciążony operator = (odpowiednik == z C++) zwraca wartość <em>boolean</em>.</p>
<p><strong>Czym jest nowa linia?</strong><br />
Wygląda na to, że wczytując z pliku tekstowego Ada automatycznie zamienia sekwencje znaków nowej linii wg Unixa (ASCII 10) i Windowsa (ASCII 13 + ASCII 10) na znaki ASCII 30.  Cytując ze skryptu <a href="http://www.zsk.p.lodz.pl/~zajaczko/Podstawy_Informatyki_Ada_95/Ada_95_Skrypt_Wyd_II.pdf"><em>&#8220;Wstęp do programowania w języku Ada&#8217;95&#8243;</em></a>:</p>
<blockquote><p>znaki ograniczające linie tekstu w systemie Unix (Character&#8217;Val (10)) i w systemie DOS, Windows (Character&#8217;Val (13)&#038; Character&#8217;Val (10)) są interpretowane w taki sposób, że są zawsze zamieniane na znak (Character&#8217;Val (30))</p></blockquote>
<p>Jest to o tyle ciekawe, że ASCII 30 to znak sterujący RS, czyli Record Separator.</p>
<p>Na dzień dzisiejszy Ada ma jak dla mnie tylko jedną poważną wadę &#8211; absolutny brak sensownej dokumentacji w sieci. Pomimo Pascalowej składni i braku darmowych wygodnych narzędzi pod Windowsa jest językiem bardzo interesującym i szczerze mówiąc nie zdziwiłbym się, gdyby dalej była używana w miejscach takich jak medycyna czy wojsko, w których niezawodność oprogramowania czasu rzeczywistego jest kluczowa. A &#8211; cytując Fusa &#8211; jest przytłaczający dowód na to, że sprzęt wojskowy jest niezawodny: wciąż żyjemy.</p>
]]></content:encoded>
			<wfw:commentRss>http://temporal.pr0.pl/devblog/2009/11/11/ada-ciekawostki-jezyka/feed/</wfw:commentRss>
		<slash:comments>1</slash:comments>
		</item>
		<item>
		<title>Problemy, przenosiny i nowe tematy</title>
		<link>http://temporal.pr0.pl/devblog/2009/11/07/problemy-przenosiny-i-nowe-tematy/</link>
		<comments>http://temporal.pr0.pl/devblog/2009/11/07/problemy-przenosiny-i-nowe-tematy/#comments</comments>
		<pubDate>Sat, 07 Nov 2009 13:36:45 +0000</pubDate>
		<dc:creator>Jacek Złydach</dc:creator>
				<category><![CDATA[Informatyka]]></category>
		<category><![CDATA[devBlog - Techniczne]]></category>
		<category><![CDATA[C++]]></category>
		<category><![CDATA[devBlog]]></category>

		<guid isPermaLink="false">http://temporal.pr0.pl/devblog/?p=749</guid>
		<description><![CDATA[Przez ostatnie dwa tygodnie devBlog straszył grzybem atomowym. Mieliśmy poważne problemy związane z szafoserwerem pr0.pl, i chociaż dzięki Fusowi znów działa PHP, to blog długo tu już nie postoi. W najbliższych tygodniach planowana jest przeprowadzka na wirtualny serwer. Domena (miejmy nadzieję) pozostanie ta sama. Póki co devBlog jest czynny, ale nigdy nie wiadomo kiedy zdarzy [...]]]></description>
			<content:encoded><![CDATA[<p>Przez ostatnie dwa tygodnie devBlog straszył grzybem atomowym. Mieliśmy poważne problemy związane z szafoserwerem pr0.pl, i chociaż dzięki Fusowi znów działa PHP, to blog długo tu już nie postoi. W najbliższych tygodniach planowana jest przeprowadzka na wirtualny serwer. Domena (miejmy nadzieję) pozostanie ta sama. Póki co devBlog jest czynny, ale nigdy nie wiadomo kiedy zdarzy się najbliższa awaria.</p>
<p>W związku z tym, że wokół mnie dzieje się obecnie bardzo dużo ciekawych rzeczy związanych z informatyką to na pewno pojawi się też i więcej tekstów; główny przypływ nastąpi jednak najprawdopodobniej po przeprowadzce.</p>
<p>Serdecznie pozdrawiam też Czytelnika z IS2009, którego miałem okazję spotkać na środowym wykładzie z PUKu <img src='http://temporal.pr0.pl/devblog/wp-includes/images/smilies/icon_wink.gif' alt=';)' class='wp-smiley' /> .</p>
<p>PS. W ramach relaksu polecam rozwiązanie sobie zadań z konkursu <a href="http://www.nokiasiemensnetworks.com/">Nokia Siemens Networks</a> na <a href="http://www.ck.agh.edu.pl/targi/index.php">Targach Pracy AGH</a> &#8211; wyglądały one mniej więcej (podaję z pamięci) tak:</p>
<div class="codecolorer-container cpp default" style="overflow:auto;white-space:nowrap;border:1px solid #9F9F9F;width:435px;height:300px;"><div class="cpp codecolorer" style="padding:5px;font:normal 12px/1.4em Monaco, Lucida Console, monospace;white-space:nowrap"><span style="color: #666666;">//Co zostanie wypisane?</span><br />
<span style="color: #0000ff;">const</span> <span style="color: #0000ff;">int</span> STALA <span style="color: #000080;">=</span> <span style="color: #0000dd;">3</span><span style="color: #008080;">;</span><br />
<br />
<span style="color: #0000ff;">struct</span> Test<br />
<span style="color: #008000;">&#123;</span><br />
&nbsp; &nbsp; <span style="color: #0000ff;">void</span> Funkcja<span style="color: #008000;">&#40;</span><span style="color: #008000;">&#41;</span><br />
&nbsp; &nbsp; <span style="color: #008000;">&#123;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; std<span style="color: #008080;">::</span><span style="color: #0000dd;">cout</span> <span style="color: #000080;">&lt;&lt;</span> STALA <span style="color: #000080;">&lt;&lt;</span> std<span style="color: #008080;">::</span><span style="color: #007788;">endl</span><span style="color: #008080;">;</span><br />
&nbsp; &nbsp; <span style="color: #008000;">&#125;</span><br />
&nbsp; &nbsp; <span style="color: #0000ff;">enum</span><br />
&nbsp; &nbsp; <span style="color: #008000;">&#123;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; STALA <span style="color: #000080;">=</span> <span style="color: #0000dd;">5</span><br />
&nbsp; &nbsp; <span style="color: #008000;">&#125;</span><span style="color: #008080;">;</span><br />
<span style="color: #008000;">&#125;</span><span style="color: #008080;">;</span><br />
<br />
<span style="color: #0000ff;">int</span> main<span style="color: #008000;">&#40;</span><span style="color: #008000;">&#41;</span><br />
<span style="color: #008000;">&#123;</span><br />
&nbsp; &nbsp; Test obiekt<span style="color: #008080;">;</span><br />
&nbsp; &nbsp; obiekt.<span style="color: #007788;">Funkcja</span><span style="color: #008000;">&#40;</span><span style="color: #008000;">&#41;</span><span style="color: #008080;">;</span><br />
&nbsp; &nbsp; <span style="color: #0000ff;">return</span> <span style="color: #0000dd;">0</span><span style="color: #008080;">;</span><br />
<span style="color: #008000;">&#125;</span><br />
<br />
<span style="color: #666666;">//a) 3</span><br />
<span style="color: #666666;">//b) 5</span><br />
<span style="color: #666666;">//c) błąd kompilacji</span><br />
<span style="color: #666666;">//d) wartość niezdefiniowana</span></div></div>
<div class="codecolorer-container cpp default" style="overflow:auto;white-space:nowrap;border:1px solid #9F9F9F;width:435px;"><div class="cpp codecolorer" style="padding:5px;font:normal 12px/1.4em Monaco, Lucida Console, monospace;white-space:nowrap"><span style="color: #666666;">//Co zostanie wypisane?</span><br />
<span style="color: #0000ff;">int</span> a <span style="color: #000080;">=</span> <span style="color: #0000ff;">int</span><span style="color: #008000;">&#40;</span><span style="color: #008000;">&#41;</span> <span style="color: #000080;">=</span> <span style="color: #0000dd;">3</span><span style="color: #008080;">;</span><br />
<br />
a <span style="color: #000080;">=</span> <span style="color: #0000dd;">2</span><span style="color: #008080;">;</span><br />
std<span style="color: #008080;">::</span><span style="color: #0000dd;">cout</span> <span style="color: #000080;">&lt;&lt;</span> a <span style="color: #000080;">&lt;&lt;</span> std<span style="color: #008080;">::</span><span style="color: #007788;">endl</span><span style="color: #008080;">;</span><br />
<br />
<span style="color: #666666;">//a) 3</span><br />
<span style="color: #666666;">//b) 2</span><br />
<span style="color: #666666;">//c) błąd kompilacji</span><br />
<span style="color: #666666;">//d) wartość nieokreślona</span></div></div>
<div class="codecolorer-container cpp default" style="overflow:auto;white-space:nowrap;border:1px solid #9F9F9F;width:435px;"><div class="cpp codecolorer" style="padding:5px;font:normal 12px/1.4em Monaco, Lucida Console, monospace;white-space:nowrap"><span style="color: #666666;">//Co zostanie wypisane?</span><br />
<br />
<span style="color: #0000ff;">int</span> a <span style="color: #000080;">=</span> <span style="color: #0000dd;">0</span><span style="color: #008080;">;</span><br />
<span style="color: #0000ff;">int</span> b <span style="color: #000080;">=</span> <span style="color: #0000dd;">0</span><span style="color: #008080;">;</span><br />
<br />
<span style="color: #0000ff;">if</span><span style="color: #008000;">&#40;</span>a<span style="color: #000040;">++</span> <span style="color: #000040;">&amp;&amp;</span> b<span style="color: #000040;">++</span><span style="color: #008000;">&#41;</span><br />
<span style="color: #008000;">&#123;</span><br />
&nbsp; &nbsp; b <span style="color: #000040;">+</span><span style="color: #000080;">=</span> <span style="color: #0000dd;">5</span><span style="color: #008080;">;</span><br />
<span style="color: #008000;">&#125;</span><br />
<br />
std<span style="color: #008080;">::</span><span style="color: #0000dd;">cout</span> <span style="color: #000080;">&lt;&lt;</span> a <span style="color: #000040;">+</span> b <span style="color: #000080;">&lt;&lt;</span> std<span style="color: #008080;">::</span><span style="color: #007788;">endl</span><span style="color: #008080;">;</span></div></div>
]]></content:encoded>
			<wfw:commentRss>http://temporal.pr0.pl/devblog/2009/11/07/problemy-przenosiny-i-nowe-tematy/feed/</wfw:commentRss>
		<slash:comments>2</slash:comments>
		</item>
		<item>
		<title>Hipster PDA &#8211; organizer &#8216;zrób to sam&#8217;</title>
		<link>http://temporal.pr0.pl/devblog/2009/10/16/hipster-pda-organizer-zrob-to-sam/</link>
		<comments>http://temporal.pr0.pl/devblog/2009/10/16/hipster-pda-organizer-zrob-to-sam/#comments</comments>
		<pubDate>Fri, 16 Oct 2009 15:43:42 +0000</pubDate>
		<dc:creator>Jacek Złydach</dc:creator>
				<category><![CDATA[Pragmatyzm]]></category>
		<category><![CDATA[Rozwój osobisty]]></category>
		<category><![CDATA[Sztuczki (Life Hacks)]]></category>
		<category><![CDATA[43 Folders]]></category>
		<category><![CDATA[GTD]]></category>
		<category><![CDATA[Hipster PDA]]></category>
		<category><![CDATA[life hacks]]></category>
		<category><![CDATA[porady]]></category>

		<guid isPermaLink="false">http://temporal.pr0.pl/devblog/?p=730</guid>
		<description><![CDATA[Nie ma powodu, żeby mieć tą samą myśl dwa razy; chyba, że bardzo lubisz ją mieć.
 David Allen, Getting Things Done
Powszechnym zjawiskiem stało się posiadanie organizerów &#8211; najczęściej różnego rodzaju i rozmiaru kalendarzy w mniej lub bardziej twardej oprawie, które znajdują swoje stałe miejsce w niezliczonych plecakach, torebkach i samochodach. Notatniki te możemy dostać w [...]]]></description>
			<content:encoded><![CDATA[<blockquote><p>Nie ma powodu, żeby mieć tą samą myśl dwa razy; chyba, że bardzo lubisz ją mieć.</p></blockquote>
<p> <em>David Allen, Getting Things Done</em></p>
<p>Powszechnym zjawiskiem stało się posiadanie organizerów &#8211; najczęściej różnego rodzaju i rozmiaru kalendarzy w mniej lub bardziej twardej oprawie, które znajdują swoje stałe miejsce w niezliczonych plecakach, torebkach i samochodach. Notatniki te możemy dostać w sklepach papierniczych, biurowych, a nawet i w spożywczych &#8211; zwykle wiąże się to z wydatkiem kilkudziesięciu złotych. Pomijając kwestię właściwego używania tych narzędzi (po zimny prysznic odsyłam do <a href="http://pl.wikipedia.org/wiki/Getting_Things_Done">Getting Things Done</a>), zapewne nie każdy zdaje sobie sprawę, że <strong>w pełni funkcjonalny i elegancki organizer można zrobić samemu za kilka złotych</strong>.</p>
<p><strong>Hipster PDA</strong><br />
Pomysł ten, zaproponowany <a href="http://www.hipsterpda.com">Merlina Manna na 43Folders</a>, sprowadza się do pliku karteczek o rozmiarze niewiele większym od karty kredytowej spiętego klipsem do papieru. Taka prosta konstrukcja ma swoje zalety w stosunku do konwencjonalnych organizerów &#8211; zarówno papierowych jak i cyfrowych:</p>
<ul>
<li><strong>Elastyczność</strong>: Brak narzuconej struktury oznacza, że notujemy co chcemy i jak chcemy.</li>
<li><strong>Wygoda</strong>: Klips do papieru pozwala otwierać notes na wiele różnych sposobów, oraz rozłożyć go, przetasować i wymienić karteczki &#8211; na przykład zarchiwizować stare notatki lub dołożyć nowy papier.</li>
<li><strong>Funkcjonalność</strong>: Możemy wyjąć karteczkę z notatkami i bez obaw dać ją komuś innemu.</li>
<li><strong>Pewność</strong>: Nigdy nie skończy się mu bateria, nie grozi mu awaria z powodu wstrząsów.</li>
<li><strong>Bezpieczeństwo</strong>: Raczej mała szansa, że ktoś będzie chciał go ukraść.</li>
</ul>
<p>Oczywiście Hipster PDA złożony z czystych kartek może okazać się niewystarczający &#8211; w końcu jak może zastąpić elegancki kalendarz czy listy adresów, które znajdują się w sklepowych oragnizerach?</p>
<p><strong>D*I*Y Planner i Hipster PDA</strong><br />
<a href="http://www.diyplanner.com/">D*I*Y Planner</a> (<acronym title="Do It Yourself">DIY</acronym> to z angielskiego &#8216;zrób to sam&#8217;) Douglasa Johnstona to zbiór bardzo dobrych darmowych szablonów do budowy własnego organizera. Pośród nich znajdują się m.in.:</p>
<ul>
<li>Kalendarz dzienny, miesięczny i roczny</li>
<li>Checklisty dla agend, zadań i projektów</li>
<li>Listy zakupów i wydatków</li>
<li>Różne karty związane z zarządzaniem biznesem i projektami</li>
<li>Karty związane z powieściopisarstwem i innymi kreatywnymi czynnościami</li>
<li>Szablony pozwalające tworzyć własne karty do organizera</li>
</ul>
<p>Oryginalnie zestaw ten powstał z myślą o dużych organizerach, jednak autor stworzył też wersję specjalnie dla Hipster PDA. Jedyne, co trzeba zrobić, by zamienić plik papieru w potężny organizer <strong>dostosowany do indywidualnych potrzeb</strong>, to&#8230; ściągnąć <a href="http://www.diyplanner.com/templates/official/hpda">D*I*Y Planner Hipster PDA Edition</a> i wydrukować interesujące nas karty.</p>
<p><strong>Implementacja</strong><br />
Używam Hipster PDA już od ponad dwóch lat i miałem przy tym okazję wielokrotnie sprawdzić, że jest to przydatne narzędzie &#8211; chciałbym więc podzielić się kilkoma uwagami związanymi z implementacją.</p>
<p>Konstrukcja Hipster PDA sprowadza się do ściągnięcia wspomnianego pakietu kartek, wydrukowania interesujących egzemplarzy i odpowiednim pocięciu &#8211; na jedną kartkę A4 dostajemy cztery wkładki do Hipster PDA. Warto przy tym wszystkim zalaminować (koszt: ok. 4zł) pierwszą i ostatnią kartę (okładki) &#8211; dzięki temu będą one sztywniejsze i szersze od reszty, co skutecznie ochroni notes przed zniszczeniem w kieszeni. Klips do papieru nie może być zbyt duży, gdyż wtedy przeglądanie notesu byłoby niewygodne. Dobrze jest też mieć dedykowany długopis lub ołówek do noszenia razem z notesem. Mój obecny Hipster PDA wygląda tak:</p>
<p><img src="http://temporal.pr0.pl/devblog/download/posts/hPDA/hpda-parts-450.jpg" alt="HipsterPDA - rozłożony" /><br />
<em>Mój Hipster PDA &#8211; w kawałkach</em></p>
<p><img src="http://temporal.pr0.pl/devblog/download/posts/hPDA/hpda-450.jpg" alt="HipsterPDA" /><br />
<em>Ten sam Hipster PDA po złożeniu, z dedykowanym dla niego ołówkiem automatycznym</em></p>
<p>Jest to już drugie podejście do tego organizera &#8211; o ile za pierwszym razem trzymałem tam kalendarz dzienny, miesięczny i całą masę przeróżnych list, o tyle teraz <a href="http://biz.blox.pl/2009/07/ZTD-05-Nawyk-1-Gromadzenie.html">skupiłem się</a> przede wszystkim na używaniu Hipster PDA jako podręcznego notesu do zbierania informacji (gdzie się podział kalendarz i dlaczego tak jest lepiej to temat na osobny wpis) i przenoszenia specyficznych danych (ostatnio dołączyłem zestaw kodów <a href="http://pl.wikipedia.org/wiki/EAN">EAN-13</a> do najczęściej kupowanych przeze mnie produktów spożywczych).</p>
<p>Hipster PDA, znany szczególnie w kręgu tzw. <acronym title="Getting Things Done">GTD</acronym>-owców, to bardzo dobra alternatywa dla konwencjonalnych organizerów. Jest tani, bazuje na papierze i można &#8211; a nawet trzeba &#8211; nosić go wszędzie ze sobą.</p>
]]></content:encoded>
			<wfw:commentRss>http://temporal.pr0.pl/devblog/2009/10/16/hipster-pda-organizer-zrob-to-sam/feed/</wfw:commentRss>
		<slash:comments>2</slash:comments>
		</item>
		<item>
		<title>Najlepsze z dwóch światów &#8211; Cygwin vs Services for Unix-based Applications pod Windows 7</title>
		<link>http://temporal.pr0.pl/devblog/2009/10/13/najlepsze-z-dwoch-swiatow-cygwin-vs-services-for-unix-based-applications-pod-windows-7/</link>
		<comments>http://temporal.pr0.pl/devblog/2009/10/13/najlepsze-z-dwoch-swiatow-cygwin-vs-services-for-unix-based-applications-pod-windows-7/#comments</comments>
		<pubDate>Tue, 13 Oct 2009 07:11:44 +0000</pubDate>
		<dc:creator>Jacek Złydach</dc:creator>
				<category><![CDATA[Informatyka]]></category>
		<category><![CDATA[Cygwin]]></category>
		<category><![CDATA[SUA]]></category>
		<category><![CDATA[Unix]]></category>
		<category><![CDATA[Vista]]></category>
		<category><![CDATA[Windows]]></category>

		<guid isPermaLink="false">http://temporal.pr0.pl/devblog/?p=723</guid>
		<description><![CDATA[Wykorzystuj moc powłoki
Powyższa rada pochodząca z &#8220;Pragmatycznego Programisty&#8221; zapewne jest oczywista dla użytkowników systemu UNIX, jednak osoby pracujące pod Windowsem często nie zdają sobie sprawy, jak wielkim usprawnieniem jest dobry zestaw narzędzi konsolowych. Powszechnie wiadomo, że procesor poleceń CMD.EXE nie grzeszy funkcjonalnością, jednak istnieją sposoby poszerzenia możliwości systemu Windows w zakresie aplikacji konsolowych.
Użytkownicy wersji Enterprise [...]]]></description>
			<content:encoded><![CDATA[<blockquote><p>Wykorzystuj moc powłoki</p></blockquote>
<p>Powyższa rada pochodząca z <em><a href="http://merlin.pl/Pragmatyczny-programista-Od-czeladnika-do-mistrza_Andrew-Hunt-David-Thomas/browse/product/1,299928.html">&#8220;Pragmatycznego Programisty&#8221;</a></em> zapewne jest oczywista dla użytkowników systemu UNIX, jednak osoby pracujące pod Windowsem często nie zdają sobie sprawy, jak wielkim usprawnieniem jest dobry zestaw narzędzi konsolowych. Powszechnie wiadomo, że procesor poleceń CMD.EXE nie grzeszy funkcjonalnością, jednak istnieją sposoby poszerzenia możliwości systemu Windows w zakresie aplikacji konsolowych.</p>
<p>Użytkownicy wersji Enterprise lub wyższych systemu Windows Vista i Windows 7 dysponują funkcją <a href="http://en.wikipedia.org/wiki/Subsystem_for_UNIX-based_Applications">Subsystem for Unix-based Applications</a> (w skrócie SUA, znane też jako SFU lub Interix). Ten element systemu komunikuje się bezpośrednio z jądrem systemu Windows i pozwala aplikacjom Uniksowym działać obok zwykłych aplikacji systemu Windows. Ponieważ API Uniksa działa tutaj równolegle do WinAPI można powiedzieć, że system rozdwaja się i po części staje się Uniksem &#8211; narzędzia z tego systemu działają na Windowsie natywnie, bez pośredniej emulacji.</p>
<p><a href="http://temporal.pr0.pl/devblog/download/posts/SUA/sua.png"><img src="http://temporal.pr0.pl/devblog/download/posts/SUA/sua-450.png" alt="SUA pod Windows 7" /></a><br />
<em>SUA pod Windows 7 radzi sobie zarówno w tradycyjnej konsoli jak i z aplikacjami X-Window.</em></p>
<p>Po aktywacji i ściągnięciu potrzebnego pakietu SUA zawiera jedynie podstawowy zestaw narzędzi. Całą resztę &#8211; w sumie ponad 400 różnych programów &#8211; możemy pobrać ze strony <a href="http://www.suacommunity.com/">SUA Community</a>. Wśród dostępnych aplikacji znajdziemy m.in. ls, awk, grep, perl, ssh, xterm czy vim. SUA nie zawiera serwera X &#8211; ten ostatni musimy ściągnąć sami. Istnieją darmowe i płatne alternatywy; ja obecnie korzystam z <a href="http://www.straightrunning.com/XmingNotes/">Xming</a>.</p>
<p>Użytkownicy innych wersji systemu Windows &#8217;skazani&#8217; są na <a href="http://pl.wikipedia.org/wiki/Cygwin">pakiet Cygwin</a>. Korzystałem z niego pod Windows 2000 i Windows 2003 Server; pakiet ten spisywał się znakomicie. W dużym skrócie, Cygwin to zestaw DLLek emulujących interfejs unikowych bibliotek C i zapewniający kompatybilność z <a href="http://en.wikipedia.org/wiki/POSIX">POSIX</a>.  W oparciu o nie skompilowano całą masę przeróżnych narzędzi unikowych &#8211; począwszy od <a href="http://en.wikipedia.org/wiki/Coreutils">coreutils</a> i <a href="http://en.wikipedia.org/wiki/GNU_Binary_Utilities">binutils</a>, przez interpretery Perla, Pythona, kompilator TeX, na narzędziach i Window Managerach dla X-Window skończywszy. Dostępnych składników systemu jest wielokrotnie więcej niż w przypadku SUA. Całość wyposażona jest w dość wygodny (aczkolwiek <a href="http://pl.wikipedia.org/wiki/Plik:Cygwin-setup.png">niezbyt prosty w obsłudze</a>) instalator pozwalający w dowolnej chwili aktualizować lub wgrywać nowe pakiety.</p>
<p><a href="http://temporal.pr0.pl/devblog/download/posts/SUA/skrin.png"><img src="http://temporal.pr0.pl/devblog/download/posts/SUA/skrin-450.png" alt="Cygwin pod Windows 2000" /></a><br />
<em>Xterm&#8217;y Cygwina pracujące równolegle z aplikacjami Windows 2000.</em></p>
<p><a href="http://temporal.pr0.pl/devblog/download/posts/SUA/iridium.png"><img src="http://temporal.pr0.pl/devblog/download/posts/SUA/iridium-450.png" alt="Konstelacja Iridium w aplikacji pod Cygwinem" /></a><br />
<em>Aplikacja X-Window składająca się z dwóch programów nie wchodzących w skład pakietu Cygwin, lecz ściągniętych i skompilowanych osobno ze źródeł.</em></p>
<p>Używałem Cygwina przez liceum oraz początek studiów i mogę powiedzieć, że &#8211; po odrobinie zabawy w upiększanie i dostosowywanie &#8211; jest to wspaniałe narzędzie. Niestety, pod systemem Windows 7 występuje poważny problem z działaniem aplikacji Cygwinowych &#8211; zgaduję, że jest to spowodowane randomizacją przestrzeni adresowej wprowadzoną wraz z Windows Vista. Częstość i przypadkowość awarii praktycznie dyskwalifikuje Cygwina jako narzędzie pod Windows 7; chyba, że ktoś zna metodę jak doprowadzić produkt Cygnusa do ładu.</p>
<p>Cechą wspólną obydwu pakietów jest konieczność rekompilacji każdego dodatkowego narzędzia, którego zechcemy używać &#8211; uniksowe binarki nie mogą &#8216;tak po prostu&#8217; uruchamiać się pod Windowsem. Ponadto domyślnie oba posiadają nieaktualne zestawy narzędzi &#8211; na przykład GCC starsze niż kierunek, na którym studiuję. Wybija się tutaj SUA &#8211; narzędzia ściągane z SUA Community są stosunkowo nowe. Pod Cygwinem jednak dostępnych narzędzi jest dużo więcej &#8211; wliczając brakujący w SUA serwer X. W obecnej chwili mam też małe problemy z uruchomieniem kolorowania kodami ANSI Escape w xterm&#8217;ie pod SUA &#8211; z Cygwinem nie było tego problemu.</p>
<p>Alternatywą dla powyższych dwóch rozwiązań jest pakiet <a href="http://ppt.sourceforge.net/">Perl Power Tools</a> będący implementacją podstawowych narzędzi Uniksa w języku Perl. Inną opcją jest też pakiet <a href="http://en.wikipedia.org/wiki/UWIN">UWIN</a>. Pod Windowsem mamy też oczywiście <a href="http://en.wikipedia.org/wiki/PowerShell">PowerShell&#8217;a</a>; jest to narzędzie oparte o zupełnie inne założenia niż system Unix. Różnica ta daje mu możliwości, z którymi warto się zapoznać.</p>
<p>Ktoś mógłby zapytać: dlaczego nie zainstalować Linuksa na wirtualnej maszynie? Otóż nawet istnienie współdzielonych folderów nie daje tej swobody użycia narzędzi UNIX przy pracy nad projektami w systemie Windows. W przypadku wirtualnej maszyny mamy wyraźne rozdzielenie systemu-gospodarza i systemu-gościa; mieszanie funkcjonalności obu systemów przy pracy nad jednym projektem, choć technicznie możliwe, jest dosyć skomplikowane.</p>
<p>Chociaż SUA w obecnej chwili wymaga Windowsów w wersji dostępnej dla niewielu, warto być świadomym istnienia tego pakietu &#8211; może przyjść czas, w którym będzie on dostępny także na tańszych wersjach systemu, może też przyjdzie zetknąć się z nim w pracy zawodowej. Niezależnie od tego, które z omówionych narzędzi jest dla nas dostępne warto zastanowić się, czy nasze obecne i przyszłe projekty nie mogłyby skorzystać z potęgi narzędzi Uniksowych pod systemem Windows.</p>
<p>PS. Tak, przesiadłem się na Windows 7 <img src='http://temporal.pr0.pl/devblog/wp-includes/images/smilies/icon_smile.gif' alt=':)' class='wp-smiley' /> .</p>
]]></content:encoded>
			<wfw:commentRss>http://temporal.pr0.pl/devblog/2009/10/13/najlepsze-z-dwoch-swiatow-cygwin-vs-services-for-unix-based-applications-pod-windows-7/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>REPL i PHP &#8211; czyli Telnetem do rakiety :)</title>
		<link>http://temporal.pr0.pl/devblog/2009/09/15/repl-i-php-czyli-telnetem-do-rakiety/</link>
		<comments>http://temporal.pr0.pl/devblog/2009/09/15/repl-i-php-czyli-telnetem-do-rakiety/#comments</comments>
		<pubDate>Tue, 15 Sep 2009 14:01:00 +0000</pubDate>
		<dc:creator>Jacek Złydach</dc:creator>
				<category><![CDATA[Informatyka]]></category>
		<category><![CDATA[Pragmatyzm]]></category>
		<category><![CDATA[Lisp]]></category>
		<category><![CDATA[narzędzia]]></category>
		<category><![CDATA[Perl]]></category>
		<category><![CDATA[PHP]]></category>
		<category><![CDATA[PHP Interactive]]></category>
		<category><![CDATA[phpa]]></category>
		<category><![CDATA[phpsh]]></category>
		<category><![CDATA[Python]]></category>
		<category><![CDATA[REPL]]></category>
		<category><![CDATA[Ruby]]></category>
		<category><![CDATA[webmasterka]]></category>

		<guid isPermaLink="false">http://temporal.pr0.pl/devblog/?p=700</guid>
		<description><![CDATA[
Telneting into your rocket is sort of fundamentally cool.

Wiele języków &#8211; Lisp, Python, Perl czy Ruby posiadają tzw. pętlę wczytaj-wykonaj-wypisz &#8211; z angielskiego Read-Eval-Print Loop, czyli w skrócie REPL. Chodzi oczywiście o tryb interaktywny, w którym możemy wpisywać wyrażenia w danym języku, które są natychmiast wykonywane a rezultaty działania zwracane. Poza oczywistym zastosowaniem jakim jest [...]]]></description>
			<content:encoded><![CDATA[<blockquote cite="http://www.armadilloaerospace.com/n.x/Armadillo/Home/News?news_id=84"><p>
Telneting into your rocket is sort of fundamentally cool.
</p></blockquote>
<p>Wiele języków &#8211; Lisp, Python, Perl czy Ruby posiadają tzw. <a href="http://pl.wikipedia.org/wiki/REPL">pętlę wczytaj-wykonaj-wypisz</a> &#8211; z angielskiego <a href="http://en.wikipedia.org/wiki/REPL">Read-Eval-Print Loop</a>, czyli w skrócie REPL. Chodzi oczywiście o tryb interaktywny, w którym możemy wpisywać wyrażenia w danym języku, które są natychmiast wykonywane a rezultaty działania zwracane. Poza oczywistym zastosowaniem jakim jest mądrzejszy kalkulator <img src='http://temporal.pr0.pl/devblog/wp-includes/images/smilies/icon_smile.gif' alt=':)' class='wp-smiley' />  REPL może przydawać się też do debugowania kodu, często pracującego. Python ma nawet <a href="http://datamech.com/devan/trypython/trypython.py">swojego on-line REPLa</a> do wypróbowania <img src='http://temporal.pr0.pl/devblog/wp-includes/images/smilies/icon_smile.gif' alt=':)' class='wp-smiley' />  .</p>
<p>PHP jest językiem, na którego temat można znaleźć <a href="http://www.devblogi.pl/2009/09/php-to-badziew-ale-to-nie-ma-znaczenia.html">bardzo wiele negatywnych opinii</a> &#8211; jednak pomimo tego i tak jest szeroko wykorzystywany do tworzenia aplikacji webowych. Biorąc pod uwagę specyfikę działania skryptów PHP &#8211; są one wykonywane od nowa &#8216;na czysto&#8217; przy każdym zapytaniu HTTP &#8211; REPL mógłby być dla tego języka przydatnym narzędziem; szkoda tylko, że autorzy tego nie uwzględnili (ściślej rzecz ujmując PHP posiada <a href="http://blog.thinkphp.de/archives/44-More-PHP-power-on-the-command-line.html">tryb interaktywny</a> wywoływany parametrem <code class="codecolorer text default"><span class="text">-a</span></code>, ale z bliżej mi nieznanych powodów tryb ten jest <a href="http://onwebdevelopment.blogspot.com/2008/03/php-interactive-shell.html">raczej</a> <a href="http://cow.neondragon.net/index.php/945-Php-Interactive-Mode">krytykowany</a>).</p>
<p>Podczas opracowywania <a href="http://temporal.pr0.pl/devblog/2009/09/14/eksperyment-podsumowanie/">wyników Eksperymentu</a> powstał problem &#8211; jak pracować na danych, których samo wyciągnięcie z bazy i przetworzenie zajmuje (na localhost&#8217;cie) ok. 1.5 minuty? Zwłaszcza kiedy jeszcze na początku nie wie się, co się chce osiągnąć? W takich sytuacjach przydaje się REPL &#8211; i <strong>na szczęście takowy dla PHP został stworzony</strong>.</p>
<p><strong><a href="http://www.programmersparadox.com/2008/08/26/php-repl/">phpsh</a></strong> to projekt Facebook&#8217;a, będący Open-Source i napisany głównie&#8230; w Pythonie. Szczegóły pod adresem:<br />
<a href="http://www.phpsh.org/">http://www.phpsh.org/</a> Całość wykonana jest bardzo ładnie i dobrze wykorzystuje możliwość wyświetlania w konsoli kolorowego tekstu. Po rozpakowaniu na serwerze działa po prostu &#8216;z marszu&#8217; <img src='http://temporal.pr0.pl/devblog/wp-includes/images/smilies/icon_smile.gif' alt=':)' class='wp-smiley' /> &nbsp;.</p>
<p>Dalsze poszukiwania pozwoliły znaleźć trzy kolejne projekty: <strong><a href="http://jan.kneschke.de/projects/php-shell/">php shell</a></strong>, <strong><a href="http://david.acz.org/phpa/">phpa</a></strong> oraz pozwalający na zdalną pracę przez przeglądarkę (i potrafiący wyświetlać wyjście w HTMLu) <strong><a href="http://www.hping.org/phpinteractive/">PHP Interactive</a></strong>. Niech więc każdy wybierze co lubi (ja zamierzam raczej zmienić język <img src='http://temporal.pr0.pl/devblog/wp-includes/images/smilies/icon_wink.gif' alt=';)' class='wp-smiley' /> &nbsp;).</p>
<p><a href="http://www.programmersparadox.com/2008/01/22/your-first-programming-language-needs-a-repl/">Przydatność</a> narzędzia jakim jest REPL jest nieoceniona, wypadałoby <a href="http://www.flownet.com/gat/jpl-lisp.html">zacytować</a> pracownika <a href="http://www.jpl.nasa.gov">NASA JPL</a> dotyczący awarii na pokładzie sterowanego zdalnie pojazdu kosmicznego:</p>
<blockquote><p>
Debugging a program running on a $100M piece of hardware that is 100 million miles away is an interesting experience. Having a read-eval-print loop running on the spacecraft proved invaluable in finding and fixing the problem.
</p></blockquote>
<p><em>Edit 15.09.2009 17:39</em><br />
<a href="http://rav.rootnode.net">Fus</a> donosi, że nawet <a href="http://www.mono-project.com/CsharpRepl">C# ma swojego REPL&#8217;a</a>. Podjęte też zostały próby stworzenia takiego narzędzia <a href="http://www.google.pl/search?q=C%2B%2B+repl">dla C i C++</a>.</p>
]]></content:encoded>
			<wfw:commentRss>http://temporal.pr0.pl/devblog/2009/09/15/repl-i-php-czyli-telnetem-do-rakiety/feed/</wfw:commentRss>
		<slash:comments>1</slash:comments>
		</item>
		<item>
		<title>Eksperyment &#8211; podsumowanie</title>
		<link>http://temporal.pr0.pl/devblog/2009/09/14/eksperyment-podsumowanie/</link>
		<comments>http://temporal.pr0.pl/devblog/2009/09/14/eksperyment-podsumowanie/#comments</comments>
		<pubDate>Mon, 14 Sep 2009 03:35:30 +0000</pubDate>
		<dc:creator>Jacek Złydach</dc:creator>
				<category><![CDATA[Informatyka]]></category>
		<category><![CDATA[badania]]></category>
		<category><![CDATA[dobro Galaktyki]]></category>
		<category><![CDATA[eksperyment]]></category>
		<category><![CDATA[HTML]]></category>
		<category><![CDATA[HTTP]]></category>
		<category><![CDATA[PHP]]></category>
		<category><![CDATA[webmasterka]]></category>

		<guid isPermaLink="false">http://temporal.pr0.pl/devblog/?p=664</guid>
		<description><![CDATA[W tym wpisie znajdują się wyczekiwane przez niektórych wyniki Eksperymentu HTTP. Celem całej tej zabawy było odpowiedzenie sobie na następujące pytanie:
Czy jest jakiś sposób, żeby odróżnić zapytanie o zasób osadzony na stronie od &#8216;normalnego&#8217; zapytania?
Inaczej &#8211; czy da się na przykład rozróżnić, kiedy przeglądarka pyta o obrazek osadzony za pomocą &#60;img src=... /&#62;, a kiedy [...]]]></description>
			<content:encoded><![CDATA[<p>W tym wpisie znajdują się wyczekiwane przez niektórych wyniki <a href="http://temporal.pr0.pl/devblog/2009/09/09/http-eksperyment/">Eksperymentu HTTP</a>. Celem całej tej zabawy było odpowiedzenie sobie na następujące pytanie:<br />
<strong>Czy jest jakiś sposób, żeby odróżnić zapytanie o zasób osadzony na stronie od &#8216;normalnego&#8217; zapytania?</strong><br />
Inaczej &#8211; czy da się na przykład rozróżnić, kiedy przeglądarka pyta o obrazek osadzony za pomocą <code class="codecolorer html4strict default"><span class="html4strict"><span style="color: #009900;">&lt;<a href="http://december.com/html/4/element/img.html"><span style="color: #000000; font-weight: bold;">img</span></a> <span style="color: #000066;">src</span><span style="color: #66cc66;">=</span>... <span style="color: #66cc66;">/</span>&gt;</span></span></code>, a kiedy o sam obrazek, którego adres wpisany został bezpośrednio lub wywołany za pomocą linka? Czy da się odróżnić, kiedy ktoś osadza obrazek na swojej stronie, a kiedy tylko do niego linkuje?</p>
<p>Jedyną rzeczą, która mogłaby zawierać takie informacje jest <a href="http://pl.wikipedia.org/wiki/Hypertext_Transfer_Protocol">zapytanie HTTP</a> wysyłane przez przeglądarkę do serwera. We wstępnych badaniach wykluczyliśmy możliwość użycia <a href="http://pl.wikipedia.org/wiki/HTTP_referrer">nagłówka Referer</a> do rozróżnienia zapytań &#8211; co prawda Referer przy elementach osadzonych ma zwykle wartość odpowiadającą osadzającej stronie, ale taki sam nagłówek uzyskamy klikając w link znajdujący się na takiej stronie. Z pozostałych nagłówków żaden nie ma na celu informować o rodzaju zapytania. Okazuje się jednak, że takie rozpoznanie jest możliwe &#8211; trzeba podejść do sprawy statystycznie. Podejrzenia dość szybko padły na nagłówek Accept&#8230;</p>
<p>Eksperyment, w którym w zeszłym tygodniu około 200 (+/-50) osób wzięło udział pozwolił mi zebrać trochę danych statystycznych. Obiektem zainteresowania było zapytanie HTTP wysyłane przez przeglądarkę przy próbie pobierania obrazka JPG i PNG celem osadzenia go na stronie (&lt;img src=&#8230;) lub bezpośredniego wyświetlenia. W centrum zainteresowania znalazł się nagłówek Accept &#8211; jedyny, który okazuje się przenosić istotne dla nas informacje.</p>
<p><strong>Wyniki</strong><br />
<strong>Nagłówek Accept <a href="http://www.w3.org/Protocols/rfc2616/rfc2616-sec14.html">pozwala przeglądarce określić</a>, jakiego typu multimediów spodziewa się w odpowiedzi na swoje zapytanie. Okazuje się, że przeglądarki spodziewając się elementu do osadzenia na stronie często wysyłają w tym nagłówku inne typy, niż w przypadku obrazków pobieranych do wyświetlenia bezpośredniego.</strong> Spójrzmy na przykład na ten wykres dla przeglądarki Firefox:<br />
<a href="http://temporal.pr0.pl/devblog/download/posts/eksperyment/firefox.png"><br />
<img src="http://temporal.pr0.pl/devblog/download/posts/eksperyment/firefox-450px.png" alt="Wykres przedstawiający wyniki Eksperymentu dla przeglądarki Firefox." /></a></p>
<p>Wykres ten przedstawia szansę wyświetlenia danego wpisu w nagłówku Accept w zapytaniu o obrazek osadzony (EMBEDDED) lub do wyświetlenia bezpośredniego (LINK). Różnica w zawartości nagłówków jest wyraźnie widoczna. Wykres jest znormalizowany &#8211; przeskalowany tak, że wartość 1 odpowiada sytuacji, gdy dany nagłówek wystąpił w każdym zapytaniu danego typu. Okazuje się, że w przypadku Firefoksa rodzaj zapytania mamy jak na dłoni, wystarczy spojrzeć w nagłówek Accept! Przyglądnijmy się więc wykresom dla innych przeglądarek:</p>
<p><a href="http://temporal.pr0.pl/devblog/download/posts/eksperyment/opera.png"><br />
<img src="http://temporal.pr0.pl/devblog/download/posts/eksperyment/opera-450px.png" alt="Wykres przedstawiający wyniki Eksperymentu dla przeglądarki Opera." /></a><br />
Opera nie daje nam najmniejszych szans &#8211; w każdym zapytaniu wysyła identyczny nagłówek Accept.</p>
<p><a href="http://temporal.pr0.pl/devblog/download/posts/eksperyment/ie.png"><br />
<img src="http://temporal.pr0.pl/devblog/download/posts/eksperyment/ie-450px.png" alt="Wykres przedstawiający wyniki Eksperymentu dla przeglądarki Internet Explorer." /></a><br />
Internet Explorer jak zawsze sprawia dużo radości &#8211; z jednej strony odróżnienie rodzaju zapytania zdaje się być trywialnie proste, z drugiej strony IE ma dziwną <a href="http://www.newmediacampaigns.com/page/browser-rest-http-accept-headers">tendencję zasypywania nas specyficznymi wpisami w nagłówku</a>. Najbardziej zabawny jest <code class="codecolorer html4strict default"><span class="html4strict">image/pjpeg</span></code>, który w jednym zapytaniu potrafi wystąpić <strong>dwa razy obok siebie</strong>. Nie rozumiem przyczyn tego zjawiska, ale występuje w wersjach IE od 6 do 8. Ale obiecano mi już, że zostanie to zgłoszone do Microsoftu <img src='http://temporal.pr0.pl/devblog/wp-includes/images/smilies/icon_smile.gif' alt=':)' class='wp-smiley' /> .</p>
<p><a href="http://temporal.pr0.pl/devblog/download/posts/eksperyment/safari.png"><br />
<img src="http://temporal.pr0.pl/devblog/download/posts/eksperyment/safari-450px.png" alt="Wykres przedstawiający wyniki Eksperymentu dla przeglądarki Safari." /></a><br />
Tutaj bardzo prosto &#8211; tak samo jak w IE, zapytania osadzone mają bardzo krótki nagłówek Accept <img src='http://temporal.pr0.pl/devblog/wp-includes/images/smilies/icon_wink.gif' alt=';)' class='wp-smiley' /> </p>
<p><a href="http://temporal.pr0.pl/devblog/download/posts/eksperyment/mozilla.png"><br />
<img src="http://temporal.pr0.pl/devblog/download/posts/eksperyment/mozilla-450px.png" alt="Wykres przedstawiający wyniki Eksperymentu dla przeglądarki Mozilla." /></a><br />
Ten wykres przedstawia przeglądarki przedstawiające się jako Mozilla, które nie zaklasyfikowały się nigdzie indziej. Wykres jest analogiczny do tego od Firefoksa (tak na prawdę część z przeglądarek na tym wykresie to źle rozpoznane Firefoksy &#8211; przyczyny tego zjawiska omawiam dalej). Podobała mi się w tym wszystkim Mozilla, która przedstawiła się jako &#8220;<em>ROBOT DO WYKRADANIA KONTENTU</em>&#8221; <img src='http://temporal.pr0.pl/devblog/wp-includes/images/smilies/icon_smile.gif' alt=':)' class='wp-smiley' />  .</p>
<p><a href="http://temporal.pr0.pl/devblog/download/posts/eksperyment/chrome.png"><br />
<img src="http://temporal.pr0.pl/devblog/download/posts/eksperyment/chrome-450px.png" alt="Wykres przedstawiający wyniki Eksperymentu dla przeglądarki Chrome." /></a><br />
Google Chrome także nie robi problemów przy rozpoznaniu typu zapytania.</p>
<p><a href="http://temporal.pr0.pl/devblog/download/posts/eksperyment/inne.png"><br />
<img src="http://temporal.pr0.pl/devblog/download/posts/eksperyment/inne-450px.png" alt="Wykres przedstawiający wyniki Eksperymentu dla nie sklasyfikowanych przeglądarek." /></a><br />
W przypadku nierozpoznanych przeglądarek sprawa troszkę się zaciemnia, ale wciąż można zidentyfikować przeważające tendencje, które pozwalają rozróżnić rodzaj zapytania.</p>
<p>Dla podsumowania, oto zapytania dla wszystkich przeglądarek na raz:<br />
<a href="http://temporal.pr0.pl/devblog/download/posts/eksperyment/wszystkie.png"><br />
<img src="http://temporal.pr0.pl/devblog/download/posts/eksperyment/wszystkie-450px.png" alt="Wykres przedstawiający wyniki Eksperymentu zbiorczo dla wszystkich przeglądarek." /></a></p>
<p><strong>O samym Eksperymencie</strong><br />
<a href="http://temporal.pr0.pl/devblog/download/posts/eksperyment/przegladarki.png"><br />
<img src="http://temporal.pr0.pl/devblog/download/posts/eksperyment/przegladarki-450px.png" alt="Wykres przedstawiający przeglądarki, które wzięły udział w Eksperymencie." /></a><br />
Powyższy wykres przedstawia wszystkie główne rodziny przeglądarek zidentyfikowane przez skrypty (proszę nie zwracać uwagi na wartości numeryczne &#8211; odnoszą się ilości zapytań wygenerowanych przez daną przeglądarkę). Identyfikacji przeglądarek dokonywała funkcja <a href="http://pl.php.net/manual/pl/function.get-browser.php">get_browser()</a> w PHP. Co prawda funkcja ta dość skutecznie rozdzieliła przeglądarki, jednak mimo wszystko pozostawia wiele do życzenia (mówiąc mniej formalnie &#8211; jest skopana) &#8211; nie radzi sobie z niektórymi wariacjami Firefoksa,  Safari czy Chrome na systemach Apple. Dużo lepiej z deszyfrowaniem nagłówka User-Agent zdaje się radzić sobie jedna <a href="http://www.useragentstring.com/index.php">ze stron w Internecie</a>.</p>
<p>Serdecznie dziękuję wszystkim, którzy poświęcili swój czas i wzięli udział. Bardzo miłym akcentem było wrzucenie linku do Eksperymentu na Wykop. Ponadto dziękuję wszystkim tym, którzy zachęcali znajomych do wzięcia udziału. Pozdrawiam też użytkowników Linksa i Lynxa <img src='http://temporal.pr0.pl/devblog/wp-includes/images/smilies/icon_wink.gif' alt=';)' class='wp-smiley' /> . Szczególne podziękowania dla kolegów ze Stosowanej oraz wszystkich gości z Blip&#8217;a!</p>
<p><strong>Zastosowania</strong><br />
Mając możliwość rozpoznania celu zapytania o dany zasób możemy odpowiednio zareagować. Przykładowe zastosowania tej wiedzy to:</p>
<ul>
<li>Lepsze sprawdzanie, czy ktoś nie <a href="http://pl.wikipedia.org/wiki/Hotlink">hotlinkuje</a> naszych zdjęć/obrazków &#8211; klasyczne używanie nagłówka Referer jest nieskuteczne i denerwujące dla osób korzystających z Google Images.</li>
<li>Serwowanie różnej treści zależnie od rodzaju zapytania &#8211; chyba głównie dla zabawy <img src='http://temporal.pr0.pl/devblog/wp-includes/images/smilies/icon_smile.gif' alt=':)' class='wp-smiley' /> </li>
<li>Wybiórcze stosowanie przekierowań &#8211; serwowanie <a href="http://temporal.pr0.pl/devblog/2009/09/10/przekierowania-skracanie-i-ukrywanie-adresow-co-i-jak/">ramek maskujących adres</a> w przypadku zapytania bezpośredniego oraz używanie np. przekierowania proxy w przypadku zapytań osadzonych.</li>
</ul>
<p><strong>Proof of concept</strong><br />
Miał być, ale nie ma &#8211; próbując z Paszczakiem zaktualizować browsercaps.ini na serwerze coś zepsuliśmy <img src='http://temporal.pr0.pl/devblog/wp-includes/images/smilies/icon_wink.gif' alt=';)' class='wp-smiley' /> . Z tego powodu na razie przykładu działania nie będzie &#8211; dość powiedzieć, że u mnie lokalnie działa <img src='http://temporal.pr0.pl/devblog/wp-includes/images/smilies/icon_smile.gif' alt=':)' class='wp-smiley' /> . Na podstawie zebranych danych <a href="http://temporal.pr0.pl/devblog/code-snippets/#CODE_SNIPPETS_HTTP_EKSPERYMENT_DATA">wygenerowałem tabelkę w PHP</a> pozwalającą napisać sobie skrypt rozpoznający rodzaj zapytania.</p>
<p><strong>Co dalej?</strong><br />
Powstają coraz to nowe wersje przeglądarek, a wraz z nimi prawdopodobnie będzie zmieniać się zawartość nagłówka Accept. Można spróbować stworzyć system rozpoznawania zapytania oparty o <a href="http://en.wikipedia.org/wiki/Naive_Bayesian_classifier">filtr bayesowski</a> lub wykorzystać inne metody pozwalające na bieżąco aktualizować stan wiedzy na temat używanych wartości nagłówków.<br />
Danych, które zebrałem nie było strasznie dużo, ale jeżeli ktoś chce poddać je dalszej analizie to chętnie je udostępnię <img src='http://temporal.pr0.pl/devblog/wp-includes/images/smilies/icon_smile.gif' alt=':)' class='wp-smiley' />  .</p>
<p><em>Edit</em><br />
Dla wytrwałych bajka o <a href="http://webaim.org/blog/user-agent-string-history/">zdecydowanie pokręconych stringach User Agent</a> <img src='http://temporal.pr0.pl/devblog/wp-includes/images/smilies/icon_smile.gif' alt=':)' class='wp-smiley' /> </p>
<p><em>Edit 2</em><br />
Wykresy, o które prosił dr_bonzo:<br />
<del datetime="2010-07-27T08:34:15+00:00"><a href="http://temporal.pr0.pl/blog/materialy/posty/eksperyment/odwrocone">http://temporal.pr0.pl/blog/materialy/posty/eksperyment/odwrocone</a><br />
Czytelniej ? <img src='http://temporal.pr0.pl/devblog/wp-includes/images/smilies/icon_smile.gif' alt=':)' class='wp-smiley' /> </del><ins datetime="2010-07-27T08:34:15+00:00">zginęły przy zmianie serwera, powinny być gdzieś w backupie.</ins></p>
]]></content:encoded>
			<wfw:commentRss>http://temporal.pr0.pl/devblog/2009/09/14/eksperyment-podsumowanie/feed/</wfw:commentRss>
		<slash:comments>7</slash:comments>
		</item>
		<item>
		<title>Przekierowania, skracanie i ukrywanie adresów &#8211; co i jak?</title>
		<link>http://temporal.pr0.pl/devblog/2009/09/10/przekierowania-skracanie-i-ukrywanie-adresow-co-i-jak/</link>
		<comments>http://temporal.pr0.pl/devblog/2009/09/10/przekierowania-skracanie-i-ukrywanie-adresow-co-i-jak/#comments</comments>
		<pubDate>Thu, 10 Sep 2009 09:30:48 +0000</pubDate>
		<dc:creator>Jacek Złydach</dc:creator>
				<category><![CDATA[Informatyka]]></category>
		<category><![CDATA[eksperyment]]></category>
		<category><![CDATA[Google]]></category>
		<category><![CDATA[HTML]]></category>
		<category><![CDATA[HTTP]]></category>
		<category><![CDATA[JavaScript]]></category>
		<category><![CDATA[mod_rewrite]]></category>
		<category><![CDATA[PHP]]></category>
		<category><![CDATA[porady]]></category>
		<category><![CDATA[SEO]]></category>
		<category><![CDATA[skracanie adresu]]></category>
		<category><![CDATA[webmasterka]]></category>

		<guid isPermaLink="false">http://temporal.pr0.pl/devblog/?p=632</guid>
		<description><![CDATA[W ostatnim okresie upowszechniły się serwisy skracające adresy, takie jak tnij.org, tinyurl.com czy działający wewnątrz Blipa rdir.pl. W tym wpisie prezentuję techniki leżące u podstaw takich usług &#8211; metody przekierowywania przeglądarek i ukrywania adresów. Ponieważ &#8217;serwis skrótowy&#8217; jest jednym z elementów projektu, nad którym pracuję, poniższy opis jest de-facto spojrzenie z perspektywy budowania usługi skracania [...]]]></description>
			<content:encoded><![CDATA[<p>W ostatnim okresie upowszechniły się serwisy skracające adresy, takie jak <a href="http://tnij.org/">tnij.org</a>, <a href="http://tinyurl.com/">tinyurl.com</a> czy działający wewnątrz <a href="http://blip.pl/">Blipa</a> rdir.pl. W tym wpisie prezentuję techniki leżące u podstaw takich usług &#8211; metody przekierowywania przeglądarek i ukrywania adresów. Ponieważ &#8217;serwis skrótowy&#8217; jest jednym z elementów projektu, nad którym pracuję, poniższy opis jest de-facto spojrzenie z perspektywy budowania usługi skracania adresów. Na koniec wspomnę też kilka słów o toczącym się <a href="http://temporal.pr0.pl/devblog/2009/09/09/http-eksperyment/">Eksperymencie HTTP</a>.</p>
<p><strong>mod_rewrite i przepisywanie URL</strong><br />
Kluczem do stworzenia systemu <a href="http://pl.wikipedia.org/wiki/Skracanie_adres%C3%B3w_internetowych">skracania adresów</a> jest możliwość &#8216;przepisywania adresów&#8217; &#8211; dzięki temu nasz system będzie umiał obsłużyć adresy postaci: <code class="codecolorer text default"><span class="text">http://moj.system.skrotow.pl/skroconyurl</span></code>. Do tego celu można wykorzystać na przykład bardzo popularny moduł mod_rewrite serwera Apache. Krótko i konkretnie temat &#8216;ładnych linków&#8217; <a href="http://pornel.net/dobrelinki">omówił na swojej stornie porneL</a>. Przykład .htaccess, którego obecnie używam <em>(nazwy związane z serwisem zmienione <img src='http://temporal.pr0.pl/devblog/wp-includes/images/smilies/icon_wink.gif' alt=';)' class='wp-smiley' />  )</em>:</p>
<div class="codecolorer-container text default" style="overflow:auto;white-space:nowrap;border:1px solid #9F9F9F;width:435px;"><div class="text codecolorer" style="padding:5px;font:normal 12px/1.4em Monaco, Lucida Console, monospace;white-space:nowrap">#&lt;IfModule mod_rewrite.c&gt;<br />
<br />
RewriteEngine On<br />
RewriteBase /ACME/skrypcik/<br />
<br />
#add trailing slash (url canonicalization)<br />
RewriteCond %{REQUEST_FILENAME} &nbsp; &nbsp; -d<br />
RewriteRule &nbsp; &nbsp; ^(.+[^/])$&nbsp; &nbsp; &nbsp; $1/ &nbsp; &nbsp; [R=301,L]<br />
<br />
RewriteCond &nbsp;%{REQUEST_FILENAME} !-f<br />
RewriteCond &nbsp;%{REQUEST_FILENAME} !-d<br />
RewriteRule &nbsp; &nbsp; ^(.*)$&nbsp; &nbsp; &nbsp; index.php?adres=$1&nbsp; &nbsp; &nbsp; [NC,QSA,L]<br />
<br />
#&lt;/IfModule&gt;</div></div>
<p>Występuje tu kilka rzeczy, których nie omówił jeszcze porneL. Po pierwsze, dyrektywa <code class="codecolorer text default"><span class="text">RewriteBase</span></code> &#8211; pomaga ona w poprawnym działaniu przepisywania adresów w przypadku, gdy nasza strona znajduje się w podkatalogu na serwerze. Z tą dyrektywą jest zwykle trochę zabawy, więc proszę okazywać cierpliwość <img src='http://temporal.pr0.pl/devblog/wp-includes/images/smilies/icon_wink.gif' alt=';)' class='wp-smiley' /> . Nie znam prostego (w kilku zdaniach) wyjaśnienia jej roli &#8211; jeżeli ktoś umie takowe sformułować, to zachęcam do uczynienia tego w komentarzu!</p>
<p>Po <code class="codecolorer text default"><span class="text">RewriteBase</span></code> mamy dwie linie dokonujące usuwania slashy z URI w ramach procesu przekształcania adresu do postaci kanonicznej. Istotne (<a href="http://www.mattcutts.com/blog/seo-advice-url-canonicalization/">zwłaszcza dla Google</a>) jest tutaj przekierowanie 301. Kolejne trzy linijki sprawdzają, czy żądany adres nie jest fizycznie istniejącym plikiem lub katalogiem. Podobny kod można na przykład znaleźć w .htaccess Wordpressa. Jeżeli żądany adres nie pasuje do żadnego istniejącego pliku lub katalogu na serwerze, to wywoływany jest nasz skrypt (index.php) z parametrem adres zawierającym całą końcówkę wpisaną przez użytkownika.</p>
<p>To tyle tytułem wprowadzenia do .htaccess na praktycznym przykładzie &#8211; na temat tego modułu jest <a href="http://home.pl/dokumentacja/funkcjeserwera/htaccess/modrewrite">bardzo</a> <a href="http://sf.jogger.pl/2007/05/02/mod-rewrite-w-przykladach/">dużo</a> <a href="http://httpd.apache.org/docs/1.3/mod/mod_rewrite.html">materiałów</a> <a href="http://nnplaya.pl/wpisy/mod_rewrite_a_sciezki_do_plikow">w sieci</a> &#8211; myślę, że każdy sobie poradzi. Mając już adres wpisany przez użytkownika należy jakoś odesłać mu właściwą treść. Możemy to zrobić na kilka sposobów:</p>
<p><strong>Przekierowania HTTP</strong><br />
Przekierowania te <a href="http://temporal.pr0.pl/devblog/2009/09/08/przekierowania-http/">dość dokładnie omawiałem w jednym z ostatnich postów</a>. Jest to najbardziej podstawowy sposób oddania komuś żądanego zasobu ze &#8217;skróconego&#8217; (przez termin &#8217;skrócony adres&#8217; w tym tekście rozumiem każdej długości alias w serwisie skrótowym &#8211; nawet, jeśli jest dłuższy od oryginalnego URL <img src='http://temporal.pr0.pl/devblog/wp-includes/images/smilies/icon_smile.gif' alt=':)' class='wp-smiley' />  ) adresu. Wybór kodu powinien zależeć od tego, jaką rolę pełni skrócony adres &#8211; 301 gdy zdecydujemy się przypisać go na stałe do miejsca docelowego, 302 lub 307, gdy adres docelowy może ulec zmianie.<br />
Właściwości tej metody to:</p>
<ul>
<li>Takiego przekierowania można używać także do elementów osadzanych, np. w tagach &lt;img&gt;</li>
<li>Nie można zamaskować adresu docelowego &#8211; jest on widoczny w pasku adresu przeglądarki.</li>
<li>Zwłaszcza w przypadku użycia kodu 301 PageRank przelewa się na adres docelowy (<a href="http://www.google.com/support/webmasters/bin/answer.py?hl=en&#038;answer=93633">ale ostrożnie z tym</a>).</li>
<li>Opiera się w całości na protokole HTTP, więc musi być wspierana przez wszystkie przeglądarki.</li>
</ul>
<p>Ciekawostka &#8211; serwis tnij.org zdaje się odsyłać nagłówek 301 Moved Permanently, a nie 302 Found lub 307 Temporary Redirect.</p>
<p><strong>Przekierowania &#8220;meta refresh&#8221;</strong><br />
Innym rodzajem przekierowania, wykonywanym całkowicie po stronie klienta, jest wymuszenie odświeżenia adresu przez przeglądarkę przy użyciu znacznika <code class="codecolorer html4strict default"><span class="html4strict"><span style="color: #009900;">&lt;<a href="http://december.com/html/4/element/meta.html"><span style="color: #000000; font-weight: bold;">meta</span></a>&gt;</span></span></code>. Przykładowy kod wygląda następująco:</p>
<div class="codecolorer-container html4strict default" style="overflow:auto;white-space:nowrap;border:1px solid #9F9F9F;width:435px;"><div class="html4strict codecolorer" style="padding:5px;font:normal 12px/1.4em Monaco, Lucida Console, monospace;white-space:nowrap"><span style="color: #009900;">&lt;<a href="http://december.com/html/4/element/html.html"><span style="color: #000000; font-weight: bold;">html</span></a>&gt;</span><br />
&nbsp;<span style="color: #009900;">&lt;<a href="http://december.com/html/4/element/head.html"><span style="color: #000000; font-weight: bold;">head</span></a>&gt;</span><br />
&nbsp; <span style="color: #009900;">&lt;<a href="http://december.com/html/4/element/meta.html"><span style="color: #000000; font-weight: bold;">meta</span></a> <span style="color: #000066;">http-equiv</span><span style="color: #66cc66;">=</span><span style="color: #ff0000;">&quot;Refresh&quot;</span> <span style="color: #000066;">content</span><span style="color: #66cc66;">=</span><span style="color: #ff0000;">&quot;0; url=http://www.innastrona.com/&quot;</span>&gt;</span><br />
&nbsp;<span style="color: #009900;">&lt;<span style="color: #66cc66;">/</span><a href="http://december.com/html/4/element/head.html"><span style="color: #000000; font-weight: bold;">head</span></a>&gt;</span><br />
&nbsp;<span style="color: #009900;">&lt;<a href="http://december.com/html/4/element/body.html"><span style="color: #000000; font-weight: bold;">body</span></a>&gt;</span><br />
&nbsp; <span style="color: #009900;">&lt;<a href="http://december.com/html/4/element/p.html"><span style="color: #000000; font-weight: bold;">p</span></a>&gt;</span>Proszę, kliknij w <span style="color: #009900;">&lt;<a href="http://december.com/html/4/element/a.html"><span style="color: #000000; font-weight: bold;">a</span></a> <span style="color: #000066;">href</span><span style="color: #66cc66;">=</span><span style="color: #ff0000;">&quot;http://www.innastrona.com/&quot;</span>&gt;</span>link<span style="color: #009900;">&lt;<span style="color: #66cc66;">/</span><a href="http://december.com/html/4/element/a.html"><span style="color: #000000; font-weight: bold;">a</span></a>&gt;</span>!<span style="color: #009900;">&lt;<span style="color: #66cc66;">/</span><a href="http://december.com/html/4/element/p.html"><span style="color: #000000; font-weight: bold;">p</span></a>&gt;</span><br />
&nbsp;<span style="color: #009900;">&lt;<span style="color: #66cc66;">/</span><a href="http://december.com/html/4/element/body.html"><span style="color: #000000; font-weight: bold;">body</span></a>&gt;</span><br />
<span style="color: #009900;">&lt;<span style="color: #66cc66;">/</span><a href="http://december.com/html/4/element/html.html"><span style="color: #000000; font-weight: bold;">html</span></a>&gt;</span></div></div>
<p>Generujemy taki kod, podstawiając odpowiedni adres. Cyfra 0 może zostać zastąpiona inną &#8211; określa ona czas w sekundach, po jakim przeglądarka powinna dokonać odświeżenia strony z nowym adresem.<br />
Własności tej metody:</p>
<ul>
<li>Nie można zamaskować adresu docelowego &#8211; jest on widoczny w pasku adresu przeglądarki.</li>
<li><a href="http://sebastians-pamphlets.com/google-and-yahoo-treat-undelayed-meta-refresh-as-301-redirect/">Chodzą wieści</a>, że Google umie czytać ten typ przekierowania z kodu HTML &#8211; ale na rewelacyjny przelew PageRank bym nie liczył.</li>
<li>Może nie być wspierane przez wszystkie przeglądarki. Dlatego też powinno się umieścić w dokumencie informację o linku dla przeglądarek nie wspierających tej metody.</li>
<li>Znikoma przydatność.</li>
</ul>
<p>Ponieważ w tym przypadku znacznik <code class="codecolorer html4strict default"><span class="html4strict"><span style="color: #009900;">&lt;<a href="http://december.com/html/4/element/meta.html"><span style="color: #000000; font-weight: bold;">meta</span></a>&gt;</span></span></code> nadpisuje istniejący w HTTP nagłówek Refresh, istnieje też wariant tej metody nie wymagający umieszczania dodatkowego znacznika w dokumencie HTML &#8211; możemy zamiast tego wysłać dowolny HTML i wygenerować odpowiedni nagłówek HTTP w skrypcie. Przykład:</p>
<div class="codecolorer-container php default" style="overflow:auto;white-space:nowrap;border:1px solid #9F9F9F;width:435px;"><div class="php codecolorer" style="padding:5px;font:normal 12px/1.4em Monaco, Lucida Console, monospace;white-space:nowrap"><span style="color: #000000; font-weight: bold;">&lt;?php</span><br />
<a href="http://www.php.net/header"><span style="color: #990000;">Header</span></a><span style="color: #009900;">&#40;</span><span style="color: #0000ff;">'Refresh: 0; url=http://www.innastrona.com'</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span><br />
<span style="color: #b1b100;">echo</span> <span style="color: #0000ff;">'Proszę kliknąć w &lt;a href=&quot;http://www.innastrona.con&quot;&gt;link&lt;/a&gt;.'</span><span style="color: #339933;">;</span><br />
<span style="color: #000000; font-weight: bold;">?&gt;</span></div></div>
<p>Osobiście ciekawi mnie, jak przeglądarka zareagowałaby w przypadku zapytania o osadzony element <code class="codecolorer html4strict default"><span class="html4strict">(<span style="color: #009900;">&lt;<a href="http://december.com/html/4/element/img.html"><span style="color: #000000; font-weight: bold;">img</span></a> <span style="color: #000066;">src</span><span style="color: #66cc66;">=</span><span style="color: #ff0000;">&quot;... &gt;</span></span>)</span></code>, gdyby odesłać jej obrazek razem z nagłówkiem Refresh. Być może sprawdzę to przy najbliższej okazji.</p>
<p><strong>Przekierowania Javascript</strong><br />
Metoda podobna do meta refresh &#8211; wysyłamy stronę ze spreparowanym JavaScript&#8217;em, który automatycznie przekierowuje użytkownika pod inny adres.<br />
Cechy techniki:</p>
<ul>
<li>Nie działa z elementami osadzonymi.</li>
<li>Wiele <a href="http://pl.wikipedia.org/wiki/Robot_internetowy">crawlerów</a> nie umie obsługiwać JavaScript&#8217;u &#8211; wyszukiwarki nie zobaczą przekierowań.</li>
<li>Niektórzy <a href="http://pl.wikipedia.org/wiki/Lynx_(przegl%C4%85darka)">nie posiadają</a> lub <a href="http://en.wikipedia.org/wiki/JavaScript#Security">celowo wyłączają</a> obsługę JavaScript&#8217;u w przeglądarce.</li>
<li>Teoretycznie można próbować użyć jej do zamaskowania adresu docelowego zasobu w pasku adresu &#8211; niestety nie znam się aż tak na JavaScript, żeby podać przykład.</li>
</ul>
<p><strong>Maskowanie adresu &#8211; metoda ramek</strong><br />
Użycie <a href="http://pornel.net/ramki">znienawidzonego</a> znacznika &lt;frameset&gt; pozwala bardzo skutecznie zamaskować adres docelowy strony, na którą przekierowujemy (i przy okazji zmienić jej tytuł). Wystarczy wygenerować taki oto HTML:</p>
<div class="codecolorer-container html4strict default" style="overflow:auto;white-space:nowrap;border:1px solid #9F9F9F;width:435px;"><div class="html4strict codecolorer" style="padding:5px;font:normal 12px/1.4em Monaco, Lucida Console, monospace;white-space:nowrap"><span style="color: #00bbdd;">&lt;!DOCTYPE HTML PUBLIC &quot;-//W3C//DTD HTML 4.01 Frameset//EN&quot;</span><br />
<span style="color: #00bbdd;"> &nbsp; &quot;http://www.w3.org/TR/html4/frameset.dtd&quot;&gt;</span><br />
<span style="color: #009900;">&lt;<a href="http://december.com/html/4/element/html.html"><span style="color: #000000; font-weight: bold;">html</span></a>&gt;</span><br />
&nbsp; &nbsp; <span style="color: #009900;">&lt;<a href="http://december.com/html/4/element/head.html"><span style="color: #000000; font-weight: bold;">head</span></a>&gt;</span><br />
&nbsp; &nbsp; <span style="color: #009900;">&lt;<span style="color: #66cc66;">/</span><a href="http://december.com/html/4/element/head.html"><span style="color: #000000; font-weight: bold;">head</span></a>&gt;</span><br />
&nbsp; &nbsp; <br />
&nbsp; &nbsp; <span style="color: #009900;">&lt;<a href="http://december.com/html/4/element/frameset.html"><span style="color: #000000; font-weight: bold;">frameset</span></a> <span style="color: #000066;">cols</span><span style="color: #66cc66;">=</span><span style="color: #ff0000;">&quot;100%&quot;</span>&gt;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #009900;">&lt;<a href="http://december.com/html/4/element/frame.html"><span style="color: #000000; font-weight: bold;">frame</span></a> <span style="color: #000066;">src</span><span style="color: #66cc66;">=</span><span style="color: #ff0000;">&quot;http://www.innastrona.com&quot;</span> <span style="color: #000066;">name</span><span style="color: #66cc66;">=</span><span style="color: #ff0000;">&quot;moja_ramka&quot;</span> <span style="color: #66cc66;">/</span>&gt;</span><br />
&nbsp; &nbsp; <span style="color: #009900;">&lt;<span style="color: #66cc66;">/</span><a href="http://december.com/html/4/element/frameset.html"><span style="color: #000000; font-weight: bold;">frameset</span></a>&gt;</span><br />
<span style="color: #009900;">&lt;<span style="color: #66cc66;">/</span><a href="http://december.com/html/4/element/html.html"><span style="color: #000000; font-weight: bold;">html</span></a>&gt;</span></div></div>
<p>Własności tej metody:</p>
<ul>
<li>Pozwala zamaskować adres docelowy i wymienić tytuł.</li>
<li>Nie działa z elementami osadzonymi &#8211; z oczywistych przyczyn.</li>
<li>Standardem są już skrypty pozwalające stronie automatycznie &#8216;wyskoczyć z ramki&#8217; &#8211; i wtedy nici z maskowania adresu.</li>
<li>Może być przyczyną kontrowersji i ataków ze strony niedouczonych webmasterów stron docelowych.</li>
</ul>
<p>Tę technikę spotykamy się wbrew pozorom dość często &#8211; na stronach takich jak <a href="http://www.wykop.pl/ramka/231015/internet-skonczyl-40-lat">Wykop.pl</a> czy nawet <a href="http://images.google.pl/images?q=s%C5%82oneczko">Google Images</a>. Takie strony po prostu dodają dodatkową ramkę z własnymi informacjami <img src='http://temporal.pr0.pl/devblog/wp-includes/images/smilies/icon_smile.gif' alt=':)' class='wp-smiley' /> .</p>
<p><strong>Przekierowania &#8216;proxy&#8217;</strong><br />
Najbardziej bezpośrednią metodą wyświetlenia cudzego contentu pod swoim adresem <img src='http://temporal.pr0.pl/devblog/wp-includes/images/smilies/icon_smile.gif' alt=':)' class='wp-smiley' />  jest pobranie jej przez nasz serwer i oddanie użytkownikowi. W PHP pomóc nam w tym może funkcja <code class="codecolorer php default"><span class="php"><a href="http://www.php.net/readfile"><span style="color: #990000;">readfile</span></a><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span></span></code>. Metoda jest bardzo prosta w teorii i gwarantuje zamaskowanie adresu, jednak rodzi też szereg trudności technicznych:</p>
<ul>
<li>Jeżeli oddajemy w ten sposób stronę internetową to najprawdopodobniej posypią się wszystkie relatywne odnośniki do obrazków, skryptów i CSS &#8211; dostaniemy goły, nieużyteczny dokument HTML.</li>
<li>Jeżeli oddajemy coś innego niż zwykły tekst to musimy ręcznie określić <a href="http://pl.wikipedia.org/wiki/Typ_MIME">typ MIME</a> zwracanego zasobu. A ponieważ zasób jest nie u nas, to możemy albo zgadywać ten typ (np. po rozszerzeniu), albo odczytywać dopiero po ściągnięciu. Innymi słowy &#8211; dodatkowa robota.</li>
<li>Cała treść przechodzi przez nasz serwer, skutecznie go spowalniając (już nie mówiąc o ewentualnych limitach downloadu).</li>
</ul>
<p>Wspominam o tej technice, gdyż ma ona także dużo dobrych właściwości:</p>
<ul>
<li>Kompletne zamaskowanie adresu zasobu.</li>
<li>Działa z elementami osadzonymi.</li>
<li>Pozwala nam modyfikować zasób i sposób jego przetwarzania (np. można <a href="http://www.google.pl/search?q=content-disposition+attachment">wymusić na przeglądarce wyświetlenie okienka &#8220;Zapisz jako&#8230;&#8221;</a>).</li>
</ul>
<p>Wspomniane przeze mnie problemy techniczne można oczywiście obejść, ale pytanie czy nie jest to przerost formy nad treścią <img src='http://temporal.pr0.pl/devblog/wp-includes/images/smilies/icon_smile.gif' alt=':)' class='wp-smiley' /> .</p>
<p>Trochę ten post wyszedł przydługi&#8230; <img src='http://temporal.pr0.pl/devblog/wp-includes/images/smilies/icon_wink.gif' alt=';)' class='wp-smiley' /> . A teraz obiecany na początku&#8230;</p>
<p><strong>Eksperyment HTTP</strong><br />
Chciałbym w tym miejscu podziękować wszystkim osobom, które już wzięły udział i rozgłaszały Eksperyment wśród innych. Ruch pierwszego dnia był spory; jakaś dobra dusza nawet wrzuciła link na Wykop <img src='http://temporal.pr0.pl/devblog/wp-includes/images/smilies/icon_smile.gif' alt=':)' class='wp-smiley' /> . Zebrałem już dość dużo danych, jakieś 85% tego, co założyłem jako minimum. Dlatego jeżeli ktoś jeszcze nie brał udziału, to <strong><a href="http://temporal.pr0.pl/devblog/2009/09/09/http-eksperyment/">zapraszam</a></strong>, a jeżeli już brał to zachęcam o podrzucenie linka innym osobom! Myślę, że wyniki opracuję w najbliższych dniach. Dla zaostrzenia apetytu powiem tylko, że eksperyment ma duży związek z tematem tego posta <img src='http://temporal.pr0.pl/devblog/wp-includes/images/smilies/icon_smile.gif' alt=':)' class='wp-smiley' /> .</p>
]]></content:encoded>
			<wfw:commentRss>http://temporal.pr0.pl/devblog/2009/09/10/przekierowania-skracanie-i-ukrywanie-adresow-co-i-jak/feed/</wfw:commentRss>
		<slash:comments>2</slash:comments>
		</item>
		<item>
		<title>HTTP &#8211; Eksperyment</title>
		<link>http://temporal.pr0.pl/devblog/2009/09/09/http-eksperyment/</link>
		<comments>http://temporal.pr0.pl/devblog/2009/09/09/http-eksperyment/#comments</comments>
		<pubDate>Wed, 09 Sep 2009 08:48:31 +0000</pubDate>
		<dc:creator>Jacek Złydach</dc:creator>
				<category><![CDATA[Informatyka]]></category>
		<category><![CDATA[Kategoria nie przypisana]]></category>
		<category><![CDATA[dobro Galaktyki]]></category>
		<category><![CDATA[eksperyment]]></category>
		<category><![CDATA[HTTP]]></category>
		<category><![CDATA[PHP]]></category>
		<category><![CDATA[webmasterka]]></category>

		<guid isPermaLink="false">http://temporal.pr0.pl/devblog/?p=625</guid>
		<description><![CDATA[Aktualizacja &#8211; 12.09.2009
Eksperyment został zakończony, trwa przetwarzanie zebranych danych. Zapraszam &#8211; wyniki oraz cel samych badań już wkrótce!  
Aktualizacja &#8211; 14.09.2009
Wyniki już są    .
Drodzy Czytelnicy, w ramach prac nad pewnym projektem i poszerzaniem wiedzy n/t HTTP przeprowadzam mały eksperyment statystyczny. Każdy z Was może wziąć w nim udział i tym samym [...]]]></description>
			<content:encoded><![CDATA[<p><em>Aktualizacja &#8211; 12.09.2009</em><br />
Eksperyment został zakończony, trwa przetwarzanie zebranych danych. Zapraszam &#8211; wyniki oraz cel samych badań już wkrótce! <img src='http://temporal.pr0.pl/devblog/wp-includes/images/smilies/icon_smile.gif' alt=':)' class='wp-smiley' /> </p>
<p><em>Aktualizacja &#8211; 14.09.2009</em><br />
<a href="http://temporal.pr0.pl/devblog/2009/09/14/eksperyment-podsumowanie/">Wyniki już są </a> <img src='http://temporal.pr0.pl/devblog/wp-includes/images/smilies/icon_smile.gif' alt=':)' class='wp-smiley' />  .</p>
<p>Drodzy Czytelnicy, w ramach prac nad pewnym projektem i <a href="http://temporal.pr0.pl/devblog/2009/09/08/przekierowania-http/">poszerzaniem wiedzy n/t HTTP</a> przeprowadzam mały eksperyment statystyczny. <strong>Każdy z Was może wziąć w nim udział i tym samym zrobić coś dla dobra Galaktyki!</strong> <img src='http://temporal.pr0.pl/devblog/wp-includes/images/smilies/icon_smile.gif' alt=':)' class='wp-smiley' /> . Wystarczy jedynie wejść na podaną niżej stronę eksperymentu i po załadowaniu kliknąć w oba obrazki (mają podłożone linki).</p>
<p><strong><a href="http://temporal.pr0.pl/eksperyment/eksperyment.html" rel="nofollow">Strona Eksperymentu</a></strong></p>
<p>W eksperymencie tym zbieram tylko troszkę danych na temat zapytania HTTP wysyłanego przez przeglądarkę. Wyniki i opracowanie podam po zebraniu odpowiedniej ilości danych, czyli &#8211; miejmy nadzieję &#8211; w ciągu kilku najbliższych dni. Jednocześnie bardzo prosiłbym o nie znęcanie się nade mną przez fałszowanie wyników lub hackowanie strony. Wystarczy wejść, kliknąć dwa razy i wyjść <img src='http://temporal.pr0.pl/devblog/wp-includes/images/smilies/icon_smile.gif' alt=':)' class='wp-smiley' /> .</p>
<p>Z góry dziękuję wszystkim, którzy zechcą wziąć udział w eksperymencie! Wyniki wkrótce!</p>
<p><strong>Ważny Edit!</strong><br />
Dziękuję tym, którzy tak ochoczo zareagowali na wezwanie do wzięcia udziału! Jednocześnie mam prośbę &#8211; <strong>jeżeli ktoś ma zainstalowane w systemie kilka przeglądarek WWW, to zachęcam do wejścia na stronę Eksperymentu każdą z nich z osobna</strong>! Dzięki temu zebrane zostanie więcej istotnych danych <img src='http://temporal.pr0.pl/devblog/wp-includes/images/smilies/icon_smile.gif' alt=':)' class='wp-smiley' /> .</p>
]]></content:encoded>
			<wfw:commentRss>http://temporal.pr0.pl/devblog/2009/09/09/http-eksperyment/feed/</wfw:commentRss>
		<slash:comments>4</slash:comments>
		</item>
		<item>
		<title>Przekierowania HTTP</title>
		<link>http://temporal.pr0.pl/devblog/2009/09/08/przekierowania-http/</link>
		<comments>http://temporal.pr0.pl/devblog/2009/09/08/przekierowania-http/#comments</comments>
		<pubDate>Tue, 08 Sep 2009 09:48:21 +0000</pubDate>
		<dc:creator>Jacek Złydach</dc:creator>
				<category><![CDATA[Informatyka]]></category>
		<category><![CDATA[Apache]]></category>
		<category><![CDATA[Google]]></category>
		<category><![CDATA[HTTP]]></category>
		<category><![CDATA[mod_rewrite]]></category>
		<category><![CDATA[PHP]]></category>
		<category><![CDATA[porady]]></category>
		<category><![CDATA[SEO]]></category>
		<category><![CDATA[webmasterka]]></category>

		<guid isPermaLink="false">http://temporal.pr0.pl/devblog/?p=586</guid>
		<description><![CDATA[W ostatnim okresie czasu intensywnie pracuję nad pewnym projektem w PHP. Prace te pozwoliły mi się zapoznać dokładnie z różnymi technikami przekierowywania przeglądarek do żądanych zasobów. W tym poście chciałbym omówić główne przekierowania zdefiniowane w protokole HTTP; przynajmniej jedno z nich powinno być powszechnie znane programistom PHP. Wpis ten oparty jest o post &#8220;The anatomy [...]]]></description>
			<content:encoded><![CDATA[<p>W ostatnim okresie czasu intensywnie pracuję nad pewnym projektem w <a href="http://pl.wikipedia.org/wiki/PHP"><acronym title="PHP Hypertext Preprocessor">PHP</acronym></a>. Prace te pozwoliły mi się zapoznać dokładnie z różnymi technikami przekierowywania przeglądarek do żądanych zasobów. W tym poście chciałbym omówić główne przekierowania zdefiniowane w protokole HTTP; przynajmniej jedno z nich powinno być powszechnie znane programistom PHP. Wpis ten oparty jest o post <a href="http://sebastians-pamphlets.com/the-anatomy-of-http-redirects-301-302-307/">&#8220;The anatomy of server sided redirect&#8221;</a> na <a href="http://sebastians-pamphlets.com/">blogu Sebastian&#8217;s Pamphlets</a>, specyfikacji HTTP/1.1, której wydrukowany fragment trzymam obok siebie oraz osobistych doświadczeniach.</p>
<p><strong>Przekierowania HTTP</strong><br />
Jak <a href="http://kurs.browsehappy.pl/HTTP/Wprowadzenie">wiadomo</a>, fundamentalny dla WWW protokół <acronym title="HyperText Transfer Protocol">HTTP</acronym> zawiera kody odpowiedzi (opisane <a href="http://www.w3.org/Protocols/rfc2616/rfc2616-sec10.html#sec10">w sekcji 10 specyfikacji RFC2616</a>), którymi serwer WWW informuje przeglądarki o tym, co przeglądarki mają dalej robić. Nas w tym miejscu interesują kody serii 3xx (sekcja 10.3 RFC). Zadaniem tych kodów jest przekierowanie przeglądarki pod inny adres docelowy. Kody te mają też wpływ na <a href="http://pl.wikipedia.org/wiki/Robot_internetowy">crawlery wyszukiwarek</a>, które przecież starają się udawać ludzi. Powiemy sobie o:</p>
<ul>
<li><strong>HTTP 301 Moved Permanently</strong></li>
<li><strong>HTTP 302 Found</strong></li>
<li><strong>HTTP 303 See Other</strong></li>
<li><strong>HTTP 307 Temporary Redirect</strong></li>
</ul>
<p>Gdy serwer dokonuje przekierowania to oprócz odpowiedniego kodu statusu i opisu wysyła także nagłówek <em>Location</em> zawierający adres, pod który ma udać się przeglądarka. Przykładowa odpowiedź-przekierowanie HTTP, które przeniesie przeglądarkę na stronę Google, może wyglądać następująco:</p>
<div class="codecolorer-container text default" style="overflow:auto;white-space:nowrap;border:1px solid #9F9F9F;width:435px;"><div class="text codecolorer" style="padding:5px;font:normal 12px/1.4em Monaco, Lucida Console, monospace;white-space:nowrap">HTTP/1.1 307 Temporary Redirect<br />
Location: http://www.google.pl</div></div>
<p><strong>HTTP/1.1 301 Moved Permanently</strong><br />
Kod ten tworzy permanentne przekierowanie pod adres docelowy. To tak, jakbyśmy powiedzieli przeglądarce: <em>&#8220;URI, o które prosiłaś znikło. Być może nigdy go nie było, a <strong>na pewno nigdy nie będzie</strong>. Nie będę dostarczać żadnej treści dla zapytania o to URI, więc zaktualizuj swoje zakładki podanym niżej adresem i nie zawracaj mi już więcej głowy. Nigdy więcej.&#8221;</em>.</p>
<p>Przekierowania 301 używamy najczęściej przy przeniesieniu całej strony, gdy chcemy poinstruować ludzi i crawlery o zmianie lokalizacji. W szczególności powinniśmy to zrobić, jeżeli zależy nam na utrzymaniu dotychczasowej pozycji strony w wyszukiwarkach. <a href="http://www.google.com/support/webmasters/bin/answer.py?answer=93633">Google rozumie kod 301</a>, ale stronę trzeba <a href="http://www.google.com/support/webmasters/bin/answer.py?hl=pl&#038;answer=83105">przenosić</a> <a href="http://sebastians-pamphlets.com/the-anatomy-of-http-redirects-301-302-307/#moving-sites-301">z głową</a>.</p>
<p><strong>Kod 301 jest przekierowaniem &#8216;na zawsze&#8217; &#8211; URI raz oznaczone tym numerem nie powinno być nigdy więcej używane w innym celu</strong>. To znaczy, że mamy obowiązek go utrzymywać &#8211; przynajmniej jeśli zależy nam na <a href="http://pl.wikipedia.org/wiki/PageRank">Page Rank</a> &#8211; tak długo, jak to tylko możliwe (tak, trzeba płacić i za starą domenę <img src='http://temporal.pr0.pl/devblog/wp-includes/images/smilies/icon_wink.gif' alt=';)' class='wp-smiley' /> ). Nie powinno się też nigdy zmieniać miejsca, do którego odsyła to przekierowanie. Kodu 301 powinniśmy używać też do tzw. <a href="http://en.wikipedia.org/wiki/Canonicalization#Canonicalization_in_Search_Engines_and_SEO">sprowadzenia adresu do postaci kanonicznej</a> (<a href="http://www.mattcutts.com/blog/seo-advice-url-canonicalization/">pozwala uniknąć problemów z wyszukiwarkami</a>, w tym podwójnego widzenia treści dla adresów z www i bez www). Przykład użycia pliku <a href="http://pl.wikipedia.org/wiki/Htaccess">.htacccess</a> i <a href="http://en.wikipedia.org/wiki/Rewrite_engine">mod_rewrite</a> do zapewnienia postaci kanonicznej adresu:</p>
<div class="codecolorer-container text default" style="overflow:auto;white-space:nowrap;border:1px solid #9F9F9F;width:435px;"><div class="text codecolorer" style="padding:5px;font:normal 12px/1.4em Monaco, Lucida Console, monospace;white-space:nowrap">RewriteEngine On<br />
RewriteCond %{HTTP_HOST} !^example\.com [NC]<br />
RewriteRule (.*) http://example.com/$1 [R=301,L]</div></div>
<p>Należy zwrócić uwagę na fragment <em>R=301</em> w ostatniej linijce &#8211; oznacza to, że do zmiany adresu zostanie użyte przekierowanie 301.</p>
<p>Aby przekierowanie 301 zostało wykonane poprawnie musimy wysłać przeglądarce tekst <strong>z kodem i statusem</strong> &#8211; w przeciwnym razie wykonane zostanie domyślne przekierowanie 302 Found, o którym niżej. Tyczy się to szczególnie PHP, gdzie już chyba zwyczajem stało się pisanie<a name="POST_PRZEKIEROWANIA_HTTP_1_NIECHLUJSTWO">:</a></p>
<div class="codecolorer-container php default" style="overflow:auto;white-space:nowrap;border:1px solid #9F9F9F;width:435px;"><div class="php codecolorer" style="padding:5px;font:normal 12px/1.4em Monaco, Lucida Console, monospace;white-space:nowrap"><a href="http://www.php.net/header"><span style="color: #990000;">Header</span></a><span style="color: #009900;">&#40;</span><span style="color: #0000ff;">'Location: '</span><span style="color: #339933;">.</span><span style="color: #000088;">$adres</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span></div></div>
<p>Taki kod wykona przekierowanie 302. Poprawnie sformułowane w PHP przekierowanie 301:</p>
<div class="codecolorer-container php default" style="overflow:auto;white-space:nowrap;border:1px solid #9F9F9F;width:435px;"><div class="php codecolorer" style="padding:5px;font:normal 12px/1.4em Monaco, Lucida Console, monospace;white-space:nowrap"><a href="http://www.php.net/header"><span style="color: #990000;">Header</span></a><span style="color: #009900;">&#40;</span><span style="color: #0000ff;">'HTTP/1.1 301 Moved Permanently'</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span><br />
<a href="http://www.php.net/header"><span style="color: #990000;">Header</span></a><span style="color: #009900;">&#40;</span><span style="color: #0000ff;">'Location: '</span><span style="color: #339933;">.</span><span style="color: #000088;">$adres</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span></div></div>
<p><strong>HTTP/1.1 302 Found</strong><br />
Przekierowanie 302 jest chyba najbardziej <a href="http://sebastians-pamphlets.com/the-anatomy-of-http-redirects-301-302-307/#301-moved-permanently">nadużywanym przekierowaniem</a> w sieci &#8211; głównie z powodu tego, że jest to przekierowanie domyślne, które zostanie wykonane jeżeli samodzielnie nie wykonaliśmy innego przekierowania. Problemy dotyczą głównie niewłaściwego używania 302 w miejscu, gdzie powinno być 301 &#8211; częściowo <a href="#POST_PRZEKIEROWANIA_HTTP_1_NIECHLUJSTWO">z niechlujstwa</a>, a częściowo &#8211; <a href="http://sebastians-pamphlets.com/the-anatomy-of-http-redirects-301-302-307/#302-found-elsewhere">wg Simon&#8217;s Pamphlets</a> &#8211; z różnych mitów rozpowszechnianych w środowisku <a href="http://pl.wikipedia.org/wiki/Optymalizacja_dla_wyszukiwarek_internetowych"><acronym title="Search Engine Optimization">SEO</acronym></a>. Pomyłkowe użycie 302 zamiast 301 jest niegroźne zarówno dla człowieka jak i przeglądarki, ale może wyrządzić krzywdę pozycji strony w wyszukiwarce.</p>
<p>Kod 302 Found (w HTTP/1.0 zwany 302 Moved Temporarily) służy do wskazania tymczasowej lokalizacji zasobu. Ponieważ jednak przekierowanie może się zmieniać, specyfikacja sugeruje, by klienci dalej używali tego adresu, którym przyszli, a nie tego, który dostaną z przekierowania. Jeżeli chce się z jakiegoś powodu odesłać użytkownika na inną stronę &#8211; czy to wewnętrzną, czy zewnętrzną w stosunku do naszego serwisu &#8211; to możemy użyć właśnie tego kodu. W PHP wygląda to tak:</p>
<div class="codecolorer-container php default" style="overflow:auto;white-space:nowrap;border:1px solid #9F9F9F;width:435px;"><div class="php codecolorer" style="padding:5px;font:normal 12px/1.4em Monaco, Lucida Console, monospace;white-space:nowrap"><span style="color: #666666; font-style: italic;">//Wersja HTTP/1.0</span><br />
<a href="http://www.php.net/header"><span style="color: #990000;">Header</span></a><span style="color: #009900;">&#40;</span><span style="color: #0000ff;">'HTTP/1.0 302 Moved Temporarily'</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span><br />
<a href="http://www.php.net/header"><span style="color: #990000;">Header</span></a><span style="color: #009900;">&#40;</span><span style="color: #0000ff;">'Location: '</span><span style="color: #339933;">.</span><span style="color: #000088;">$adres</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span><br />
<br />
<span style="color: #666666; font-style: italic;">//Wersja HTTP/1.1</span><br />
<a href="http://www.php.net/header"><span style="color: #990000;">Header</span></a><span style="color: #009900;">&#40;</span><span style="color: #0000ff;">'HTTP/1.1 302 Found'</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span><br />
<a href="http://www.php.net/header"><span style="color: #990000;">Header</span></a><span style="color: #009900;">&#40;</span><span style="color: #0000ff;">'Location: '</span><span style="color: #339933;">.</span><span style="color: #000088;">$adres</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span></div></div>
<p>Poza niewielkimi różnicami w specyfikacji dotyczącymi cache&#8217;ingu kody 302 obu wersji robią w zasadzie to samo. I chociaż <a href="http://www.ietf.org/rfc/rfc1945.txt">dotychczasowe (9.3)</a> <a href="http://www.ietf.org/rfc/rfc2068.txt">RFC (10.3.3)</a> nie pozwalały zmieniać przy przekierowaniu metody zapytania (np. z POST na GET), większość przeglądarek to właśnie robi (przeważyły prawdopodobnie względy bezpieczeństwa) &#8211; kod 302 jest interpretowany tak jak 303. Aby można było rozróżnić, kiedy serwer chce wykonać przekierowanie ze zmianą metody zapytania na GET a kiedy bez zmiany, wprowadzono w HTTP/1.1 dwa dodatkowe kody &#8211; <strong>303 See Other</strong> i <strong>307 Temporary Redirect</strong>. Ponieważ przeglądarki oraz crawlery potrafią już &#8216;rozmawiać&#8217; protokołem HTTP/1.1, to poza szczególnymi przypadkami gdy z jakiegoś powodu musimy &#8216;bawić się&#8217; w HTTP/1.0 możemy spokojnie korzystać z nowych kodów.</p>
<p><strong>HTTP/1.1 303 See Other</strong><br />
Według <a href="http://www.w3.org/Protocols/rfc2616/rfc2616-sec10.html#sec10.3.4">RFC2616 (10.3.4)</a> celem istnienia tego kodu jest przede wszystkim umożliwienie wynikom zapytania POST możliwości przekierowania do innych zasobów. W momencie otrzymania kodu 303 przeglądarka powinna zmienić metodę zapytania na GET. Poprawne użycie w PHP:</p>
<div class="codecolorer-container php default" style="overflow:auto;white-space:nowrap;border:1px solid #9F9F9F;width:435px;"><div class="php codecolorer" style="padding:5px;font:normal 12px/1.4em Monaco, Lucida Console, monospace;white-space:nowrap"><a href="http://www.php.net/header"><span style="color: #990000;">Header</span></a><span style="color: #009900;">&#40;</span><span style="color: #0000ff;">'HTTP/1.1 303 See Other'</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span><br />
<a href="http://www.php.net/header"><span style="color: #990000;">Header</span></a><span style="color: #009900;">&#40;</span><span style="color: #0000ff;">'Location: '</span><span style="color: #339933;">.</span><span style="color: #000088;">$adres</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span></div></div>
<p>Kodu tego powinniśmy używać w skryptach wywoływanych zapytaniem POST &#8211; po przetworzeniu żądania powinny one wykonywać przekierowanie 303 na stronę, która wyświetli nam wyniki. Dzięki temu, gdy użytkownik odświeży stronę, zapytanie POST (mogące mieć przecież jakieś skutki uboczne!) nie zostanie wykonane ponownie (Firefox w takich sytuacjach pyta, czy ponownie wysłać dane). Jest to o tyle istotne, że <a href="http://www.w3.org/Protocols/rfc2616/rfc2616-sec9.html">zgodnie ze specyfikacją</a> do wprowadzania zmian (edycja, usuwanie, itp.) w zasobach strony powinniśmy używać metody POST, nie GET (celowo pomijam tutaj <a href="http://www.w3.org/Protocols/rfc2616/rfc2616-sec9.html#sec9.6">PUT</a> i <a href="http://www.w3.org/Protocols/rfc2616/rfc2616-sec9.html#sec9.7">DELETE</a> &#8211; architektura <a href="http://en.wikipedia.org/wiki/Representational_State_Transfer">REST</a>, która je wykorzystuje, nie jest jeszcze aż tak popularna).</p>
<p><strong>HTTP/1.1 307 Temporary Redirect</strong><br />
Kod 307 to nasz najlepszy przyjaciel, gdy potrzebujemy wykonywać przekierowania do tymczasowych zasobów. W przeciwieństwie do 303 nie zmienia metody zapytania &#8211; kod 307 zachowuje się tak, jak powinien był się zachowywać w przeglądarkach 302. To właśnie tym kodem chcemy się posługiwać, więc warto zadbać o jego poprawne wysłanie, żeby przypadkiem nie wyszedł nam 302:</p>
<div class="codecolorer-container php default" style="overflow:auto;white-space:nowrap;border:1px solid #9F9F9F;width:435px;"><div class="php codecolorer" style="padding:5px;font:normal 12px/1.4em Monaco, Lucida Console, monospace;white-space:nowrap"><a href="http://www.php.net/header"><span style="color: #990000;">Header</span></a><span style="color: #009900;">&#40;</span><span style="color: #0000ff;">'HTTP/1.1 307 Temporary Redirect'</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span><br />
<a href="http://www.php.net/header"><span style="color: #990000;">Header</span></a><span style="color: #009900;">&#40;</span><span style="color: #0000ff;">'Location: '</span><span style="color: #339933;">.</span><span style="color: #000088;">$adres</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span></div></div>
<p>Jednym z zastosowań przekierowania 307 jest przekierowywanie kanałów <a href="http://pl.wikipedia.org/wiki/RSS">RSS</a>/<a href="http://pl.wikipedia.org/wiki/Atom_(standard)">Atom</a> do usługi <a href="http://pl.wikipedia.org/wiki/FeedBurner">FeedBurner</a>.</p>
<p><strong>Podsumowanie &#8211; kiedy używamy którego kodu?</strong></p>
<ul>
<li><strong>HTTP 301 Moved Permanently</strong> &#8211; gdy zasób został na stałe przeniesiony pod inny adres. Przekierowania 301 powinniśmy utrzymywać włączone tak długo, jak to możliwe i nigdy nie poddawać ich recyclingowi.</li>
<li><strong>HTTP 302 Found</strong> &#8211; gdy musimy borykać się z protokołem HTTP/1.0.</li>
<li><strong>HTTP 303 See Other</strong> &#8211; gdy skrypt, który otrzymał zapytanie POST chce wyświetlić jakieś wyniki &#8211; powinien wtedy wykonać przekierowanie 303 na stronę z wynikami. Unikniemy dzięki temu ponownego wysłania zapytania POST przy odświeżeniu strony.</li>
<li><strong>HTTP 307 Temporary Redirect</strong> &#8211; wszystkie sytuacje, gdy robimy tymczasowe przekierowania. Skracanie nazw URI, odesłanie do innej strony, przekierowanie RSS/Atom na FeedBurnerm itd.</li>
</ul>
<p><strong>Dodatkowe informacje</strong></p>
<ul>
<li>Omówione przekierowania operują bezpośrednio na poziomie protokołu HTTP. Oznacza to, że możemy ich użyć do przekierowywania np. obrazków osadzanych w tagach &lt;img&gt;.</li>
<li>Osobom używającym .htaccess do sprowadzania adresu do postaci kanonicznej (w tym np. usuwanie bądź dodawanie &#8216;www&#8217; przed nazwą) polecam upewnić się, że używają przekierowania 301 a nie domyślnego 302.</li>
</ul>
<p>Zainspirowany <a href="http://gynvael.coldwind.pl/">Gynvael&#8217;em</a> i innymi postanowiłem utworzyć też dział <a href="http://temporal.pr0.pl/devblog/code-snippets/">Code Snippets</a>, w którym znajdować się będą różne drobne i &#8211; miejmy nadzieję &#8211; przydatne fragmenty kodu. Jako pierwszy umieszczam <a href="http://temporal.pr0.pl/devblog/code-snippets/#CODE_SNIPPETS_PHP_HTTP_TOOLS">drobną klasę PHP</a> realizującą u mnie w projekcie przekierowania oraz obsługę wybranych kodów 4xx i 5xx.</p>
]]></content:encoded>
			<wfw:commentRss>http://temporal.pr0.pl/devblog/2009/09/08/przekierowania-http/feed/</wfw:commentRss>
		<slash:comments>1</slash:comments>
		</item>
		<item>
		<title>Myśli losowe</title>
		<link>http://temporal.pr0.pl/devblog/2009/08/05/mysli-losowe/</link>
		<comments>http://temporal.pr0.pl/devblog/2009/08/05/mysli-losowe/#comments</comments>
		<pubDate>Wed, 05 Aug 2009 20:06:39 +0000</pubDate>
		<dc:creator>Jacek Złydach</dc:creator>
				<category><![CDATA[Informatyka]]></category>
		<category><![CDATA[Varia]]></category>
		<category><![CDATA[blip]]></category>
		<category><![CDATA[edukacja]]></category>
		<category><![CDATA[Google]]></category>
		<category><![CDATA[hasła geometryczne]]></category>
		<category><![CDATA[przemyślenia]]></category>

		<guid isPermaLink="false">http://temporal.pr0.pl/devblog/?p=577</guid>
		<description><![CDATA[Oto kilka drobnych kwestii, które chciałbym poruszyć, a które są chyba za małe na oddzielne posty  
Hasła geometryczne
Widziałem nie raz osoby stosujące geometryczne wzorce do zapamiętania jakiegoś hasła. Przykładowo, hasło &#8220;123wsx&#8221; może być trudne do zapamiętania jako ciąg znaków, jest natomiast bardzo proste do zapamiętania jeśli zobaczymy w jaki sposób wpisuje się je na [...]]]></description>
			<content:encoded><![CDATA[<p>Oto kilka drobnych kwestii, które chciałbym poruszyć, a które są chyba za małe na oddzielne posty <img src='http://temporal.pr0.pl/devblog/wp-includes/images/smilies/icon_smile.gif' alt=':)' class='wp-smiley' /> </p>
<p><strong>Hasła geometryczne</strong><br />
Widziałem nie raz osoby stosujące geometryczne wzorce do zapamiętania jakiegoś hasła. Przykładowo, hasło &#8220;123wsx&#8221; może być trudne do zapamiętania jako ciąg znaków, jest natomiast bardzo proste do zapamiętania jeśli zobaczymy w jaki sposób wpisuje się je na klawiaturze komputera. Podobnie, widziałem alarm zakodowany w taki sposób, że ciąg liczb nie ma żadnego znaczenia, natomiast klawisze układają się w łatwy do zapamiętania wzór. Nie jest to oczywiście zbyt bezpieczne &#8211; hasło typowo geometryczne jest teoretycznie łatwiej podpatrzeć &#8216;z za pleców&#8217; niż każde inne. Być może łamiąc hasła powinno się oprócz najpopularniejszych wyrazów uwzględniać także najpopularniejsze wzory geometryczne <img src='http://temporal.pr0.pl/devblog/wp-includes/images/smilies/icon_smile.gif' alt=':)' class='wp-smiley' />  .</p>
<p><strong>Źródła wiedzy</strong><br />
Kilka miejsc, które mogą się przydać do zdobycia wiedzy w wielu dziedzinach, głównie ścisłych:</p>
<ul>
<li><strong><a href="http://wazniak.mimuw.edu.pl/">&#8220;Ważniak&#8221;</a> </strong>- znany i używany przez polskich studentów kierunków informatycznych zbiór materiałów podzielonych na wirtualne kursy. Coś jak wirtualna uczelnia <img src='http://temporal.pr0.pl/devblog/wp-includes/images/smilies/icon_smile.gif' alt=':)' class='wp-smiley' /> </li>
<li><strong><a href="http://research.microsoft.com/apps/tools/tuva/index.html#data=4|0||72036f54-7e17-4435-b972-a18050d5828b||">Wykłady Feynmana</a></strong> &#8211; udostępnione on-line wykłady dr Richarda Feynmana (<a href="http://en.wikipedia.org/wiki/Richard_Feynman">tego Feynmana</a>). Wspominał o nich <a href="http://notatki.alexba.eu/2009-07-18/wyklady-feynmana-w-internecie/">Alex w swoich notatkach</a>. Nie sprawdzałem jeszcze tego osobiście, ale wygląda na coś bardzo wartościowego.</li>
<li><strong><a href="http://ocw.mit.edu/OcwWeb/web/home/home/index.htm">Open Course Ware</a></strong> &#8211; czyl MIT on-line. Wspomniał o tym <a href="http://zajaczkowski.org/2009/06/30/open-course-ware-czyli-jak-kazdy-z-nas-moze-sobie-postudiowac-na-mit/#more-4671">Bartosz Zajączkowski</a> na swoim blogu.</li>
<p> Kolejna rzecz do sprawdzenia <img src='http://temporal.pr0.pl/devblog/wp-includes/images/smilies/icon_smile.gif' alt=':)' class='wp-smiley' /> .
</ul>
<p><strong>Blip i Google</strong><br />
Od około miesiąca eksperymentuję z serwisem <a href="http://blip.pl">Blip</a>. W ciągu tego czasu mój profil blipowy wypozycjonował się &#8217;samoistnie&#8217; na pierwsze miejsce w Google&#8217;ach przy pytaniu o moje nazwisko. W podobny sposób wyszukując jednego z moich kolegów po nazwisku znajdziemy Twittera już na drugim miejscu. Tak błyskawiczne pozycjonowanie się serwisów mikroblogowych może być niebezpieczne dla każdego, kto zaczyna tam wypisywać nieprzemyślane głupoty <img src='http://temporal.pr0.pl/devblog/wp-includes/images/smilies/icon_smile.gif' alt=':)' class='wp-smiley' />  .</p>
]]></content:encoded>
			<wfw:commentRss>http://temporal.pr0.pl/devblog/2009/08/05/mysli-losowe/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Linux Oświecony &#8211; Tapety</title>
		<link>http://temporal.pr0.pl/devblog/2009/07/21/linux-oswiecony-tapety/</link>
		<comments>http://temporal.pr0.pl/devblog/2009/07/21/linux-oswiecony-tapety/#comments</comments>
		<pubDate>Tue, 21 Jul 2009 10:00:51 +0000</pubDate>
		<dc:creator>Jacek Złydach</dc:creator>
				<category><![CDATA[Grafika Komputerowa]]></category>
		<category><![CDATA[Humor]]></category>
		<category><![CDATA[Enlightened Guest]]></category>
		<category><![CDATA[Linux]]></category>
		<category><![CDATA[sztuka]]></category>
		<category><![CDATA[tapety]]></category>
		<category><![CDATA[Windows]]></category>

		<guid isPermaLink="false">http://temporal.pr0.pl/devblog/?p=546</guid>
		<description><![CDATA[Microsoft tworzy niekiedy bardzo ciekawe terminy. Stanisław Wawszczak dopadł ostatnio książkę o Windows Server 2008 (świeżutką, prosto z Microsoft Press) i tak oto dowiedzieliśmy się o istnieniu oświeconych systemów-gości &#8211; z angielskiego enlightened guest systems. Dużo uwagi Microsoft przeznaczył na udostępnienie pewnych funkcji Linuksom, i tak powstał &#8216;Enlightened Linux Guest&#8217;. Techniczny opis znaleźć można na [...]]]></description>
			<content:encoded><![CDATA[<p>Microsoft tworzy niekiedy bardzo ciekawe terminy. <a href="http://wawszczak.pr0.pl">Stanisław Wawszczak</a> dopadł ostatnio książkę o Windows Server 2008 (świeżutką, prosto z Microsoft Press) i tak oto dowiedzieliśmy się o istnieniu <em><a href="http://wawszczak.pr0.pl/2009/07/21/enlightened-guest-operating-system/">oświeconych systemów-gości</a></em> &#8211; z angielskiego <em>enlightened guest systems</em>. Dużo uwagi Microsoft przeznaczył na udostępnienie pewnych funkcji Linuksom, i tak powstał <em>&#8216;Enlightened Linux Guest&#8217;</em>. Techniczny opis znaleźć można <a href="http://msdn.microsoft.com/en-us/library/cc768520(BTS.10).aspx">na MSDN</a>; dla odmiany chciałbym zaprezentować artystyczne ujęcie tematu w oparciu o wizję przedstawioną przez Staśka. Poniżej znajdują się trzy tapety w rozdzielczości 1280&#215;800 (laptopowa panorama) każda.<br />
<center><a href="http://temporal.pr0.pl/devblog/download/galleries/enlightenment/enlightnment_blank.png"><img src="http://temporal.pr0.pl/devblog/download/galleries/enlightenment/enlightnment_blank_450.png" alt="Tapeta - Logo Windows 2008" /></a></center><br />
<center><a href="http://temporal.pr0.pl/devblog/download/galleries/enlightenment/enlightnment_logo_bottom.png"><img src="http://temporal.pr0.pl/devblog/download/galleries/enlightenment/enlightnment_bottom_450.png" alt="Tapeta - Logo Windows 2008" /></a><br />
</center><br />
<center><a href="http://temporal.pr0.pl/devblog/download/galleries/enlightenment/enlightnment_nologo.png"><img src="http://temporal.pr0.pl/devblog/download/galleries/enlightenment/enlightnment_top_450.png" alt="Tapeta - Kolejna z logo Windows 2008" /></a></center><br />
Tapety są mojego autorstwa; zostały wykonane przy użyciu jedynie <a href="http://www.paint.net/">Paint.NET</a>. Na życzenie mogę przygotować wersje w innych (byle nie za dużych) rozdzielczościach.<br />
Sam Tux w krawacie pochodzi z <a href="http://galeria.max-payne.info/wyswietl.php?gal=4&#038;zdjecie=1">pewnej strony</a>, na której nie udało mi się odnaleźć żadnych danych kontaktowych do autora &#8211; jeśli więc naruszyłem czyjeś prawa autorskie, proszę o powiadomienie.</p>
<p>Ah, w chwili przygotowywania tego posta do publikacji znalazłem na <a href="http://www.wykop.pl/wykopalisko">Wykopalisku</a> artykuł <a href="http://technologie.gazeta.pl/technologie/1,82011,6842542,Szok__Microsoft_ofiarowal_kod_do_kernela_Linuksa.html">poruszający temat</a> oświecenia Linuksa <img src='http://temporal.pr0.pl/devblog/wp-includes/images/smilies/icon_wink.gif' alt=';)' class='wp-smiley' />  . </p>
]]></content:encoded>
			<wfw:commentRss>http://temporal.pr0.pl/devblog/2009/07/21/linux-oswiecony-tapety/feed/</wfw:commentRss>
		<slash:comments>1</slash:comments>
		</item>
		<item>
		<title>Lato w Teatrze</title>
		<link>http://temporal.pr0.pl/devblog/2009/07/20/lato-w-teatrze/</link>
		<comments>http://temporal.pr0.pl/devblog/2009/07/20/lato-w-teatrze/#comments</comments>
		<pubDate>Mon, 20 Jul 2009 21:59:13 +0000</pubDate>
		<dc:creator>Jacek Złydach</dc:creator>
				<category><![CDATA[Varia]]></category>
		<category><![CDATA[Z życia]]></category>
		<category><![CDATA[Kraków]]></category>
		<category><![CDATA[Lato w Teatrze]]></category>
		<category><![CDATA[Pan Twardowski]]></category>
		<category><![CDATA[sztuka]]></category>
		<category><![CDATA[teatr]]></category>
		<category><![CDATA[Teatr Figur]]></category>

		<guid isPermaLink="false">http://temporal.pr0.pl/devblog/?p=557</guid>
		<description><![CDATA[Jeśli, Czytelniku, posiadasz rodzeństwo poniżej 15 lat (lub sam jesteś w tym wieku) to proponuję alternatywę dla wakacyjnego siedzenia przed komputerem / telewizorem i oglądania odmóżdżających telenowel. Mowa o odbywającej się w kilku większych miastach w Polsce akcji Lato w Teatrze. Wydarzenie to skierowane jest do osób w wieku wczesnomłodym   i realizowane jest [...]]]></description>
			<content:encoded><![CDATA[<p>Jeśli, Czytelniku, posiadasz rodzeństwo poniżej 15 lat (lub sam jesteś w tym wieku) to proponuję alternatywę dla wakacyjnego siedzenia przed komputerem / telewizorem i oglądania odmóżdżających telenowel. Mowa o odbywającej się w kilku większych miastach w Polsce akcji <strong><a href="http://www.latowteatrze.pl/">Lato w Teatrze</a></strong>. Wydarzenie to skierowane jest do osób w wieku <em>wczesnomłodym</em> <img src='http://temporal.pr0.pl/devblog/wp-includes/images/smilies/icon_wink.gif' alt=';)' class='wp-smiley' />  i realizowane jest w postaci tzw. półkolonii. W dużym skrócie &#8211; zapisujemy brata / siostrę i za dwa tygodnie mamy młodego artystę <img src='http://temporal.pr0.pl/devblog/wp-includes/images/smilies/icon_smile.gif' alt=':)' class='wp-smiley' /> .</p>
<p>Wczoraj (w niedzielę, 19.07.2009) w Krakowie dobiegł końca pierwszy turnus Lata w Teatrze. Tematem przewodnim był <a href="http://pl.wikipedia.org/wiki/Pan_Twardowski_(posta%C4%87)">Pan Twardowski</a> oraz cienie. Dzieci, wspólnie z artystami, zrealizowały serię bardzo interesujących prac obejmujących <a href="http://latowteatrzekrakow.blox.pl/2009/07/Warsztaty-muzyczneprowadzacy-Wojciech-Terechowicz.html">musical</a>, <a href="http://latowteatrzekrakow.blox.pl/2009/07/Warsztaty-z-teatru-cieni-w-Kinie-Wrzos-zajecia.html">teatr cieni</a> czy konstrukcję makiety Księżyca (fani Warhammera by się nie powstydzili <img src='http://temporal.pr0.pl/devblog/wp-includes/images/smilies/icon_smile.gif' alt=':)' class='wp-smiley' />  ) i trzech całkiem dobrze działających katapult. Organizatorem krakowskich zajęć jest <a href="http://www.teatrfigur.pl/">Teatr Figur</a> (strona padła, bo się rachunków nie zapłaciło <img src='http://temporal.pr0.pl/devblog/wp-includes/images/smilies/icon_smile.gif' alt=':)' class='wp-smiley' />  ).</p>
<p>Cieszę się, że taka akcja ma miejsce w Polsce. Zarówno nasi młodsi podopieczni mogą na tym wiele skorzystać (krakowskie przedstawienia były wykonane na prawdę rewelacyjnie) jak i starsi mogą się czegoś nauczyć &#8211; obcowania z kreatywnością nigdy za wiele. Ja się nieźle ubawiłem więc polecam wszystkim <img src='http://temporal.pr0.pl/devblog/wp-includes/images/smilies/icon_wink.gif' alt=';)' class='wp-smiley' /> . A tak w ogóle o Lecie w Teatrze dowiedziałem się dzięki <a href="http://www.flickr.com/photos/teatrfigurkrakow/sets/72157621501358891/">łapance ulicznej</a>, którą <a href="http://latowteatrzekrakow.blox.pl/2009/07/Final-pracy-grupyy-dziennikarsko-promocyjnej.html">przeprowadzała grupa dziennikarska</a>.</p>
]]></content:encoded>
			<wfw:commentRss>http://temporal.pr0.pl/devblog/2009/07/20/lato-w-teatrze/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Wspomaganie prezentacji &#8211; Office 2007 i OpenOffice.org</title>
		<link>http://temporal.pr0.pl/devblog/2009/07/19/wspomaganie-prezentacji-%e2%80%93-office-2007-i-openofficeorg/</link>
		<comments>http://temporal.pr0.pl/devblog/2009/07/19/wspomaganie-prezentacji-%e2%80%93-office-2007-i-openofficeorg/#comments</comments>
		<pubDate>Sat, 18 Jul 2009 22:39:54 +0000</pubDate>
		<dc:creator>Jacek Złydach</dc:creator>
				<category><![CDATA[Informatyka]]></category>
		<category><![CDATA[Varia]]></category>
		<category><![CDATA[life hacks]]></category>
		<category><![CDATA[narzędzia]]></category>
		<category><![CDATA[Office 2007]]></category>
		<category><![CDATA[OpenOffice.org]]></category>
		<category><![CDATA[porady]]></category>
		<category><![CDATA[PowerPoint]]></category>
		<category><![CDATA[prezentacje multimedialne]]></category>
		<category><![CDATA[Widok Prezentera]]></category>

		<guid isPermaLink="false">http://temporal.pr0.pl/devblog/?p=531</guid>
		<description><![CDATA[Ostatnio wypatrzyłem bardzo interesującą funkcję w PowerPoint 2007. Narzędzie to nazywa się &#8220;Widok prezentera&#8221; i może kiedyś usunie pewne zjawisko, które uważam za dość ciekawe (żeby nie powiedzieć: dziwne&#8230;) &#8211; otóż w typowej prezentacji multimedialnej prelegent wyświetla na rzutniku obraz z podłączonego komputera, po czym&#8230; bierze papierową wersję notatek i korzysta właśnie z nich. Ponadto, [...]]]></description>
			<content:encoded><![CDATA[<p>Ostatnio wypatrzyłem bardzo interesującą funkcję w PowerPoint 2007. Narzędzie to nazywa się <em>&#8220;Widok prezentera&#8221;</em> i może kiedyś usunie pewne zjawisko, które uważam za dość ciekawe (żeby nie powiedzieć: dziwne&#8230;) &#8211; otóż w typowej prezentacji multimedialnej prelegent wyświetla na rzutniku obraz z podłączonego komputera, po czym&#8230; bierze papierową wersję notatek i korzysta właśnie z nich. Ponadto, gdy przychodzi coś wskazać na prezentacji, zwykle dokonuje się magicznego rytuału machania rękami w powietrzu i czarowania wskaźniczkiem laserowym. Do maszyny podchodzi się tylko po to, by zmienić slajdy (a co sprytniejsi robią to pilotem lub telefonem komórkowym).</p>
<p>&#8220;Widok prezentera&#8221; dostępny w PowerPoint 2007 (i podobno także w PowerPoint 2003) udostępnia nam na ekranie naszego komputera:</p>
<ul>
<li><strong>Zegary</strong> &#8211; jeden z nich mierzy czas trwania prezentacji, drugi &#8211; pokazuje aktualną godzinę</li>
<li><strong>Notatki</strong> &#8211; adnotacje do slajdów wyświetlane są z prawej strony &#8211; można w nich umieścić te same punkty i uwagi, które zwykle mamy na kartce</li>
<li><strong>Zakreślacze i pismo odręczne</strong> &#8211; możemy szybko przekształcić wskaźnik myszki w narzędzie do pisania odręcznego lub zwykły <a href="http://en.wikipedia.org/wiki/Highlighter">zakreślacz </a>(taki gruby pisak, którym studenci lubią bazgrać po kserówkach</li>
</ul>
<p>Poniższy screen ilustruje użycie &#8220;Widoku prezentera&#8221; oraz jego funkcji zakreślacza.<br />
<center><a href="http://temporal.pr0.pl/devblog/download/varia/prezentacja.png" target="_blank"><img src="http://temporal.pr0.pl/devblog/download/varia/prezentacja_450px.png" alt="Przykład użycia Widoku Prezentera." /></a></center><br />
Z użyciem tego &#8220;widoku&#8221; można dokonywać prezentacji bez posiadania papierowej wersji głównych punktów i uwag pomocniczych. Ponadto zakreślenie bezpośrednio na prezentacji będzie dużo bardziej czytelne dla odbiorców niż używanie palca, kija, linijki lub wskaźniczka laserowego (któremu zwykle i tak w czasie pokazu kończy się bateria).</p>
<p>Ktoś powie, że papier jest wygodniejszy &#8211; jestem skłonny się zgodzić. Typowa forma prezentacji (także biznesowych!), jaką dotąd widziałem sprowadza się do postawienia laptopa na stoliku lub ławeczce. Korzystanie z komputera staje się dla prelegenta niewygodne i nieeleganckie (trzeba się schylać). Wydaje mi się jednak, że problem ten można obejść jeśli tylko się chce. Ponadto technologie takie jak ekrany dotykowe oraz laptopy-tablety (które można po prostu trzymać w ręce) mogą pomóc i ostatecznie wyrzucić nadmiarowy papier z prezentacji multimedialnych.</p>
<p>A co mają zrobić użytkownicy OpenOffice? Pod Windows można skorzystać z <a href="http://technet.microsoft.com/en-us/sysinternals/bb897434.aspx">narzędzia ZoomIt pakietu SysInternals</a> (czyli de-facto Microsoftu), który pozwala w sposób wygodny powiększać fragmenty obrazu oraz rysować po nich i wprowadzać tekst. Program ten radzi sobie dobrze z dwoma monitorami i może przydać się nie tylko podczas prezentacji w Impressie <img src='http://temporal.pr0.pl/devblog/wp-includes/images/smilies/icon_wink.gif' alt=';)' class='wp-smiley' /> .</p>
]]></content:encoded>
			<wfw:commentRss>http://temporal.pr0.pl/devblog/2009/07/19/wspomaganie-prezentacji-%e2%80%93-office-2007-i-openofficeorg/feed/</wfw:commentRss>
		<slash:comments>3</slash:comments>
		</item>
		<item>
		<title>Słoneczna strona Internetu ;)</title>
		<link>http://temporal.pr0.pl/devblog/2009/07/03/sloneczna-strona-internetu/</link>
		<comments>http://temporal.pr0.pl/devblog/2009/07/03/sloneczna-strona-internetu/#comments</comments>
		<pubDate>Fri, 03 Jul 2009 16:57:21 +0000</pubDate>
		<dc:creator>Jacek Złydach</dc:creator>
				<category><![CDATA[Varia]]></category>
		<category><![CDATA[Internet Provider]]></category>
		<category><![CDATA[Kazimierz]]></category>
		<category><![CDATA[Kraków]]></category>
		<category><![CDATA[sloneczko.net]]></category>
		<category><![CDATA[Słoneczko]]></category>

		<guid isPermaLink="false">http://temporal.pr0.pl/devblog/?p=511</guid>
		<description><![CDATA[Chciałbym uprzejmie podziękować firmie FHU Maja, prowadzącej serwis sloneczko.net, za udostępnienie mi maila w swojej domenie. Firma ta w ramach hasła &#8220;Internet na Kazimierzu&#8221; zapewnia dostęp do Internetu na terenie krakowskiej dzielnicy Kazimierz. Od dzisiaj można mnie osiągnąć pod adresem 
Niedługo wrócę z końcówką reportażu i jakimiś nowymi tekstami, a na razie wszystkim Czytelnikom życzę [...]]]></description>
			<content:encoded><![CDATA[<p>Chciałbym uprzejmie podziękować firmie <strong>FHU Maja</strong>, prowadzącej serwis <strong><a href="http://sloneczko.net">sloneczko.net</a></strong>, za udostępnienie mi maila w swojej domenie. Firma ta w ramach hasła <em>&#8220;Internet na Kazimierzu&#8221;</em> zapewnia dostęp do Internetu na terenie <a href="http://pl.wikipedia.org/wiki/Kazimierz_(Krak%C3%B3w)">krakowskiej dzielnicy Kazimierz</a>. Od dzisiaj można mnie osiągnąć pod adresem <img src="http://temporal.pr0.pl/devblog/download/slonecznymail.png" alt="Nowy e-mail" style="vertical-align: middle;" /></p>
<p>Niedługo wrócę z końcówką reportażu i jakimiś nowymi tekstami, a na razie wszystkim Czytelnikom życzę słonecznych wakacji <img src='http://temporal.pr0.pl/devblog/wp-includes/images/smilies/icon_wink.gif' alt=';)' class='wp-smiley' />  .</p>
]]></content:encoded>
			<wfw:commentRss>http://temporal.pr0.pl/devblog/2009/07/03/sloneczna-strona-internetu/feed/</wfw:commentRss>
		<slash:comments>1</slash:comments>
		</item>
		<item>
		<title>Stulecie Robotów w Krakowie &#8211; Reportaż, część 3</title>
		<link>http://temporal.pr0.pl/devblog/2009/06/15/stulecie-robotow-w-krakowie-reportaz-czesc-3/</link>
		<comments>http://temporal.pr0.pl/devblog/2009/06/15/stulecie-robotow-w-krakowie-reportaz-czesc-3/#comments</comments>
		<pubDate>Mon, 15 Jun 2009 17:24:22 +0000</pubDate>
		<dc:creator>Jacek Złydach</dc:creator>
				<category><![CDATA[Applied Science]]></category>
		<category><![CDATA[Informatyka]]></category>
		<category><![CDATA[Stulecie Robotów w Krakowie]]></category>
		<category><![CDATA[ATmega128]]></category>
		<category><![CDATA[C++]]></category>
		<category><![CDATA[FSM]]></category>
		<category><![CDATA[Galeria Krakowska]]></category>
		<category><![CDATA[Graupner Robotics]]></category>
		<category><![CDATA[maszyna stanów skończonych]]></category>
		<category><![CDATA[qfix]]></category>
		<category><![CDATA[reportaże]]></category>
		<category><![CDATA[roboty]]></category>
		<category><![CDATA[SoccerBoard]]></category>
		<category><![CDATA[Stulecie Robotów]]></category>
		<category><![CDATA[sztuczna inteligencja]]></category>

		<guid isPermaLink="false">http://temporal.pr0.pl/devblog/?p=448</guid>
		<description><![CDATA[(kontynuacja tematu o Festiwalu Robotów w Krakowie)
(Stulecie Robotów &#8211; Galeria)
(]]></description>
			<content:encoded><![CDATA[<p><em><a href="http://temporal.pr0.pl/devblog/2009/06/06/stulecie-robotow-w-krakowie-reportaz-czesc-1/">(kontynuacja tematu o Festiwalu Robotów w Krakowie)</a><br />
<em><a href="http://temporal.pr0.pl/devblog/galerie/stulecie-robotow-w-krakowie/">(Stulecie Robotów &#8211; Galeria)</a></em><br />
(<a href="http://temporal.pr0.pl/devblog/2009/06/07/stulecie-robotow-w-krakowie-reportaz-czesc-2/"><< poprzednia część</a>)</em></p>
<p><img src="http://temporal.pr0.pl/devblog/download/roboty_krakow/stulecie_vsmall.jpg" alt="Stulecie Robotów - logo" width="100"  style="float: left; margin-right: 15px;" /></p>
<p>Wrzuciłem <a href="http://temporal.pr0.pl/devblog/galerie/stulecie-robotow-w-krakowie/">troszkę nowych zdjęć do galerii</a>. Pojawiły się też pierwsze filmiki, ale o tym później <img src='http://temporal.pr0.pl/devblog/wp-includes/images/smilies/icon_smile.gif' alt=':)' class='wp-smiley' /> . W tej części reportażu opisuję osobiste zmagania z robotem Graupnera, które okazały się wielkim sukcesem (<a href="http://www.youtube.com/watch?v=Y6ljFaKRTrI">&#8220;I&#8217;m making a note here: HUGE SUCCESS&#8221;</a>) i doprowadziły do sytuacji, w której robot z zamontowanym aparatem cyfrowym rozbijał się po sklepach w Galerii Krakowskiej <img src='http://temporal.pr0.pl/devblog/wp-includes/images/smilies/icon_smile.gif' alt=':)' class='wp-smiley' /> .</p>
<p><center><strong>Starcie Trzecie &#8211; Sobota, 06.06.2009</strong></center><br />
Tym razem spędziłem w Galerii praktycznie cały dzień, intensywnie pracując nad uruchomionym już robotem Graupnera. Zaczęło się od prostych programików testowych, które pozwoliły mi ocenić funkcjonowanie silników i przycisków na płytce oraz ogólną mechanikę pracy z robotem. Mając już tę podstawową wiedzę zabrałem się za kolejny etap zabawy&#8230;</p>
<p><strong>Kalibracja czujników odległości</strong><br />
Przede mną znajdowały się czujniki odległości. Z instrukcji po niemiecku dowiedziałem się tylko tyle, że działają na podczerwień i mierzą odległość w granicach 4-30cm. Jego obłsuga, podobnie jak każdego innego analogowego czujnika na tej płytce sprowadzała się do wywołania funkcji, która zwracała wartość od 0 do 255. Nigdzie w dokumentacji nie podano, jak mają się te wskazania (0..255) do odległości wyrażonej w metrach (nie była podana tzw. <em>charakterystyki czujnika</em>). Zmierzyłem ją więc eksperymentalnie. Po stwierdzeniu, że większe wartości występują, gdy wykryty obiekt znajduje się bliżej czujnika posłużyłem się linijką i poniższym kodem:</p>
<div class="codecolorer-container cpp default" style="overflow:auto;white-space:nowrap;border:1px solid #9F9F9F;width:435px;"><div class="cpp codecolorer" style="padding:5px;font:normal 12px/1.4em Monaco, Lucida Console, monospace;white-space:nowrap"><span style="color: #0000ff;">while</span><span style="color: #008000;">&#40;</span><span style="color: #0000dd;">1</span><span style="color: #008000;">&#41;</span><br />
<span style="color: #008000;">&#123;</span><br />
&nbsp; &nbsp; <span style="color: #0000ff;">if</span><span style="color: #008000;">&#40;</span>board.<span style="color: #007788;">GetMainBoard</span><span style="color: #008000;">&#40;</span><span style="color: #008000;">&#41;</span>.<span style="color: #007788;">analog</span><span style="color: #008000;">&#40;</span><span style="color: #0000dd;">7</span><span style="color: #008000;">&#41;</span> <span style="color: #000080;">&gt;</span> FORWARD_THRESHOLD<span style="color: #008000;">&#41;</span><br />
&nbsp; &nbsp; <span style="color: #008000;">&#123;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; board.<span style="color: #007788;">GetMainBoard</span><span style="color: #008000;">&#40;</span><span style="color: #008000;">&#41;</span>.<span style="color: #007788;">motor</span><span style="color: #008000;">&#40;</span><span style="color: #0000dd;">0</span>, <span style="color: #0000dd;">255</span><span style="color: #008000;">&#41;</span><span style="color: #008080;">;</span><br />
&nbsp; &nbsp; <span style="color: #008000;">&#125;</span><br />
&nbsp; &nbsp; <span style="color: #0000ff;">else</span><br />
&nbsp; &nbsp; <span style="color: #008000;">&#123;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; board.<span style="color: #007788;">GetMainBoard</span><span style="color: #008000;">&#40;</span><span style="color: #008000;">&#41;</span>.<span style="color: #007788;">motorsOff</span><span style="color: #008000;">&#40;</span><span style="color: #008000;">&#41;</span><span style="color: #008080;">;</span><br />
&nbsp; &nbsp; <span style="color: #008000;">&#125;</span><br />
<span style="color: #008000;">&#125;</span></div></div>
<p>Jak nie trudno zauważyć, regulując parametr <em>FORWARD_THRESHOLD</em> zmieniałem moment, w którym uruchamiały się silniczki. Po rozciągnięciu składanej kilkumetrowej linijki mierzyłem więc czujnik ręką, badając w którym momencie zaczyna on wskazywać zadaną w <em>FORWARD_THRESHOLD</em> wartość. W ten sposób uzyskałem 10 punktów, układających się w mniej-więcej w eksponentę <img src='http://temporal.pr0.pl/devblog/wp-includes/images/smilies/icon_wink.gif' alt=';)' class='wp-smiley' /> .<br />
<center><a href="http://temporal.pr0.pl/devblog/download/roboty_krakow/charakterystyka.png" target="_blank"><img src="http://temporal.pr0.pl/devblog/download/roboty_krakow/charakterystyka_small.png" alt="Doświadczalnie zmierzona charakterystyka czujnika odległości." /></a></center><br />
Mając te próbki mogłem już wyznaczyć przybliżoną odległość dla dowolnego wskazania czujników w mierzonym zakresie oraz spodziewane wskazanie czujników dla dowolnej podanej odległości &#8211; wszystko to oczywiście za pomocą magicznej sztuczki zwanej <em>liniową interpolacją</em><a name="POST_STULECIE_ROBOTOW_W_KRAKOWIE_REP3_MT_1" href="#POST_STULECIE_ROBOTOW_W_KRAKOWIE_REP3_REF_1">*</a>, o mniej więcej w ten sposób:</p>
<div class="codecolorer-container cpp default" style="overflow:auto;white-space:nowrap;border:1px solid #9F9F9F;width:435px;height:300px;"><div class="cpp codecolorer" style="padding:5px;font:normal 12px/1.4em Monaco, Lucida Console, monospace;white-space:nowrap"><span style="color: #666666;">//(...)</span><br />
<span style="color: #666666;">//gdzies tam w konstruktorze:</span><br />
<span style="color: #666666;">//set up ir sensor data</span><br />
irSensorSettings<span style="color: #008000;">&#91;</span><span style="color: #0000dd;">0</span><span style="color: #008000;">&#93;</span> <span style="color: #000080;">=</span> <span style="color: #0000dd;">0</span><span style="color: #008080;">;</span> &nbsp; &nbsp;irSensorRanges<span style="color: #008000;">&#91;</span><span style="color: #0000dd;">0</span><span style="color: #008000;">&#93;</span> <span style="color: #000080;">=</span> <span style="color:#800080;">1.3f</span><span style="color: #008080;">;</span><br />
irSensorSettings<span style="color: #008000;">&#91;</span><span style="color: #0000dd;">1</span><span style="color: #008000;">&#93;</span> <span style="color: #000080;">=</span> <span style="color: #0000dd;">12</span><span style="color: #008080;">;</span> &nbsp; irSensorRanges<span style="color: #008000;">&#91;</span><span style="color: #0000dd;">1</span><span style="color: #008000;">&#93;</span> <span style="color: #000080;">=</span> <span style="color:#800080;">0.65f</span><span style="color: #008080;">;</span><br />
irSensorSettings<span style="color: #008000;">&#91;</span><span style="color: #0000dd;">2</span><span style="color: #008000;">&#93;</span> <span style="color: #000080;">=</span> <span style="color: #0000dd;">15</span><span style="color: #008080;">;</span> &nbsp; irSensorRanges<span style="color: #008000;">&#91;</span><span style="color: #0000dd;">2</span><span style="color: #008000;">&#93;</span> <span style="color: #000080;">=</span> <span style="color:#800080;">0.34f</span><span style="color: #008080;">;</span><br />
irSensorSettings<span style="color: #008000;">&#91;</span><span style="color: #0000dd;">3</span><span style="color: #008000;">&#93;</span> <span style="color: #000080;">=</span> <span style="color: #0000dd;">25</span><span style="color: #008080;">;</span> &nbsp; irSensorRanges<span style="color: #008000;">&#91;</span><span style="color: #0000dd;">3</span><span style="color: #008000;">&#93;</span> <span style="color: #000080;">=</span> <span style="color:#800080;">0.30f</span><span style="color: #008080;">;</span><br />
irSensorSettings<span style="color: #008000;">&#91;</span><span style="color: #0000dd;">4</span><span style="color: #008000;">&#93;</span> <span style="color: #000080;">=</span> <span style="color: #0000dd;">30</span><span style="color: #008080;">;</span> &nbsp; irSensorRanges<span style="color: #008000;">&#91;</span><span style="color: #0000dd;">4</span><span style="color: #008000;">&#93;</span> <span style="color: #000080;">=</span> <span style="color:#800080;">0.24f</span><span style="color: #008080;">;</span><br />
irSensorSettings<span style="color: #008000;">&#91;</span><span style="color: #0000dd;">5</span><span style="color: #008000;">&#93;</span> <span style="color: #000080;">=</span> <span style="color: #0000dd;">40</span><span style="color: #008080;">;</span> &nbsp; irSensorRanges<span style="color: #008000;">&#91;</span><span style="color: #0000dd;">5</span><span style="color: #008000;">&#93;</span> <span style="color: #000080;">=</span> <span style="color:#800080;">0.16f</span><span style="color: #008080;">;</span><br />
irSensorSettings<span style="color: #008000;">&#91;</span><span style="color: #0000dd;">6</span><span style="color: #008000;">&#93;</span> <span style="color: #000080;">=</span> <span style="color: #0000dd;">50</span><span style="color: #008080;">;</span> &nbsp; irSensorRanges<span style="color: #008000;">&#91;</span><span style="color: #0000dd;">6</span><span style="color: #008000;">&#93;</span> <span style="color: #000080;">=</span> <span style="color:#800080;">0.13f</span><span style="color: #008080;">;</span><br />
irSensorSettings<span style="color: #008000;">&#91;</span><span style="color: #0000dd;">7</span><span style="color: #008000;">&#93;</span> <span style="color: #000080;">=</span> <span style="color: #0000dd;">75</span><span style="color: #008080;">;</span> &nbsp; irSensorRanges<span style="color: #008000;">&#91;</span><span style="color: #0000dd;">7</span><span style="color: #008000;">&#93;</span> <span style="color: #000080;">=</span> <span style="color:#800080;">0.08f</span><span style="color: #008080;">;</span><br />
irSensorSettings<span style="color: #008000;">&#91;</span><span style="color: #0000dd;">8</span><span style="color: #008000;">&#93;</span> <span style="color: #000080;">=</span> <span style="color: #0000dd;">100</span><span style="color: #008080;">;</span>&nbsp; irSensorRanges<span style="color: #008000;">&#91;</span><span style="color: #0000dd;">8</span><span style="color: #008000;">&#93;</span> <span style="color: #000080;">=</span> <span style="color:#800080;">0.06f</span><span style="color: #008080;">;</span><br />
irSensorSettings<span style="color: #008000;">&#91;</span><span style="color: #0000dd;">9</span><span style="color: #008000;">&#93;</span> <span style="color: #000080;">=</span> <span style="color: #0000dd;">150</span><span style="color: #008080;">;</span>&nbsp; irSensorRanges<span style="color: #008000;">&#91;</span><span style="color: #0000dd;">9</span><span style="color: #008000;">&#93;</span> <span style="color: #000080;">=</span> <span style="color:#800080;">0.025f</span><span style="color: #008080;">;</span><br />
<span style="color: #666666;">//(...)</span><br />
<span style="color: #666666;">//magiczna funkcja:</span><br />
<span style="color: #0000ff;">int</span> GetIRThresholdForDistance<span style="color: #008000;">&#40;</span><span style="color: #0000ff;">float</span> distance<span style="color: #008000;">&#41;</span><br />
<span style="color: #008000;">&#123;</span><br />
&nbsp; &nbsp; <span style="color: #0000ff;">for</span><span style="color: #008000;">&#40;</span><span style="color: #0000ff;">int</span> i <span style="color: #000080;">=</span> <span style="color: #0000dd;">1</span> <span style="color: #008080;">;</span> i <span style="color: #000080;">&lt;</span> IR_SENSOR_SAMPLES <span style="color: #008080;">;</span> <span style="color: #000040;">++</span>i<span style="color: #008000;">&#41;</span><br />
&nbsp; &nbsp; <span style="color: #008000;">&#123;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #0000ff;">if</span><span style="color: #008000;">&#40;</span>distance <span style="color: #000080;">&gt;</span> irSensorRanges<span style="color: #008000;">&#91;</span>i<span style="color: #008000;">&#93;</span><span style="color: #008000;">&#41;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #008000;">&#123;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #0000ff;">float</span> scale <span style="color: #000080;">=</span> <span style="color: #008000;">&#40;</span>distance <span style="color: #000040;">-</span> irSensorRanges<span style="color: #008000;">&#91;</span>i<span style="color: #008000;">&#93;</span><span style="color: #008000;">&#41;</span><span style="color: #000040;">/</span><span style="color: #008000;">&#40;</span>irSensorRanges<span style="color: #008000;">&#91;</span>i<span style="color: #000040;">-</span><span style="color: #0000dd;">1</span><span style="color: #008000;">&#93;</span> <span style="color: #000040;">-</span> irSensorRanges<span style="color: #008000;">&#91;</span>i<span style="color: #008000;">&#93;</span><span style="color: #008000;">&#41;</span><span style="color: #008080;">;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #0000ff;">return</span> <span style="color: #0000ff;">static_cast</span><span style="color: #000080;">&lt;</span><span style="color: #0000ff;">int</span><span style="color: #000080;">&gt;</span><span style="color: #008000;">&#40;</span>irSensorSettings<span style="color: #008000;">&#91;</span>i<span style="color: #008000;">&#93;</span><span style="color: #000040;">*</span><span style="color: #008000;">&#40;</span>scale<span style="color: #008000;">&#41;</span> <span style="color: #000040;">+</span> irSensorSettings<span style="color: #008000;">&#91;</span>i<span style="color: #000040;">-</span><span style="color: #0000dd;">1</span><span style="color: #008000;">&#93;</span><span style="color: #000040;">*</span><span style="color: #008000;">&#40;</span><span style="color:#800080;">1.0f</span><span style="color: #000040;">-</span>scale<span style="color: #008000;">&#41;</span><span style="color: #008000;">&#41;</span><span style="color: #008080;">;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #008000;">&#125;</span><br />
&nbsp; &nbsp; <span style="color: #008000;">&#125;</span><br />
&nbsp; &nbsp; <span style="color: #0000ff;">return</span> <span style="color: #0000dd;">0</span><span style="color: #008080;">;</span><br />
<span style="color: #008000;">&#125;</span></div></div>
<p>Pomiary nie były szczególnie dokładne, ale biorąc pod uwagę, że przedział od 2 centymetrów do ponad 1.5 metra mieści się w zakresie od 0 do 150 stwierdzam, że przybliżenie jest wystarczające <img src='http://temporal.pr0.pl/devblog/wp-includes/images/smilies/icon_smile.gif' alt=':)' class='wp-smiley' /> . Wartości powyżej 150 nie mierzyłem częściowo z braku potrzeby, a częściowo z tego, że różnice między kolejnymi wartościami wynosiłyby teoretycznie ułamki centymetra. Uzyskane pomiary błyskawicznie zweryfikowałem w praktyce i okazały się one wystarczająco dobre, by robot mógł się poruszać w terenie. Postanowiłem więc napisać&#8230;</p>
<p><strong>Proste AI robota</strong><br />
Rzeczywiście, chociaż w konstrukcji jest ono stosunkowo proste, to w praktyce przerosło (pozytywnie) moje oczekiwania. Inteligencję robota zapewniała prosta maszyna stanów<a name="POST_STULECIE_ROBOTOW_W_KRAKOWIE_REP3_MT_2" href="#POST_STULECIE_ROBOTOW_W_KRAKOWIE_REP3_REF_2">**</a>. Konstrukcję robota i skończoną maszynę stanów ilustruje poniższy schemat:<br />
<center><a href="http://temporal.pr0.pl/devblog/download/roboty_krakow/robot_schemat.png" target="_blank"><img src="http://temporal.pr0.pl/devblog/download/roboty_krakow/robot_schemat_small.png" alt="Schemat konstrukcji robota oraz jego oprogramowania." /></a></center><br />
Stan <strong>Wandering Around</strong> <em>(ang. wędrówka po okolicy)</em> to po prostu spacer w kółko &#8211; robot najpierw porusza się dwie sekundy przed siebie, by następnie skręcić w losowym kierunku przez pół sekundy. W międzyczasie czujniki odległości odpytywane są 10 razy na sekundę i w sytuacji, w której odległość od najbliższego obiektu spadnie poniżej ustalonej wartości następuje natychmiastowe przełączenie stanu na <strong>Evade</strong> <em>(ang. unikaj)</em>. Stan ten obsługuje omijanie obiektów, które znalazły się zbyt blisko. Zależnie od tego, na którym czujniku wykryto obiekt wybrany zostaje odpowiedni kierunek unikania. Robot następnie wykonuje manewr. Pojedyncza iteracja tego stanu trwa około 100ms &#8211; mniej więcej tak często robot sprawdza czujniki. Jeżeli potencjalna przeszkoda znalazła się wystarczająco daleko, robot wraca do stanu <strong>Wandering Around</strong>. Jeśli natomiast czujnik wykrył jakiś obiekt ekstremalnie blisko robota, włączony zostaje stan <strong>Run Like Hell</strong> &#8211; awaryjna ucieczka. W tym stanie robot z piskiem (dosłownie &#8211; <a href="http://en.wikipedia.org/wiki/Buzzer">beeper</a>) ucieka w kierunku przeciwnym do tego, z którego wykryto zagrożenie. Pojedyncza iteracja stanu trwa pół sekundy &#8211; przez ten czas robot nie sprawdza okolicy, co w ekstremalnych przypadkach może skończyć się uderzeniem w inną przeszkodę przy wycofywaniu się. Gdy zagrożenie minie, robot przełącza się w stan <strong>Wandering Around</strong>.</p>
<p><center><a href="http://temporal.pr0.pl/devblog/download/roboty_krakow/TRCSoccerBot.jpg" target="_blank"><img src="http://temporal.pr0.pl/devblog/download/roboty_krakow/TRCSoccerBot_small.jpg" alt="Robot, którego programowałem." /><br />
<em>Robot, którego programowałem</em></a></center></p>
<p>Ten prosty system okazał się niewiarygodnie skuteczny w terenie. Pierwsze testy na arenie pokazały, że ściany i ręce małych dzieci są dla robota praktycznie niegroźne (jedyny problem sprawiały duże roboty, które miały korpus powyżej linii czujników). Niezłym wyzwaniem była nawet próba złapania robota na tej arenie, by go wyłączyć <img src='http://temporal.pr0.pl/devblog/wp-includes/images/smilies/icon_smile.gif' alt=':)' class='wp-smiley' /> . Jednak na prawdę ciekawie zrobiło się gdy robot, uzbrojony w aparat cyfrowy, wyruszył na spacer po Galerii. Samodzielnie poruszał się między ludźmi (ku wielkiej uciesze kilkulatków), zwiedził też kilka sklepów. Poniżej dwa filmiki &#8211; jeden z areny, drugi z jazdy po Galerii:<br />
<center><object width="425" height="344"><param name="movie" value="http://www.youtube.com/v/SJhNz0cEPxo&#038;hl=pl&#038;fs=1&#038;color1=0x006699&#038;color2=0x54abd6"></param><param name="allowFullScreen" value="true"></param><param name="allowscriptaccess" value="always"></param><embed src="http://www.youtube.com/v/SJhNz0cEPxo&#038;hl=pl&#038;fs=1&#038;color1=0x006699&#038;color2=0x54abd6" type="application/x-shockwave-flash" allowscriptaccess="always" allowfullscreen="true" width="425" height="344"></embed></object></center><br />
<center><object width="425" height="344"><param name="movie" value="http://www.youtube.com/v/bZHYdd_jiOQ&#038;hl=pl&#038;fs=1&#038;color1=0x006699&#038;color2=0x54abd6"></param><param name="allowFullScreen" value="true"></param><param name="allowscriptaccess" value="always"></param><embed src="http://www.youtube.com/v/bZHYdd_jiOQ&#038;hl=pl&#038;fs=1&#038;color1=0x006699&#038;color2=0x54abd6" type="application/x-shockwave-flash" allowscriptaccess="always" allowfullscreen="true" width="425" height="344"></embed></object></center><br />
Na koniec jeszcze uwaga o stronie implementacyjnej &#8211; całą maszynę stanów oparłem (głównie dla szybkości pisania) o wskaźnik do funkcji <img src='http://temporal.pr0.pl/devblog/wp-includes/images/smilies/icon_smile.gif' alt=':)' class='wp-smiley' />  . Nie jest to może szczególnie elastyczne, ale działa świetnie <img src='http://temporal.pr0.pl/devblog/wp-includes/images/smilies/icon_smile.gif' alt=':)' class='wp-smiley' />  .<br />
Zbierając do kupy różne fragmenty kodu stworzyłem w końcu pierwszą próbę rozszerzenia API dla robotów SoccerBoard. Omawiany wyżej program, wraz z TRC SoccerBoard API 1.0 można ściągnąć z poniższego linka:<br />
<a href="http://temporal.pr0.pl/devblog/download/roboty_krakow/roboty_src1.zip">(źródła)</a></p>
<p>Gdzieś pomiędzy tym wszystkim obsługa zaczęła mi podsuwać informacje, że ponoć te roboty mogą być zdalnie sterowane. Pytali się mnie, czy nie byłbym im w stanie tego uruchomić&#8230;</p>
<p><em>Ciąg dalszy nastąpi&#8230;</em></p>
<p><strong>Przypisy:</strong><br />
<a name="POST_STULECIE_ROBOTOW_W_KRAKOWIE_REP3_REF_1" href="#POST_STULECIE_ROBOTOW_W_KRAKOWIE_REP3_MT_1">*</a> &#8211; Przeraża mnie fakt, który zaobserwowałem, że sporo osób zetknęło się z pojęciem interpolacji w szkole lub na studiach i kojarzą ją jedynie z &#8216;dziwnymi wzorami&#8217; Lagrange&#8217;a i Newtona, podczas gdy nie umieją w żaden sposób wyobrazić jej sobie w praktyce. Wspomnę coś na ten temat niedługo, stay tuned <img src='http://temporal.pr0.pl/devblog/wp-includes/images/smilies/icon_smile.gif' alt=':)' class='wp-smiley' /> .</p>
<p><a name="POST_STULECIE_ROBOTOW_W_KRAKOWIE_REP3_REF_2" href="#POST_STULECIE_ROBOTOW_W_KRAKOWIE_REP3_MT_2">**</a> &#8211; Niektórzy Czytelnicy mogą nie być zaznajomieni z koncepcją maszyny stanów skończonych <em>(ang. Finite State Machine)</em>. Żeby nie sypać skomplikowanymi definicjami z Wikipedii, powiem krótko &#8211; prostym (i typowym) przykładem FSM jest&#8230; <strong>żarówka w pokoju</strong>. Jako obiekt ma dwa <strong>stany wewnętrzne</strong> &#8211; może być zapalona lub zgaszona. Zależnie od stanu inaczej się zachowuje (zapalona &#8211; świeci i grzeje się, zgaszona &#8211; nie świeci i stygnie). Ustalone są też <strong>przejścia między stanami</strong> &#8211; używając włącznika możemy przełączyć żarówkę ze stanu <em>świeci się</em> na stan <em>nie świeci się</em> i odwrotnie. Projektując FSM rysuje się często grafy podobne do tego, który znalazł się też w tym poście.</p>
]]></content:encoded>
			<wfw:commentRss>http://temporal.pr0.pl/devblog/2009/06/15/stulecie-robotow-w-krakowie-reportaz-czesc-3/feed/</wfw:commentRss>
		<slash:comments>2</slash:comments>
		</item>
		<item>
		<title>Wirujące czarne dziury</title>
		<link>http://temporal.pr0.pl/devblog/2009/06/11/wirujace-czarne-dziury/</link>
		<comments>http://temporal.pr0.pl/devblog/2009/06/11/wirujace-czarne-dziury/#comments</comments>
		<pubDate>Thu, 11 Jun 2009 17:42:54 +0000</pubDate>
		<dc:creator>Jacek Złydach</dc:creator>
				<category><![CDATA[Humor]]></category>
		<category><![CDATA[Varia]]></category>
		<category><![CDATA[astrofizyka]]></category>
		<category><![CDATA[komiks]]></category>
		<category><![CDATA[proces Penrose'a]]></category>
		<category><![CDATA[wirujące czarne dziury]]></category>

		<guid isPermaLink="false">http://temporal.pr0.pl/devblog/?p=436</guid>
		<description><![CDATA[Dzisiaj czytając pewną książkę popularnonaukową dowiedziałem się, że według jednej z teorii obracająca się czarna dziura tworzy coś w rodzaju &#8216;wirowego&#8217; pola grawitacyjnego (zwanego też wirem grawitacyjnym), które zmusza inne ciała do poruszania się wokół niej. W tej samej książce powiedziano, że odpowiednio wycelowana wiązka promieniowania elektromagnetycznego (w tym np. światła widzialnego) jest w stanie [...]]]></description>
			<content:encoded><![CDATA[<p>Dzisiaj czytając pewną książkę popularnonaukową dowiedziałem się, że według jednej z teorii obracająca się <a href="http://pl.wikipedia.org/wiki/Czarna_dziura">czarna dziura</a> tworzy coś w rodzaju &#8216;wirowego&#8217; pola grawitacyjnego (zwanego też wirem grawitacyjnym), które zmusza inne ciała do poruszania się wokół niej. W tej samej książce powiedziano, że odpowiednio wycelowana wiązka <a href="http://pl.wikipedia.org/wiki/Promieniowanie_elektromagnetyczne">promieniowania elektromagnetycznego</a> (w tym np. światła widzialnego) jest w stanie przelecieć w pobliżu takiej obracającej się czarnej dziury i polecieć dalej, podkradając część jej grawitacyjnej energii (tym samym energia wiązki się powiększa, a szybkość obrotu czarnej dziury maleje). To teoretyczne zjawisko &#8211; podbieranie energii z wirującej czarnej dziury &#8211; zwane jest <a href="http://en.wikipedia.org/wiki/Penrose_process">procesem Penrose&#8217;a</a>. Oczywiście nie trzeba długo tłumaczyć jego konsekwencji:<br />
<a href="http://temporal.pr0.pl/devblog/download/varia/komiks_penrose.png"><img src="http://temporal.pr0.pl/devblog/download/varia/komiks_penrose.png" alt="Aby zwykły wskaźnik laserowy zamienić w kilkumegawatowy laser wystarczy przelecieć obok czarnej dziury 528 razy przy założeniu, że wiązka jest idealnie skoncentrowana i nie rozprasza się wraz z przebytą odległością." target="_blank" /></a></p>
]]></content:encoded>
			<wfw:commentRss>http://temporal.pr0.pl/devblog/2009/06/11/wirujace-czarne-dziury/feed/</wfw:commentRss>
		<slash:comments>2</slash:comments>
		</item>
		<item>
		<title>Wolfram Alpha i Google na jednej stronie!</title>
		<link>http://temporal.pr0.pl/devblog/2009/06/09/wolfram-alpha-i-google-na-jednej-stronie/</link>
		<comments>http://temporal.pr0.pl/devblog/2009/06/09/wolfram-alpha-i-google-na-jednej-stronie/#comments</comments>
		<pubDate>Tue, 09 Jun 2009 11:21:34 +0000</pubDate>
		<dc:creator>Jacek Złydach</dc:creator>
				<category><![CDATA[Varia]]></category>
		<category><![CDATA[Firefox]]></category>
		<category><![CDATA[Google]]></category>
		<category><![CDATA[porady]]></category>
		<category><![CDATA[Wolfram|Alpha]]></category>
		<category><![CDATA[wtyczki]]></category>

		<guid isPermaLink="false">http://temporal.pr0.pl/devblog/?p=428</guid>
		<description><![CDATA[Ostatnio głośno w sieci o nowej wyszukiwarce &#8211; Wolfram&#124;Alpha. Dzisiaj skorzystałem z niej po raz pierwszy i się zachwyciłem  . Chciałbym się podzielić z Wami pewnym znaleziskiem &#8211; pod tym linkiem: (link) można ściągnąć dodatek do Firefoksa, który wyświetla wyniki wyszukiwania Google i Wolfram&#124;Alpha na jednej stronie. O tak:

Dodatek (w jakiś tam sposób) wykrywa [...]]]></description>
			<content:encoded><![CDATA[<p>Ostatnio głośno w sieci o nowej wyszukiwarce &#8211; <a href="http://www.wolframalpha.com/">Wolfram|Alpha</a>. Dzisiaj skorzystałem z niej po raz pierwszy i się zachwyciłem <img src='http://temporal.pr0.pl/devblog/wp-includes/images/smilies/icon_wink.gif' alt=';)' class='wp-smiley' /> . Chciałbym się podzielić z Wami pewnym znaleziskiem &#8211; <a href="https://addons.mozilla.org/pl/firefox/addon/12006">pod tym linkiem: (link)</a> można ściągnąć dodatek do Firefoksa, który wyświetla wyniki wyszukiwania Google i Wolfram|Alpha na jednej stronie. O tak:</p>
<p><center><a href="http://temporal.pr0.pl/devblog/download/varia/wolframik.png" target="_blank"><img src="http://temporal.pr0.pl/devblog/download/varia/wolframik_small.png" alt="Wolfram i Google na jednej stronie - screen" /></a></center></p>
<p>Dodatek (w jakiś tam sposób) wykrywa stronę wyszukiwania Google i w elegancki sposób dokleja obok Wolframa &#8211; działa więc zarówno przy wpisywaniu zapytania bezpośrednio na stronie Google jak i przy skorzystaniu z listy wyszukiwarek na pasku narzędzi przeglądarki.<br />
Have fun <img src='http://temporal.pr0.pl/devblog/wp-includes/images/smilies/icon_smile.gif' alt=':)' class='wp-smiley' /> </p>
<p><ins datetime="2009-06-13T08:30:20+00:00"><strong>EDIT (13.06.2009)</strong></ins><br />
Wygląda na to, że od dzisiaj plugin nie działa jak trzeba &#8211; w momencie, gdy wygenerują się wyniki Wolframa, użytkownik zostaje nagle przeniesiony na stronę wyszukiwania WolframAlpha. Efekt ten występuje od kilku-kilkunastu godzin co potwierdza zarówno <a href="http://temporal.pr0.pl/devblog/2009/06/09/wolfram-alpha-i-google-na-jednej-stronie/comment-page-1/#comment-12890">komentarz Plokina</a>, <a href="https://addons.mozilla.org/pl/firefox/reviews/display/12006">recenzja na stronie pluginu</a> jak i fakt, że wczoraj rano &#8211; jak to się mówi &#8211; jeszcze mi działało <img src='http://temporal.pr0.pl/devblog/wp-includes/images/smilies/icon_wink.gif' alt=';)' class='wp-smiley' /> . Podejrzewam, że to Wolfram &#8211; świadomie lub nie &#8211; zepsuł plugin zmieniając coś na swojej stronie. Anyway, chwilowo, plugin <em>nie</em> działa <img src='http://temporal.pr0.pl/devblog/wp-includes/images/smilies/icon_sad.gif' alt=':(' class='wp-smiley' />  .</p>
<p><ins datetime="2009-06-13T08:30:20+00:00"><strong>EDIT (14.06.2009)</strong></ins><br />
Plugin znów działa &#8211; poprawka zapewne dokonała się po stronie Wolframa, gdyż nie ściągałem nowej wersji a na stronie pluginu nie ma wzmianki o naprawieniu problemu.</p>
]]></content:encoded>
			<wfw:commentRss>http://temporal.pr0.pl/devblog/2009/06/09/wolfram-alpha-i-google-na-jednej-stronie/feed/</wfw:commentRss>
		<slash:comments>2</slash:comments>
		</item>
		<item>
		<title>Stulecie Robotów w Krakowie &#8211; Reportaż, część 2</title>
		<link>http://temporal.pr0.pl/devblog/2009/06/07/stulecie-robotow-w-krakowie-reportaz-czesc-2/</link>
		<comments>http://temporal.pr0.pl/devblog/2009/06/07/stulecie-robotow-w-krakowie-reportaz-czesc-2/#comments</comments>
		<pubDate>Sun, 07 Jun 2009 16:58:39 +0000</pubDate>
		<dc:creator>Jacek Złydach</dc:creator>
				<category><![CDATA[Applied Science]]></category>
		<category><![CDATA[Informatyka]]></category>
		<category><![CDATA[Stulecie Robotów w Krakowie]]></category>
		<category><![CDATA[ATmega128]]></category>
		<category><![CDATA[C++]]></category>
		<category><![CDATA[Galeria Krakowska]]></category>
		<category><![CDATA[Graupner Robotics]]></category>
		<category><![CDATA[Lego Mindstorms]]></category>
		<category><![CDATA[NextGEN Gallery]]></category>
		<category><![CDATA[qfix]]></category>
		<category><![CDATA[reportaże]]></category>
		<category><![CDATA[roboty]]></category>
		<category><![CDATA[SoccerBoard]]></category>
		<category><![CDATA[Stulecie Robotów]]></category>

		<guid isPermaLink="false">http://temporal.pr0.pl/devblog/?p=394</guid>
		<description><![CDATA[(kontynuacja tematu o Festiwalu Robotów w Krakowie)
(Stulecie Robotów &#8211; Galeria)
(]]></description>
			<content:encoded><![CDATA[<p><em><a href="http://temporal.pr0.pl/devblog/2009/06/06/stulecie-robotow-w-krakowie-reportaz-czesc-1/">(kontynuacja tematu o Festiwalu Robotów w Krakowie)</a><br />
<em><a href="http://temporal.pr0.pl/devblog/galerie/stulecie-robotow-w-krakowie/">(Stulecie Robotów &#8211; Galeria)</a></em><br />
(<a href="http://temporal.pr0.pl/devblog/2009/06/06/stulecie-robotow-w-krakowie-reportaz-czesc-1/"><< poprzednia część</a>)</em></p>
<p>Oto kolejna część reportażu z imprezy Stulecie Robotów. W ramach testu <a href="http://alexrabe.boelinger.com/wordpress-plugins/nextgen-gallery/">plugina NextGEN Gallery</a> wrzuciłem kilka pierwszych zdjęć z tego wydarzenia. Niedługo pojawią się filmiki, stay tuned&#8230; <img src='http://temporal.pr0.pl/devblog/wp-includes/images/smilies/icon_smile.gif' alt=':)' class='wp-smiley' /> </p>
<p><center><strong>Starcie Drugie &#8211; Czwartek, 04.06.2009</strong></center><br />
Niedługo później, bo w czwartek (04.06.2009) wróciłem do Galerii by zająć się budową robotów. Przyszedłem dość późno, gdyż miałem tego dnia egzamin zerowy z Podstaw Sterowania <img src='http://temporal.pr0.pl/devblog/wp-includes/images/smilies/icon_wink.gif' alt=';)' class='wp-smiley' /> . Na miejscu spotkałem jednego z chłopaków od Lego Mindstorms. Poprosiliśmy o wspomniane zestawy programowalne w C++. Okazało się, że są to <a href="http://www.graupner-robotics.de/en/robot/rc-soccerbot.html">roboty niemieckiej firmy Graupner Robotics</a> służące do zawodów w piłkę nożną. Obsługa powiedziała mi, że w Niemczech takie roboty dawane są szkołom na okres kilku miesięcy, by uczniowie mieli czas przygotować oprogramowanie, a następnie roboty biorą udział w jakiegoś rodzaju konkursie. Po konkursie roboty są zwykle zostawiane szkołom.</p>
<p>Roboty dostaliśmy w dość rozsypanej postaci &#8211; przez pierwsze pół godziny grzebaliśmy w pudełkach szukając zasilania i programatora do szkieletu, który zdawał się być najprostszą w pełni działającą konstrukcją. Po uruchomieniu mechaniki przyszedł czas na programowanie; odnalezienie się zajęło jakieś kolejne pół godziny. Niestety, robot po wgraniu programu wyprawiał nieopisane cuda z silniczkami. Próba rozwiązania tego problemu zajęła mi praktycznie cały czas do 19:00. Pomagał w tym <a href="http://wawszczak.pr0.pl">Stanisław</a>, który pojawił się w międzyczasie w Galerii. Robot jednak nie zaczął działać poprawnie; musieliśmy go w końcu zostawić i opuścić galerię.</p>
<p><strong>Roboty Graupnera</strong></p>
<p><a href="http://temporal.pr0.pl/devblog/download/roboty_krakow/soccerboard_big.png" target="_blank"><img src="http://temporal.pr0.pl/devblog/download/roboty_krakow/soccerboard_small.png" alt="Układ SoccerBoard firmy qfix"  style="float: right; margin-left: 15px;" /></a></p>
<p>Platforma Graupnera różni się zasadniczo od Lego Mindstorms i Fischertechnika &#8211; w przypadku dwóch ostatnich konstrukcja robota to plastikowe klocki, natomiast ten pierwszy to pełnoprawny metalowy robot zrobiony z przykręcanych / mocowanych części. Sercem układu sterującego, <a href="http://temporal.pr0.pl/devblog/download/roboty_krakow/soccerboard_big.png" target="_blank">nazwanego SoccerBoard</a>, jest procesor ATmega128. SoccerBoard pozwala na podłączenie aż sześciu różnych silników (trzy z nich typowa konstrukcja wykorzystuje do poruszania się), 8-miu wejść cyfrowych oraz 8-miu wejść analogowych. Dodatkowo pierwsze cztery wejścia analogowe i cyfrowe mogą służyć za wyjścia mocy, którymi można np. zasilać żaróweczki. Przydatnym do debugowania programów mogłaby się okazać możliwość podłączenia małego wyświetlacza LCD &#8211; gdyby ktoś na festiwalu taki wyświetlacz miał.</p>
<p>Roboty Graupnera oparte są o platformę <a href="http://www.qfix.de">niemieckiej firmy qfix</a>. Całość programuje się w C++ przy użyciu specjalnie przygotowanego prostego API. Razem z oprogramowaniem robota instalowany jest Programmer&#8217;s Notepad, w którym proces kompilacji i programowania układu został uproszczony do naciskania klawiszy F5 i F6.</p>
<p><center><strong>Starcie Trzecie &#8211; Piątek, 05.06.2009</strong></center></p>
<p><a href="http://temporal.pr0.pl/devblog/download/roboty_krakow/pnotepad.png" target="_blank"><img src="http://temporal.pr0.pl/devblog/download/roboty_krakow/pnotepad_small.png" alt="Jak zostałem największym idiotą Galaktyki" width="128"  style="float: left; margin-right: 15px;" /></a></p>
<p> Korzystając z chwili wolnego (nie mieliśmy tego dnia zajęć) udałem się do Galerii by kontynuować próby poprawnego zaprogramowania SoccerBoard&#8217;a. Analizowałem dokładnie API qfix&#8217;a i studiowałem pojedyncze bity na portach, które ustawiały funkcje mające wpływ na silniczki. Wreszcie doszło do tego, że znalazłem w Internecie SDK i zainstalowałem je na swoim laptopie. I wtedy przypadkiem odkryłem prawdziwą przyczynę błędnej pracy układu &#8211; niewielka lista rozwijana, która &#8211; jak mi się zdawało &#8211; służyła tylko do wyboru języka, dla którego kolorowana będzie składnia kontrolowała także model programowalnego chipa. Narzędzia kompilacji i nagrywania programu, dostępne pod klawiszami F5 i F6, były zależne od wyboru dokonanego na tej liście. Tak zostałem największym idiotą Galaktyki <img src='http://temporal.pr0.pl/devblog/wp-includes/images/smilies/icon_wink.gif' alt=';)' class='wp-smiley' /> .</p>
<p>Dzięki powyższemu odkryciu udało mi się w końcu w pełni poprawnie zaprogramować robota (wszystkie hacki, które zainstalowałem w API qfix&#8217;a okazały się w tym momencie niepotrzebne <img src='http://temporal.pr0.pl/devblog/wp-includes/images/smilies/icon_wink.gif' alt=';)' class='wp-smiley' />  ). Niestety, musiałem w tym momencie opuścić Galerię ale przynajmniej było pewne, że robot Graupnera może być łatwo i przyjemnie zaprogramowany. Postanowiłem powrócić&#8230; <img src='http://temporal.pr0.pl/devblog/wp-includes/images/smilies/icon_smile.gif' alt=':)' class='wp-smiley' /> </p>
<p><em>Ciąg dalszy nastąpi&#8230;</em></p>
]]></content:encoded>
			<wfw:commentRss>http://temporal.pr0.pl/devblog/2009/06/07/stulecie-robotow-w-krakowie-reportaz-czesc-2/feed/</wfw:commentRss>
		<slash:comments>1</slash:comments>
		</item>
		<item>
		<title>Stulecie Robotów w Krakowie &#8211; Reportaż, część 1</title>
		<link>http://temporal.pr0.pl/devblog/2009/06/06/stulecie-robotow-w-krakowie-reportaz-czesc-1/</link>
		<comments>http://temporal.pr0.pl/devblog/2009/06/06/stulecie-robotow-w-krakowie-reportaz-czesc-1/#comments</comments>
		<pubDate>Sat, 06 Jun 2009 09:06:08 +0000</pubDate>
		<dc:creator>Jacek Złydach</dc:creator>
				<category><![CDATA[Applied Science]]></category>
		<category><![CDATA[Informatyka]]></category>
		<category><![CDATA[Stulecie Robotów w Krakowie]]></category>
		<category><![CDATA[ATmega128]]></category>
		<category><![CDATA[C++]]></category>
		<category><![CDATA[Fischertechnik]]></category>
		<category><![CDATA[Galeria Krakowska]]></category>
		<category><![CDATA[Graupner Robotics]]></category>
		<category><![CDATA[Lego Mindstorms]]></category>
		<category><![CDATA[qfix]]></category>
		<category><![CDATA[reportaże]]></category>
		<category><![CDATA[roboty]]></category>
		<category><![CDATA[Stulecie Robotów]]></category>

		<guid isPermaLink="false">http://temporal.pr0.pl/devblog/?p=370</guid>
		<description><![CDATA[W Galerii Krakowskiej odbywa się obecnie festiwal o nazwie &#8220;Stulecie Robotów&#8221;. Trwać będzie on (według moich informacji) do końca przyszłego tygodnia, tj. do niedzieli 14.06.2009. Galeria pełna jest gablot z małymi i dużymi robotami, jednak najciekawszym miejscem jest czynny codziennie w godzinach 09:00 &#8211; 19:00 (czasem 10:00 &#8211; 20:00) punkt, w którym przygotowano zestawy Lego [...]]]></description>
			<content:encoded><![CDATA[<p>W Galerii Krakowskiej odbywa się obecnie festiwal o nazwie &#8220;Stulecie Robotów&#8221;. Trwać będzie on (według moich informacji) <strong>do końca przyszłego tygodnia, tj. do niedzieli 14.06.2009</strong>. Galeria pełna jest gablot z małymi i dużymi robotami, jednak najciekawszym miejscem jest czynny codziennie w godzinach 09:00 &#8211; 19:00 (czasem 10:00 &#8211; 20:00) punkt, w którym przygotowano zestawy <a href="http://en.wikipedia.org/wiki/LEGO_Mindstorms">Lego Mindstorms</a>, <a href="http://en.wikipedia.org/wiki/Fischertechnik">Fischertechnik</a> i <a href="http://fjernstyret.dk/graupner-r1001-rc-soccerbot-p-121.html">Graupner Robotics (Soccerbot)</a> i do samodzielnego złożenia i zaprogramowania. Zwłaszcza ten ostatni &#8220;zestaw&#8221; jest ciekawy, gdyż wewnętrznie jest to układ ATmega128 programowany w C++.</p>
<p>Ponieważ jestem studentem i właśnie mam sesję, postanowiłem się pouczyć i tak zawędrowałem na wspomniany festiwal <img src='http://temporal.pr0.pl/devblog/wp-includes/images/smilies/icon_smile.gif' alt=':)' class='wp-smiley' /> . W najbliższych kilku postach postaram się zrelacjonować to wydarzenie. Pojawi się trochę zdjęć i filmów, których jeszcze nie zrobiłem bo byłem zbyt zajęty psuciem robotów <img src='http://temporal.pr0.pl/devblog/wp-includes/images/smilies/icon_wink.gif' alt=';)' class='wp-smiley' /> </p>
<p><center><strong>Starcie Pierwsze &#8211; Wtorek, 02.06.2009</strong></center><br />
Po krótkim spacerze między gablotami trafiłem do &#8216;części konstrukcyjnej&#8217;, gdzie zostałem zaproszony do skorzystania z zestawów Fischertechnik. Lego Mindstorms zajęte były przez młodych chłopaków, którzy tworzyli dość ambitne konstrukcje kroczące, by następnie udać się na pobliską arenę dla robotów i przetestować je w walce. Wspomniana &#8216;arena&#8217; to specjalna plansza, na której można testować zbudowane przez siebie roboty oraz sterować trzema robotami-zabawkami &#8220;na pilota&#8221;. <del datetime="2009-06-06T19:22:42+00:00">Dwa z nich przypominają transformersy <img src='http://temporal.pr0.pl/devblog/wp-includes/images/smilies/icon_smile.gif' alt=':)' class='wp-smiley' />  i poruszają się na dwóch nogach,</del><ins datetime="2009-06-06T19:22:42+00:00">Jeden z nich porusza się na dwóch nogach, drugi na owadzich kończynach a</ins> trzeci to model węża. Zdjęcia i filmiki wkrótce <img src='http://temporal.pr0.pl/devblog/wp-includes/images/smilies/icon_smile.gif' alt=':)' class='wp-smiley' /> .</p>
<p>Posadzony przed klockami Fischertechnik znalazłem jakąś instrukcję i zacząłem konstrukcję podstawowego modułu jeżdżącego. Nie było to takie proste zadanie, pierwszy raz widziałem takie klocki na oczy <img src='http://temporal.pr0.pl/devblog/wp-includes/images/smilies/icon_wink.gif' alt=';)' class='wp-smiley' /> . Otrzymałem procesor sterujący, baterię oraz dostęp do kabli i oprzyrządowania. Gdy robot był już gotowy, miły człowiek z obsługi festiwalu posadził mnie przy komputerze i poinstruował jak korzystać z oprogramowania. Po podpięciu procesora robota do PC przez kabel USB zaczęła się zabawa <img src='http://temporal.pr0.pl/devblog/wp-includes/images/smilies/icon_smile.gif' alt=':)' class='wp-smiley' /> .</p>
<p><center><a href="http://temporal.pr0.pl/devblog/download/roboty_krakow/fischertechnik_1.jpg" style="padding-right: 30px;" target="_blank"><img src="http://temporal.pr0.pl/devblog/download/roboty_krakow/fischertechnik_1_small.jpg" alt="Robot Fischertechnik, widok z boku" /></a><a href="http://temporal.pr0.pl/devblog/download/roboty_krakow/fischertechnik_2.jpg" style="padding-left: 30px;" target="_blank"><img src="http://temporal.pr0.pl/devblog/download/roboty_krakow/fischertechnik_2_small.jpg" alt="Robot Fischertechnik, widok z góry" /></a><br />
<em>Robot mojej konstrukcji</em></center></p>
<p><strong>Narzędzia Fischertechnik</strong><br />
Narzędzia Fischertechnik &#8211; podobnie jak Lego Mindstorms &#8211; pozwalają na tworzenie aplikacji przez wyklikiwanie schematów blokowych w dedykowanej aplikacji. Program, z którego korzystałem pozwalał pracować na pięciu poziomach zaawansowania &#8211; z każdym kolejnym dostawało się do dyspozycji więcej opcji. Poziom podstawowy to bardzo prosty interfejs, w którym można wyklikać prosty program. Dostępne opcje to m.in. zaczekanie na przycisk (dokładniej: wejście cyfrowe), sterowanie pracą silnika (dokładniej: wyjścia sterującego <img src='http://temporal.pr0.pl/devblog/wp-includes/images/smilies/icon_smile.gif' alt=':)' class='wp-smiley' /> ). Za pomocą niektórych bloczków program mógł się rozgałęzić lub zapętlić. Kolejnym poziomem zaawansowania był poziom &#8216;podprogramów&#8217; &#8211; w tym trybie pojawiały się dodatkowe, bardziej złożone bloczki oraz można było wyklikiwać własne funkcje (w postaci podobnych schematów blokowych), które następnie stawały się bloczkami i można było z nich korzystać w programie. Kolejne trzy poziomy to dodatkowe bloczki (m.in. operacje na zmiennych, dość zaawansowane konstrukcje logiczne) i lekkie skomplikowanie interfejsu. Niezastąpione okazało się okienko podglądu aktualnego stanu robota, dzięki któremu można było mieć zarówno podgląd wszystkich wejść analogowych i cyfrowych w czasie rzeczywistym (tak długo, jak robot był podpięty do komputera), jak i można było sterować każdym z wyjść sterujących bez konieczności wgrywania nowego programu. W całym tym procesie jedna tylko rzecz mi bardzo przeszkadzała &#8211; komputery pracowały na systemie w niemieckiej wersji językowej; nie był to wielki problem, ale za to denerwujący.</p>
<p><strong>Robot</strong><br />
Ostatecznie wyposażyłem swojego robota w dwa przyciski, które służyły za czujniki zderzenia z przeszkodą. Następnie stworzyłem program, dzięki któremu robot &#8216;patrolował&#8217; teren poruszając się z niewielką szybkością do przodu, a w przypadku naciśnięcia któregokolwiek z przycisków błyskawicznie odskakiwał i omijał punkt zderzenia (dokładniej cofał się, skręcał w odpowiednią stronę, reorientował i podjeżdżał &#8211; zakreślając coś na kształt dużego U). Ten prosty kod okazał się być wystarczająco dobry, by robot mógł zostać pozostawiony na arenie, gdzie toczyły się walki &#8211; potrafił poruszać się bardzo długo bez pomocy człowieka i nie blokował się (głównie dlatego, że jedno z kółek było krzywe i robot nie jechał zwykle idealnie po prostej).</p>
<p>Kilka słów o elementach elektronicznych w zestawach Fischertechnik, przynajmniej tych dostępnych na festiwalu. Jedynym wejściem dla robota okazał się być wspomniany przycisk. Służy on za wejście cyfrowe &#8211; ma dwa stany. Ponadto za wejście możnaby uznać pewne bliżej niezidentyfikowane urządzenie przypominające fototranzystor; nie udało mi się go jednak uruchomić. Z elementów wyjściowych dołączone były silniki oraz żarówkowe światełka. Oba te rodzaje urządzeń korzystają z tych samych wyjść. Sama płytka sterująca posiada wejścia analogowe mierzące napięcie (jedno mierzy rezystancję) i pozwala podłączyć jedynie cztery urządzenia wyjściowe (to i tak o jedno więcej niż Lego Mindstorms).</p>
<p>Wybiła godzina 19:00 i trzeba było się zbierać. Od obsługi dostałem informację, że mają też trzeci rodzaj robotów, programowalny w C++ i że mogą go udostępnić następnym razem, jeśli będę chciał. Ponadto z rozpędu zgubiłem na wystawie rolkę <a href="http://en.wikipedia.org/wiki/Duct_tape">Duct Tape</a> (na szczęście na wykończeniu).</p>
<p><em>Ciąg dalszy nastąpi&#8230;</em></p>
]]></content:encoded>
			<wfw:commentRss>http://temporal.pr0.pl/devblog/2009/06/06/stulecie-robotow-w-krakowie-reportaz-czesc-1/feed/</wfw:commentRss>
		<slash:comments>2</slash:comments>
		</item>
		<item>
		<title>Definicje</title>
		<link>http://temporal.pr0.pl/devblog/2009/06/02/definicje/</link>
		<comments>http://temporal.pr0.pl/devblog/2009/06/02/definicje/#comments</comments>
		<pubDate>Tue, 02 Jun 2009 11:23:53 +0000</pubDate>
		<dc:creator>Jacek Złydach</dc:creator>
				<category><![CDATA[Varia]]></category>
		<category><![CDATA[Z życia]]></category>
		<category><![CDATA[Asimov]]></category>
		<category><![CDATA[licencia technicia]]></category>
		<category><![CDATA[Technik]]></category>
		<category><![CDATA[TRC]]></category>
		<category><![CDATA[WPT]]></category>

		<guid isPermaLink="false">http://temporal.pr0.pl/devblog/?p=267</guid>
		<description><![CDATA[Ostrzegam, że poniższy post będzie zrozumiały tylko dla niektórych Czytelników  .


TRC istnieje już niemal pięć lat. W ciągu całego swego istnienia przeżyliśmy niejedną porażkę, ale też i wiele zakończonych sukcesem akcji dla dobra Galaktyki. I chociaż rezultaty technologicznie nie są wymierne, to jednak niedawno wykrystalizowały się nareszcie definicje fundamentalnych pojęć w TRC-owym świecie:

Technik (duże [...]]]></description>
			<content:encoded><![CDATA[<p><em>Ostrzegam, że poniższy post będzie zrozumiały tylko dla niektórych Czytelników <img src='http://temporal.pr0.pl/devblog/wp-includes/images/smilies/icon_wink.gif' alt=';)' class='wp-smiley' /> .<br />
</em><br />
<img src="http://temporal.pr0.pl/TRC/trclogo.png" alt="Logo TRC" width="175px" height="175px" style="float: left; margin-right: 5px;" /><br />
<a href="http://trc.pr0.pl"><acronym title="Temporal Research Centre">TRC</acronym></a> istnieje już niemal pięć lat. W ciągu całego swego istnienia przeżyliśmy niejedną porażkę, ale też i wiele <a href="http://temporal.pr0.pl/devblog/tag/szczeniak/">zakończonych sukcesem akcji dla dobra Galaktyki</a>. I chociaż rezultaty technologicznie nie są wymierne, to jednak niedawno wykrystalizowały się nareszcie definicje fundamentalnych pojęć w TRC-owym świecie:</p>
<ul>
<li><strong>Technik (duże T)</strong> &#8211; człowiek o ogromnych umiejętnościach i wiedzy naukowo-technicznej, którą wykorzystuje dla dobra drugich. Dobrego Technika cechują nieszablonowe pomysły i umiejętność radzenia sobie w każdej sytuacji. Celem jego działania jest pomaganie innym ludziom, których dobro stawia ponad swoje własne wygody. Kieruje się szlachetnymi pobudkami. Technik często jest nierozumiany przez zwykłych ludzi, którzy patrzą na niego z przymrużeniem oka i nierzadko unikają bliższych kontaktów (zasada: w razie dobrze mieć Technika pod ręką, ale nie za blisko). Na obecność Technika w pobliżu zwykle wskazują zjawiska takie jak anomalie czasowe, &#8217;samoistne&#8217; rozwiązywanie się problemów, dziwne &#8216;przypadki&#8217; (znane jako zjawisko WPT<a name="POST_DEFINICJE_MT_1" href="#POST_DEFINICJE_REF_1">*</a>), oraz nagłe pragnienie opuszczenia pomieszczenia<a name="POST_DEFINICJE_MT_2" href="#POST_DEFINICJE_REF_2">**</a>.</li>
<li><strong>TRC</strong> &#8211; Organizacja zajmująca się badaniami nad czasem oraz rozwojem i wykorzystaniem zaawansowanych technologii dla szeroko rozumianego dobra Galaktyki.
</li>
<li><strong>Licencia Technicia</strong> &#8211; prawo Techników do wykonywania działań w sposób, który <em>pozornie</em> łamie powszechnie znane prawa fizyki (także uniwersalna odpowiedź na pytanie: jak to zrobiłeś?).</li>
</ul>
<p>Temat społecznych konsekwencji powyższej definicji Technika podjął niedawno <a href="http://wawszczak.pr0.pl/2009/02/28/nowa-rzeczywistosc-technika/">Stanisław Wawszczak</a>.</p>
<p><a name="POST_DEFINICJE_REF_1" href="#POST_DEFINICJE_MT_1">*</a> &#8211; WPT, czyli Wewnętrzne Przeczucie Technika, które tak na prawdę nie jest przeczuciem. Zgodne z twierdzeniem, że &#8216;najłatwiej przewiduje się przyszłość, gdy się ją samemu tworzy&#8217;.<br />
<a name="POST_DEFINICJE_REF_2" href="#POST_DEFINICJE_MT_2">**</a> &#8211; TRCowska definicja Technika opiera się na swobodnej interpretacji postaci Techników z powieści <a href="http://pl.wikipedia.org/wiki/Isaac_Asimov">Asimov&#8217;a</a> pt. <a href="http://pl.wikipedia.org/wiki/Koniec_wieczno%C5%9Bci">&#8220;Koniec Wieczności&#8221;</a>.</p>
]]></content:encoded>
			<wfw:commentRss>http://temporal.pr0.pl/devblog/2009/06/02/definicje/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Normy i uwarunkowanie macierzy &#8211; ciąg dalszy</title>
		<link>http://temporal.pr0.pl/devblog/2009/03/18/normy-i-uwarunkowanie-macierzy-ciag-dalszy/</link>
		<comments>http://temporal.pr0.pl/devblog/2009/03/18/normy-i-uwarunkowanie-macierzy-ciag-dalszy/#comments</comments>
		<pubDate>Wed, 18 Mar 2009 14:46:51 +0000</pubDate>
		<dc:creator>Jacek Złydach</dc:creator>
				<category><![CDATA[Matematyka]]></category>
		<category><![CDATA[macierze]]></category>
		<category><![CDATA[metody numeryczne]]></category>
		<category><![CDATA[normy]]></category>
		<category><![CDATA[uwarunkowanie]]></category>

		<guid isPermaLink="false">http://temporal.pr0.pl/devblog/?p=342</guid>
		<description><![CDATA[Poprzedni post poświęcony tematowi uwarunkowania macierzy zyskał &#8211; ku mojemu ogromnemu zaskoczeniu &#8211; bardzo dużą popularność, przynajmniej jeśli mowa o liczbie wyszukań w Google. Jest to argument potwierdzający, że temat uwarunkowania macierzy i norm macierzowych nie jest należycie omówiony w Internecie.
W tamtym wpisie poruszyłem szereg problemów, które można streścić do jednego pytania: której normy używać, [...]]]></description>
			<content:encoded><![CDATA[<p><a href="http://temporal.pr0.pl/devblog/2008/12/12/uwarunkowanie-macierzy/">Poprzedni post</a> poświęcony tematowi uwarunkowania macierzy zyskał &#8211; ku mojemu ogromnemu zaskoczeniu &#8211; bardzo dużą popularność, przynajmniej jeśli mowa o liczbie wyszukań w Google. Jest to argument potwierdzający, że temat uwarunkowania macierzy i norm macierzowych nie jest należycie omówiony w Internecie.</p>
<p>W tamtym wpisie poruszyłem szereg problemów, które można streścić do jednego pytania: <strong>której normy używać, dlaczego, i co nam to tak właściwie daje ilościowo?</strong>. Wiąże się to też z próbą odpowiedzi na pytanie &#8220;ile to jest <em>źle uwarunkowane</em>?&#8221;</p>
<p>W ramach pracy dodatkowej na studia zbadałem ten temat dokładniej i podjąłem próbę udzielenia odpowiedzi na te i inne pytania. Mam nadzieję, że poniższy dokument rozjaśni kwestię norm, uwarunkowania macierzy, dokładności obliczeń numerycznych. Praca ta została sprawdzona przez doktora prowadzącego laboratoria z Metod Numerycznych i nie zawiera &#8220;elementów które by jakoś bardzo raziły&#8221;. Mam więc nadzieję, że będzie to wartościowe źródło dla zainteresowanych tematem osób.</p>
<p><strong><a href="http://temporal.pr0.pl/devblog/download/numerki/uwarunkowanie/opracowanie.pdf">Pobierz opracowanie</a></strong>.</p>
<p>Mile widziane będą komentarze, uwagi oraz wskazanie ewentualnych błędów.</p>
]]></content:encoded>
			<wfw:commentRss>http://temporal.pr0.pl/devblog/2009/03/18/normy-i-uwarunkowanie-macierzy-ciag-dalszy/feed/</wfw:commentRss>
		<slash:comments>2</slash:comments>
		</item>
		<item>
		<title>3h Compo</title>
		<link>http://temporal.pr0.pl/devblog/2009/03/16/3h-compo/</link>
		<comments>http://temporal.pr0.pl/devblog/2009/03/16/3h-compo/#comments</comments>
		<pubDate>Mon, 16 Mar 2009 20:00:53 +0000</pubDate>
		<dc:creator>Jacek Złydach</dc:creator>
				<category><![CDATA[Tworzenie gier]]></category>
		<category><![CDATA[algorytmy stadne]]></category>
		<category><![CDATA[Compo]]></category>
		<category><![CDATA[experiential gameplay]]></category>
		<category><![CDATA[Java]]></category>
		<category><![CDATA[uczucia]]></category>

		<guid isPermaLink="false">http://temporal.pr0.pl/devblog/?p=327</guid>
		<description><![CDATA[Wczoraj (tj. w niedzielę, 15.03.2009) na Warsztacie zorganizowano marcowe 3h compo. Konkurs trwał od 17:00 do 20:00, a tematem było stworzenie gry, która zawiera zarówno krowę jak i świnię (Szczegóły konkursu na forum Warsztatu).
Powiem szczerze, że pierwszy raz w życiu widziałem taką frekwencję &#8211; przysłano aż 28 prac. Większość z nich była grywalna, a niektóre [...]]]></description>
			<content:encoded><![CDATA[<p>Wczoraj (tj. w niedzielę, 15.03.2009) na <a href="http://gamedev.pl">Warsztacie</a> zorganizowano <a href="http://www.gamedev.pl/compo/news.php?x=view&#038;id=597">marcowe 3h compo</a>. Konkurs trwał od 17:00 do 20:00, a tematem było stworzenie gry, która zawiera zarówno krowę jak i świnię (<a href="http://forum.gamedev.pl/index.php/topic,10118.0.html">Szczegóły konkursu na forum Warsztatu)</a>.</p>
<p>Powiem szczerze, że pierwszy raz w życiu widziałem taką frekwencję &#8211; przysłano aż 28 prac. Większość z nich była grywalna, a niektóre były na prawdę godne podziwu.</p>
<p>Prace, które szczególnie mi się spodobały (kolejność alfabetyczna):</p>
<ul>
<li><a href="http://www.gamedev.pl/user.php?x=view&#038;id=1484">BrutalComputer</a> wyprodukował prostą, ale klimatyczną i wciągającą strzelankę.</li>
<li><a href="http://gynvael.coldwind.pl/?id=168">Gynvael Coldwind</a> stworzył bardzo grywalnego Tower Defense.</li>
<li>KK zaprezentował bardzo wciągającą, dynamiczną platformówkę z grafiką w stylu <a href="http://pl.wikipedia.org/wiki/ASCII-Art">ASCII-Art</a></li>
<li><a href="http://www.maskl.cba.pl">Maskl</a> został autorem <a href="http://www.gry-online.pl/s016.asp?id=59">Commandosów</a> <img src='http://temporal.pr0.pl/devblog/wp-includes/images/smilies/icon_smile.gif' alt=':)' class='wp-smiley' />  &#8211; gierka szalenie grywalna, spójna i klimatyczna.</li>
<li><a href="http://www.mi-ku.net/?p=120">Mi-Ku</a> pokazał nam gierkę z zabawną fizyką <img src='http://temporal.pr0.pl/devblog/wp-includes/images/smilies/icon_smile.gif' alt=':)' class='wp-smiley' />  .</li>
<li><a href="http://regedit.gamedev.pl">Reg</a> napisał szalenie wciągający symulator hodowli. W nocy po Compo kilka osób grało w tę grę i ścigało się na dochody farmy <img src='http://temporal.pr0.pl/devblog/wp-includes/images/smilies/icon_smile.gif' alt=':)' class='wp-smiley' /> .</li>
</ul>
<p>Na koniec kilka słów o mojej pracy. Można ją pobrać poniżej:<br />
<a href="http://temporal.pr0.pl/devblog/download/projects/3hCompo_15.03.2009/final.zip">(link do gry)</a>.<br />
Napisana została w Javie i LWJGL, powinna działać zarówno pod Windowsem jak i Linuksem. Dołączone są skrypty uruchamiające.</p>
<p><center><a href="http://temporal.pr0.pl/devblog/download/projects/3hCompo_15.03.2009/screenshot.png"><img src="http://temporal.pr0.pl/devblog/download/projects/3hCompo_15.03.2009/screenshot_120px.jpg" alt="3h Compo - screen z gry" /></a><br />
Screen z gry (kliknij aby powiększyć)</center></p>
<p>Gra nie ma swojego tytułu. Gatunkiem klasyfikuje się do <a href="http://temporal.pr0.pl/devblog/2009/03/04/experiential-gameplay/">experiential gameplay</a>. Gracz kieruje krową, która posiada emocje &#8211; główne uczucia to uczucie smutku / radości oraz zabawy / wściekłości (skutków tego ostatniego nie zdążyłem zaimplementować <img src='http://temporal.pr0.pl/devblog/wp-includes/images/smilies/icon_sad.gif' alt=':(' class='wp-smiley' />  ). Są też stany pośrednie &#8211; krowa może być bardzo smutna, smutna, neutralna, wesoła lub bardzo wesoła. Równocześnie może być też rozbawiona gonieniem świnek <img src='http://temporal.pr0.pl/devblog/wp-includes/images/smilies/icon_wink.gif' alt=';)' class='wp-smiley' />  . Krowa, która włóczy się po pastwisku smutnieje z nudów &#8211; aby poprawić jej humor trzeba przejść na &#8216;lepszą trawę&#8217;. Emocje krowy ilustrowane są przez grafikę twarzy.</p>
<p>Na planszy pojawia się też stado świń, kierowanych za pomocą prostego algorytmu stadnego. Uciekają one przed graczem, równocześnie starając się zachować spójność grupy, nie wpadać na siebie i dążyć do wspólnego celu znajdującego się niedaleko lewej krawędzi mapy.</p>
<p>Gra ta nie ma swojego celu &#8211; experiential gameplay tego nie wymaga. Ideą było zilustrowanie uczuć krowy, której humor zależy od tego gdzie się znajduje i co robi.</p>
]]></content:encoded>
			<wfw:commentRss>http://temporal.pr0.pl/devblog/2009/03/16/3h-compo/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Experiential Gameplay</title>
		<link>http://temporal.pr0.pl/devblog/2009/03/04/experiential-gameplay/</link>
		<comments>http://temporal.pr0.pl/devblog/2009/03/04/experiential-gameplay/#comments</comments>
		<pubDate>Wed, 04 Mar 2009 20:32:20 +0000</pubDate>
		<dc:creator>Jacek Złydach</dc:creator>
				<category><![CDATA[Informatyka]]></category>
		<category><![CDATA[Tworzenie gier]]></category>
		<category><![CDATA[experiential gameplay]]></category>
		<category><![CDATA[I Wish I Were The Moon]]></category>
		<category><![CDATA[sztuka]]></category>
		<category><![CDATA[uczucia]]></category>

		<guid isPermaLink="false">http://temporal.pr0.pl/devblog/?p=288</guid>
		<description><![CDATA[Experiential gameplay (nie mylić z experimental gameplay!) to termin znany z bloga Daniela Benmergui. Jest to nietypowy, eksperymentalny &#8216;gatunek&#8217; gier, który skupia się nie na konkretnym celu, ale na przeżyciach towarzyszących jego osiąganiu. Dość dobrze zostało to omówione w jednym z postów na blogu Ludomancy.com. Sam Daniel stworzył już kilka gierek w podobnej koncepcji; dwie [...]]]></description>
			<content:encoded><![CDATA[<p>Experiential gameplay (nie mylić z <em>experimental</em> gameplay!) to termin znany z <a href="http://www.ludomancy.com">bloga Daniela Benmergui</a>. Jest to nietypowy, eksperymentalny &#8216;gatunek&#8217; gier, który skupia się nie na konkretnym celu, ale na przeżyciach towarzyszących jego osiąganiu. Dość dobrze zostało to omówione <a href="http://www.ludomancy.com/blog/2007/01/17/experiential-games/">w jednym z postów</a> na blogu Ludomancy.com. Sam Daniel stworzył już kilka gierek w podobnej koncepcji; dwie z nich <a href="http://www.youtube.com/watch?v=Sfi92eqWV1w">zaprezentował na Sense of Wonder Night, Tokio Game Show 2008</a>. Gorąco polecam oglądnięcie tego video, rzuca światło na koncepcję experiential gameplay.</p>
<p>Omawiane gry dostępne są do zagrania na Kongregate:</p>
<ul>
<li><a href="http://www.kongregate.com/games/danielben/i-wish-i-were-the-moon">I Wish I Were The Moon</a></li>
<li><a href="http://www.kongregate.com/games/danielben/storyteller">Storyteller</a></li>
</ul>
<p>Ponadto ten sam autor stworzył też:<br />
<a href="http://www.ludomancy.com/blog/2008/06/03/night-raveler-and-the-heartbroken-uruguayans-the-game/">Night Raveler and the Heartbroken Uruguayans: The Game</a> oraz <a href="http://www.ludomancy.com/blog/2008/09/09/the-trials/">The Trials</a>.</p>
<p>Kolejnym ciekawym tytułem jest <a href="http://www.kongregate.com/games/GregoryWeir/the-majesty-of-colors">The Majesty of Colors</a> autorstwa <a href="http://ludusnovus.net/">Gregory&#8217;ego Weir</a>. Ta gra poświęcona jest tematyce snu, a zainspirowana została m.in. przez <em>I Wish I Were The Moon</em>. Autor napisał też ciekawy <a href="http://www.gamesetwatch.com/2009/01/postmortem_i_fell_in_love_with.php">postmortem <em>Majesty</em></a>. Interesującą pozycją zdaje się być też <a href="http://rodvik.com/rodgames/SOHMB.html">Stars over Half  Moon Bay</a> <a href="http://rodvik.com/rodgames/">Roda Humble</a> poświęcona gwiazdom na nocnym niebie, kreatywności i filozofii, niemniej jednak jest ona trudniejsza w odbiorze (przynajmniej mnie sprawia kłopot). Rod jest też autorem specyficznej gry <a href="http://www.rodvik.com/rodgames/marriage.html">The Marriage</a>, która jednak wymaga wysilenia wyobraźni.</p>
<p>Niedawno natknąłem się też na kolejną gierkę, którą mógłbym zaliczyć do &#8216;gatunku&#8217; experiential gameplay. <a href="http://www.gamedesign.jp/flash/sprinter/sprinter.html">Minigra zatytułowana Sprinter</a> to prosta ilustracja koncepcji biegania, w której do kontroli sprintera używamy dwóch klawiszy. Idea podobna do tej, którą opisał Daniel we wpisie o experiential gameplay.</p>
<p>Experiential gameplay to w pewnym sensie też gatunek eksperymentalnego gameplay. Nie jest to jednak zwykła demonstracja, <a href="http://en.wikipedia.org/wiki/Proof_of_concept">proof-of-concept</a> mający pokazać, że dany pomysł ma szansę się sprawdzić. To gry skupione na doznaniach innych niż te z gier retailowych, zasypujących nas adrenaliną i przemocą. Ze wszystkich experiential games, które widziałem najbardziej podobały mi się te, które poruszają temat uczuć &#8211; jak <em>I Wish I Were The Moon</em> i <em>Storyteller</em>.</p>
<p>Osobiście sam przymierzałem się do gierki tego typu, niemniej chwilowo pomysł zawiesiłem &#8211; częściowo z braku czasu, a częściowo&#8230; z braku szybkich narzędzi developerskich. Na <a href="http://gamedev.pl">Warsztacie</a> by się pewno obrazili, jakbym gierkę wyklikał <img src='http://temporal.pr0.pl/devblog/wp-includes/images/smilies/icon_wink.gif' alt=';)' class='wp-smiley' /> , Flasha obsługiwać jeszcze nie umiem&#8230; Myślę ewentualnie o <a href="http://temporal.pr0.pl/devblog/2009/03/02/programowanie-gier-w-javie-i-lwjgl/">Javie i LWJGL</a>, bo tam mam gotowego frameworka i nawet szybko się w tym pisze gry, ale to wszystko jest kwestią przyszłości.</p>
<p>Czytelniku, jeśli natkniesz się na inne gry tego typu (albo stworzysz takową!) to bardzo proszę, daj mi szybko znać <img src='http://temporal.pr0.pl/devblog/wp-includes/images/smilies/icon_smile.gif' alt=':)' class='wp-smiley' /> .</p>
]]></content:encoded>
			<wfw:commentRss>http://temporal.pr0.pl/devblog/2009/03/04/experiential-gameplay/feed/</wfw:commentRss>
		<slash:comments>1</slash:comments>
		</item>
		<item>
		<title>Programowanie gier w Javie i LWJGL</title>
		<link>http://temporal.pr0.pl/devblog/2009/03/02/programowanie-gier-w-javie-i-lwjgl/</link>
		<comments>http://temporal.pr0.pl/devblog/2009/03/02/programowanie-gier-w-javie-i-lwjgl/#comments</comments>
		<pubDate>Sun, 01 Mar 2009 22:51:44 +0000</pubDate>
		<dc:creator>Jacek Złydach</dc:creator>
				<category><![CDATA[Informatyka]]></category>
		<category><![CDATA[Tworzenie gier]]></category>
		<category><![CDATA[Irrlicht]]></category>
		<category><![CDATA[Java]]></category>
		<category><![CDATA[LWJGL]]></category>
		<category><![CDATA[Ogre]]></category>
		<category><![CDATA[OpenAL]]></category>
		<category><![CDATA[OpenGL]]></category>

		<guid isPermaLink="false">http://temporal.pr0.pl/devblog/?p=260</guid>
		<description><![CDATA[Java jest językiem, który zdaje się nie mieć zbyt dobrej opinii wśród programistów gier komputerowych. Kwestie porównywania wydajności tych języków są dość ciekawe, ale ostatecznie w tym miejscu interesuje nas praktyczna możliwość użycia ich do tworzenia gier. O ile język C++ ma pod tym względem niekwestionowaną pozycję lidera, o tyle Java wciąż przez swą złą [...]]]></description>
			<content:encoded><![CDATA[<p>Java jest językiem, który zdaje się nie mieć zbyt dobrej opinii wśród programistów gier komputerowych. Kwestie <a href="http://forum.gamedev.pl/index.php/topic,5069.0.html">porównywania wydajności tych języków</a> są dość ciekawe, ale ostatecznie w tym miejscu interesuje nas praktyczna możliwość użycia ich do tworzenia gier. O ile język C++ ma pod tym względem niekwestionowaną pozycję lidera, o tyle Java wciąż przez swą złą opinię zdaje się być mało rozwinięta w dziedzinie gamedevu. Powoduje to, że ktoś kto chce napisać grę (lub aplikację graficzną) w Javie nie za bardzo wie, czego szukać.</p>
<p>Chciałbym w tym miejscu polecić wszystkim bibliotekę <a href="http://www.lwjgl.org/">LWJGL</a> (<em>Lightweight Java Game Library</em>). W dużym uproszczeniu składa się ona z bindów OpenGL i <a href="http://connect.creativelabs.com/openal/default.aspx">OpenAL</a> pod Javę, funkcji do obsługi wejścia z klawiatury i myszy oraz garści drobnych klas narzędziowych. Wspiera tworzenie gier zarówno jako aplikacji jak i apletów. Główną zaletą jest przede wszystkim uporządkowanie wejścia, audio i grafiki w jednej bibliotece, dzięki czemu możemy szybko zabrać się za tworzenie gry z pomocą dobrych, wieloplatformowych bibliotek. Więcej informacji, przykłady, dokumentacja zamieszczone są na stronie projektu: <a href="http://www.lwjgl.org/">http://www.lwjgl.org/</a>. Testowałem, działa świetnie <img src='http://temporal.pr0.pl/devblog/wp-includes/images/smilies/icon_wink.gif' alt=';)' class='wp-smiley' />  (niedługo wrócę do tego tematu, bo zamierzam opublikować projekt zaliczeniowy z Programowania Obiektowego, którym była gra pisana w Javie z pomocą LWJGL).</p>
<p>Jeśli Czytelniku niepokoisz się kwestią wydajności języka, proponuję Ci zagrać w grę, która mnie ostatecznie przekonała do sensowności pisania gier w tym języku i mocno zareklamowała LWJGL:<br />
<a href="http://fabiensanglard.net/Prototyp/index.php">http://fabiensanglard.net/Prototyp/index.php</a><br />
Osobiście nie spodziewałem się zobaczyć tyle <acronym title="Frames Per Second">FPS</acronym> w JAKIEJKOLWIEK grze opartej o Javę, ale na szczęście nie jest tak źle jak kiedyś mi się wydawało.</p>
<p>Mimo wszystko jednak Java jest językiem różniącym się od C++ w koncepcji zarządzania pamięcią, co w przypadku programowania gier ma duże znaczenie. Trzeba pisać kod dużo ostrożniej i w sposób przemyślany, żeby unikać niepotrzebnego kopiowania obiektów (w miarę możliwości unikać go w ogóle &#8211; wszystko alokowane dynamicznie) oraz aliasowania się nazw zmiennych (plątające się przypadkiem po różnych obiektach referencje do składowych innego obiektu; jest to ogólna, dla mnie upierdliwa, cecha wielu języków nowszych od C++, np. PHP5). Niewątpliwie niewygodny jest też brak możliwości przeciążania operatorów.</p>
<p>Dla tych, którzy szukają całych silników graficznych mam dobrą wiadomość &#8211; istnieją porty <a href="http://jirr.sourceforge.net/">Irrlicht&#8217;a</a> i <a href="http://ogre4j.sourceforge.net/">Ogre</a> pod Javę <img src='http://temporal.pr0.pl/devblog/wp-includes/images/smilies/icon_smile.gif' alt=':)' class='wp-smiley' /> .</p>
]]></content:encoded>
			<wfw:commentRss>http://temporal.pr0.pl/devblog/2009/03/02/programowanie-gier-w-javie-i-lwjgl/feed/</wfw:commentRss>
		<slash:comments>4</slash:comments>
		</item>
		<item>
		<title>Le Parkour</title>
		<link>http://temporal.pr0.pl/devblog/2009/02/28/le-parkour/</link>
		<comments>http://temporal.pr0.pl/devblog/2009/02/28/le-parkour/#comments</comments>
		<pubDate>Sat, 28 Feb 2009 10:46:38 +0000</pubDate>
		<dc:creator>Jacek Złydach</dc:creator>
				<category><![CDATA[Humor]]></category>
		<category><![CDATA[Rysunki]]></category>
		<category><![CDATA[le parkour]]></category>
		<category><![CDATA[Mirror's Edge]]></category>
		<category><![CDATA[Yamakasi]]></category>

		<guid isPermaLink="false">http://temporal.pr0.pl/devblog/?p=262</guid>
		<description><![CDATA[
]]></description>
			<content:encoded><![CDATA[<p><center><a href="http://temporal.pr0.pl/devblog/download/varia/leparkour.png"><img src="http://temporal.pr0.pl/devblog/download/varia/leparkour-small.png" alt="Try playing Mirror's Edge on HD without crosshair after taking Aviomarin." /></a></center></p>
]]></content:encoded>
			<wfw:commentRss>http://temporal.pr0.pl/devblog/2009/02/28/le-parkour/feed/</wfw:commentRss>
		<slash:comments>1</slash:comments>
		</item>
		<item>
		<title>Zagubiony świat</title>
		<link>http://temporal.pr0.pl/devblog/2009/02/24/zagubiony-swiat/</link>
		<comments>http://temporal.pr0.pl/devblog/2009/02/24/zagubiony-swiat/#comments</comments>
		<pubDate>Tue, 24 Feb 2009 21:59:50 +0000</pubDate>
		<dc:creator>Jacek Złydach</dc:creator>
				<category><![CDATA[Z życia]]></category>
		<category><![CDATA[Słoneczko]]></category>

		<guid isPermaLink="false">http://temporal.pr0.pl/devblog/?p=246</guid>
		<description><![CDATA[W tym roku bez poezji. Bo jeden obraz wart jest więcej, niż mnóstwo słów&#8230;

(pobierz małą wersję &#8211; ok. 2MB)
(pobierz wersję niskiej jakości &#8211; uwaga, ok. 10MB)
(pobierz wersję wysokiej jakości &#8211; uwaga, ok. 60MB)
Dedykuję Słoneczku i starym czasom, które minęły.
]]></description>
			<content:encoded><![CDATA[<p>W tym roku bez poezji. Bo jeden obraz wart jest więcej, niż mnóstwo słów&#8230;<br />
<center><img src="http://temporal.pr0.pl/devblog/download/varia/sloneczko/Mosaic_2_micro.jpg" alt="Kochane Słoneczko razem ze Słoneczkiem." /></center><br />
<a href="http://temporal.pr0.pl/devblog/download/varia/sloneczko/Mosaic_2med.jpg">(pobierz małą wersję &#8211; ok. 2MB)</a><br />
<a href="http://temporal.pr0.pl/devblog/download/varia/sloneczko/Mosaic_2lq.jpg">(pobierz wersję niskiej jakości &#8211; uwaga, ok. 10MB)</a><br />
<a href="http://temporal.pr0.pl/devblog/download/varia/sloneczko/Mosaic_2.jpg">(pobierz wersję wysokiej jakości &#8211; uwaga, ok. 60MB)</a></p>
<p>Dedykuję Słoneczku i starym czasom, które minęły.</p>
]]></content:encoded>
			<wfw:commentRss>http://temporal.pr0.pl/devblog/2009/02/24/zagubiony-swiat/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Projekty zaliczeniowe &#8211; rzut pierwszy :)</title>
		<link>http://temporal.pr0.pl/devblog/2009/02/22/projekty-zaliczeniowe-rzut-pierwszy/</link>
		<comments>http://temporal.pr0.pl/devblog/2009/02/22/projekty-zaliczeniowe-rzut-pierwszy/#comments</comments>
		<pubDate>Sun, 22 Feb 2009 21:10:32 +0000</pubDate>
		<dc:creator>Jacek Złydach</dc:creator>
				<category><![CDATA[Informatyka]]></category>
		<category><![CDATA[Projekty studenckie]]></category>
		<category><![CDATA[Tworzenie gier]]></category>
		<category><![CDATA[AGH]]></category>
		<category><![CDATA[alfabet Morsa]]></category>
		<category><![CDATA[analiza głównych składowych]]></category>
		<category><![CDATA[Anything]]></category>
		<category><![CDATA[C++]]></category>
		<category><![CDATA[Delphi]]></category>
		<category><![CDATA[gra w życie]]></category>
		<category><![CDATA[Matematyka]]></category>
		<category><![CDATA[prezentacje multimedialne]]></category>

		<guid isPermaLink="false">http://temporal.pr0.pl/devblog/?p=230</guid>
		<description><![CDATA[Jedną z najlepszych stron kierunku Informatyka Stosowana na AGH są pojawiające się od czasu do czasu projekty zaliczeniowe. Poniżej publikuję pierwszą serię &#8216;drobnicy&#8217; &#8211; projekty zaliczeniowe z I roku. Nie są może one zbyt ambitne (sprawy osobiste wymagały bardzo dużo uwagi), ale potrzebne zaliczenia dały  .
Podstawy Użytkowania Komputerów (I semestr)
Pobierz prezentacje
Zaliczeniem z najlepszego jak [...]]]></description>
			<content:encoded><![CDATA[<p>Jedną z najlepszych stron kierunku Informatyka Stosowana na AGH są pojawiające się od czasu do czasu projekty zaliczeniowe. Poniżej publikuję pierwszą serię &#8216;drobnicy&#8217; &#8211; projekty zaliczeniowe z I roku. Nie są może one zbyt ambitne (sprawy osobiste wymagały bardzo dużo uwagi), ale potrzebne zaliczenia dały <img src='http://temporal.pr0.pl/devblog/wp-includes/images/smilies/icon_wink.gif' alt=';)' class='wp-smiley' /> .</p>
<p><strong>Podstawy Użytkowania Komputerów (I semestr)</strong><br />
<a href="http://temporal.pr0.pl/devblog/download/is07/zaliczeniowki/PUK.zip">Pobierz prezentacje</a><br />
Zaliczeniem z <a href="http://temporal.pr0.pl/devblog/2007/12/13/swieze-buleczki-jak-pisac-specyfikacje/">najlepszego jak dotąd przedmiotu</a> z najlepszym jak dotąd prowadzącym <img src='http://temporal.pr0.pl/devblog/wp-includes/images/smilies/icon_smile.gif' alt=':)' class='wp-smiley' />  była prezentacja multimedialna oraz specyfikacja projektu technicznego. Ta druga zaginęła gdzieś w czeluściach Internetu (była robiona grupowo na jakiejś Wiki u <a href="http://wizualno-werbalny.blogspot.com/">Asmodeusza</a> na serwerze). Na temat prezentacji multimedialnej wybrałem wstęp do programowania gier. Nie dane było mi jej jednak przedstawić publicznie <img src='http://temporal.pr0.pl/devblog/wp-includes/images/smilies/icon_sad.gif' alt=':(' class='wp-smiley' /> .</p>
<p><strong>Podstawy Informatyki (I semestr)</strong><br />
<a href="http://temporal.pr0.pl/devblog/download/is07/zaliczeniowki/PI.zip">Pobierz paczkę</a><br />
W ramach zaliczenia przedmiotu oddałem trzy programy. Pierwsze dwa &#8211; konwerter kodu Morse&#8217;a i baza danych na drzewie binarnym &#8211; nie są warte uwagi (może za wyjątkiem sztuczki zastosowanej w bazie, by ułatwić sobie kasowanie elementów z drzewa <img src='http://temporal.pr0.pl/devblog/wp-includes/images/smilies/icon_biggrin.gif' alt=':D' class='wp-smiley' />  ). Trzecim programem jest wyjątkowo dopieszczony symulator <a href="http://pl.wikipedia.org/wiki/Gra_w_%C5%BCycie">gry w życie</a>. Opisy w Readme.</p>
<p><strong>Analiza Danych i Probabilistyka (II semestr)</strong><br />
<a href="http://temporal.pr0.pl/devblog/download/is07/zaliczeniowki/skladowe.zip">Pobierz <acronym title="Principal Component Analysis">PCA</acronym></a><br />
Program ten ilustruje <a href="http://pl.wikipedia.org/wiki/Analiza_g%C5%82%C3%B3wnych_sk%C5%82adowych">problematykę analizy i redukcji głównych składowych</a>. Oddany w terminie zdobyłby lekką ręką 6.0, jednak z powodu spóźnienia ocena była niższa <img src='http://temporal.pr0.pl/devblog/wp-includes/images/smilies/icon_sad.gif' alt=':(' class='wp-smiley' /> . Opis w Readme.</p>
<p>Na pierwszym roku stworzyłem jeszcze troszkę nie wartej publikacji drobnicy, która dała 6.0 i zwolnienie z języka C. Analogiczną ocenę i zwolnienie z C++&#8217;a dał framework Anything-A (retrofit <a href="http://temporal.pr0.pl/devblog/projekty/anything/">Anything</a>) <img src='http://temporal.pr0.pl/devblog/wp-includes/images/smilies/icon_smile.gif' alt=':)' class='wp-smiley' /> .</p>
<p>Trwa drugi rok, do tej pory wrzuciłem już <a href="http://temporal.pr0.pl/devblog/2009/01/23/softimagexsi-i-kaczka-startujaca-z-tafli-lodu/">jeden z projektów zaliczeniowych</a> i <a href="http://temporal.pr0.pl/devblog/2009/01/08/sprawozdanka/">sporo</a> <a href="http://temporal.pr0.pl/devblog/2009/01/21/metody-numeryczne-zadania-dodatkowe/">drobnicy</a>, która powstała w trakcie nauki. Z gotowych projektów może podrzucę za jakiś czas projekt zaliczeniowy z Programowania Obiektowego (gra w Javie). Ponadto, obecny &#8211; czwarty już &#8211; semestr zdaje się być wyjątkowo nasycony projektami; niewątpliwie nowych prac powstanie więcej <img src='http://temporal.pr0.pl/devblog/wp-includes/images/smilies/icon_smile.gif' alt=':)' class='wp-smiley' /> .</p>
]]></content:encoded>
			<wfw:commentRss>http://temporal.pr0.pl/devblog/2009/02/22/projekty-zaliczeniowe-rzut-pierwszy/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Limity OneNote</title>
		<link>http://temporal.pr0.pl/devblog/2009/02/20/limity-onenote/</link>
		<comments>http://temporal.pr0.pl/devblog/2009/02/20/limity-onenote/#comments</comments>
		<pubDate>Thu, 19 Feb 2009 22:08:19 +0000</pubDate>
		<dc:creator>Jacek Złydach</dc:creator>
				<category><![CDATA[Informatyka]]></category>
		<category><![CDATA[Pragmatyzm]]></category>
		<category><![CDATA[narzędzia]]></category>
		<category><![CDATA[OneNote]]></category>

		<guid isPermaLink="false">http://temporal.pr0.pl/devblog/?p=200</guid>
		<description><![CDATA[A jednak nawet OneNote ma swoje limity. Ostatnio w ramach nauki analizy matematycznej przygotowałem w pojedynczej notatce OneNote&#8217;a pewien konspekt, który po wydrukowaniu ma 23 strony. Oprócz tekstu zawiera on bardzo dużo wklejonych obrazków ze wzorami i fragmentami książki do matematyki. Przy takiej ilości danych w jednej notatce OneNote się poddaje &#8211; wczytanie notatki (gdy [...]]]></description>
			<content:encoded><![CDATA[<p>A jednak nawet <a href="http://temporal.pr0.pl/devblog/2007/12/19/onenote/">OneNote</a> ma swoje limity. Ostatnio w ramach nauki analizy matematycznej przygotowałem <em>w pojedynczej notatce OneNote&#8217;a</em> pewien konspekt, który po wydrukowaniu ma 23 strony. Oprócz tekstu zawiera on bardzo dużo wklejonych obrazków ze wzorami i fragmentami książki do matematyki. Przy takiej ilości danych w jednej notatce OneNote się poddaje &#8211; wczytanie notatki (gdy np. przełączaliśmy na inną) trwa nawet do minuty, a samo jej przewijanie też potrafi na chwilkę zamrozić program.</p>
<p>Wniosek jest oczywisty &#8211; pojedyncze notatki w programie OneNote nie nadają się do tworzenia <em>bardzo</em> długich dokumentów ze sporą ilością multimediów. Na szczęście nie jest to większy problem &#8211; wystarczy nie pakować wszystkiego do jednej notatki, ale tworzyć ich kilka (OneNote radzi sobie dobrze z drukowaniem całych sekcji na raz).</p>
]]></content:encoded>
			<wfw:commentRss>http://temporal.pr0.pl/devblog/2009/02/20/limity-onenote/feed/</wfw:commentRss>
		<slash:comments>1</slash:comments>
		</item>
		<item>
		<title>Denerwujące UAC?</title>
		<link>http://temporal.pr0.pl/devblog/2009/02/14/denerwujace-uac/</link>
		<comments>http://temporal.pr0.pl/devblog/2009/02/14/denerwujace-uac/#comments</comments>
		<pubDate>Sat, 14 Feb 2009 11:22:36 +0000</pubDate>
		<dc:creator>Jacek Złydach</dc:creator>
				<category><![CDATA[Kategoria nie przypisana]]></category>
		<category><![CDATA[bezpieczeństwo]]></category>
		<category><![CDATA[PowerShell]]></category>
		<category><![CDATA[UAC]]></category>
		<category><![CDATA[Vista]]></category>
		<category><![CDATA[Windows]]></category>

		<guid isPermaLink="false">http://temporal.pr0.pl/devblog/?p=210</guid>
		<description><![CDATA[UAC, czyli User Account Control albo Kontrola konta użytkownika to funkcja wprowadzona w systemie Windows Vista, która notorycznie jest wyłączana przez użytkowników. Zastanawiałem się ostatnio dlaczego, i nie widzę ku temu racjonalnych powodów.
Mówi się, że funkcja ta &#8216;jest upierdliwa, bo trzeba potwierdzać każdą drobną czynność&#8217;. Ale czy rzeczywiście? Zazwyczaj potwierdzenie wymagane jest jedynie w przypadku [...]]]></description>
			<content:encoded><![CDATA[<p><a href="http://en.wikipedia.org/wiki/User_Account_Control">UAC</a>, czyli <em>User Account Control</em> albo <em>Kontrola konta użytkownika</em> to funkcja wprowadzona w systemie Windows Vista, która notorycznie jest wyłączana przez użytkowników. Zastanawiałem się ostatnio dlaczego, i nie widzę ku temu racjonalnych powodów.</p>
<p>Mówi się, że funkcja ta &#8216;jest upierdliwa, bo trzeba potwierdzać każdą drobną czynność&#8217;. Ale czy rzeczywiście? Zazwyczaj potwierdzenie wymagane jest jedynie w przypadku instalacji oprogramowania (użytkownicy Windows XP są zapewne i tak przyzwyczajeni do komunikatów wyskakujących przy plikach .exe&#8230;) i zmiany ustawień systemowych, które mogą mieć wpływ na szeroko rozumiane bezpieczeństwo komputera. Rozumiem, że niektóre osoby (głównie gracze) instalują programy dość często, ale jakoś nie wyobrażam sobie ilości instalowanego oprogramowania, przy której jedno kliknięcie więcej stawałoby się na prawdę męczące.</p>
<p>Tak prawdę mówiąc (tutaj ukłon w stronę wszelkich Apostołów UNIXa), to UAC jest w pewnym sensie odpowiednikiem UNIXowych poleceń <a href="http://pl.wikipedia.org/wiki/Su_(Unix)">su</a> i <a href="http://en.wikipedia.org/wiki/Sudo">sudo</a>, które pozwalają nadać konkretnej aplikacji uprawnienia innego użytkownika (w szczególności administratora). W systemach UNIXowych zaleca się, by użytkownik korzystał z konta o uprawnieniach &#8216;zwykłych&#8217;, a w przypadku wyjątkowej potrzeby (instalacja, zmiana ustawień) nadawał konkretnej sesji / aplikacji tymczasowo wyższe uprawnienia przy użyciu su. Środowiska graficzne typu <a href="http://en.wikipedia.org/wiki/KDE">KDE</a>/<a href="http://en.wikipedia.org/wiki/GNOME">Gnome </a>potrafią nawet zapytać użytkownika o pozwolenie na uruchomienie konkretnej aplikacji z prawami administratora (i ewentualnie o hasło), jeśli jest to konieczne. Zauważmy, że niewiele się to różni od UAC oraz Windowsowego <a href="http://en.wikipedia.org/wiki/Runas">&#8216;Uruchom program jako&#8217;</a>.</p>
<p>Korzystanie z UAC podnosi bezpieczeństwo systemu, bo jeżeli cokolwiek potrzebuje za dużych uprawnień, to się o tym dowiemy. Tak zupełnie na marginesie, pozwala nam to też oceniać program pod kątem tego, co on tak na prawdę robi &#8211; mało prawdopodobne jest, żeby np. edytor tekstu wymagał uwierzytelnienia przez UAC&#8230;</p>
<p>Osobiście pracuję pod Windows Vista Home Premium już ponad rok i jak na razie mnie ta funkcja nie przeszkadza <img src='http://temporal.pr0.pl/devblog/wp-includes/images/smilies/icon_smile.gif' alt=':)' class='wp-smiley' /> . Dlatego zachęcam wszystkich do ponownego spojrzenia na UAC i nawet jeśli nie włączenie go to zastanowienie się, czy rzeczywiście jest to tak &#8216;upierdliwa&#8217; funkcja. Może są jeszcze inne konkretne powody, dla których ludzie decydują się wyłączyć UAC? Czytelniku, jeśli znasz taki to napisz o tym w komentarzu <img src='http://temporal.pr0.pl/devblog/wp-includes/images/smilies/icon_smile.gif' alt=':)' class='wp-smiley' /> . </p>
<p>PS. Użytkownicy <a href="http://pl.wikipedia.org/wiki/Windows_PowerShell">PowerShell</a>&#8216;a po zainstalowaniu <a href="http://www.codeplex.com/PowerShellCX">PowerShell Community Extensions</a> otrzymują m.in. polecenie su (alias na Elevate) <img src='http://temporal.pr0.pl/devblog/wp-includes/images/smilies/icon_wink.gif' alt=';)' class='wp-smiley' /> .</p>
]]></content:encoded>
			<wfw:commentRss>http://temporal.pr0.pl/devblog/2009/02/14/denerwujace-uac/feed/</wfw:commentRss>
		<slash:comments>4</slash:comments>
		</item>
		<item>
		<title>Układy klawiatury &#8211; gdy mieszają się znaki&#8230;</title>
		<link>http://temporal.pr0.pl/devblog/2009/02/12/uklady-klawiatury-gdy-mieszaja-sie-znaki/</link>
		<comments>http://temporal.pr0.pl/devblog/2009/02/12/uklady-klawiatury-gdy-mieszaja-sie-znaki/#comments</comments>
		<pubDate>Thu, 12 Feb 2009 11:07:55 +0000</pubDate>
		<dc:creator>Jacek Złydach</dc:creator>
				<category><![CDATA[Informatyka]]></category>
		<category><![CDATA[feedback]]></category>
		<category><![CDATA[interfejs użytkownika]]></category>
		<category><![CDATA[klawiatura]]></category>
		<category><![CDATA[poradnik]]></category>
		<category><![CDATA[UI]]></category>
		<category><![CDATA[Windows]]></category>

		<guid isPermaLink="false">http://temporal.pr0.pl/devblog/?p=213</guid>
		<description><![CDATA[Użytkownicy systemu Windows często spotykają się z bardzo ciekawym zjawiskiem &#8211; czasami program, do którego wpisujemy tekst nagle zaczyna reagować na klawisze inaczej niż zazwyczaj. Przykładowo litery &#8216;y&#8217; i &#8216;z&#8217; zamieniają się miejscami, zamiast średnika pojawia się polskie &#8216;ł&#8217;, itp. Wiele osób nie zna przyczyn tego &#8216;fenomenu&#8217; i często nie umie sobie z nim poradzić. [...]]]></description>
			<content:encoded><![CDATA[<p>Użytkownicy systemu Windows często spotykają się z bardzo ciekawym zjawiskiem &#8211; czasami program, do którego wpisujemy tekst nagle zaczyna reagować na klawisze inaczej niż zazwyczaj. Przykładowo litery &#8216;y&#8217; i &#8216;z&#8217; zamieniają się miejscami, zamiast średnika pojawia się polskie &#8216;ł&#8217;, itp. Wiele osób nie zna przyczyn tego &#8216;fenomenu&#8217; i często nie umie sobie z nim poradzić. A wszystkiemu winne są&#8230;<br />
<strong><br />
&#8230;klawisze CTRL, ALT i SHIFT oraz ustawienia klawiatur</strong>. Typowy użytkownik systemu Windows w Polsce ma zazwyczaj zainstalowane układy klawiszy o nazwach: <em>Polski (programisty)</em> i <em>Polski (maszynistki)/Polski (214)</em>. Zazwyczaj korzysta się z tego pierwszego układu, niemniej układów można mieć więcej i można je zmieniać. Dla naszej &#8216;wygody&#8217;, służy do tego skrót klawiszowy CTRL+SHIFT. Jego naciśnięcie powoduje zmianę używanego układu klawiatury, przez co nagle np. zamiast literki &#8216;z&#8217; pojawia się literka &#8216;y&#8217; i dzieją się inne temu podobne rzeczy. Tak się niestety składa, że pisząc tekst (a zwłaszcza klepiąc kod) często korzystamy z klawiszy CTRL i SHIFT. Bardzo łatwo jest wtedy omyłkowo nacisnąć te dwa klawisze na raz, co jest przyczyną wspomnianych &#8216;niewyjaśnionych zjawisk związanych z klawiaturą&#8217;. Lekarstwem na ten problem jest oczywiście ponowne naciśnięcie kombinacji CTRL+SHIFT.</p>
<p>Obok zmiany układu klawiatury mamy też pokrewną funkcję &#8211; zmiana używanego języka. Typowy system Windows w Polsce ma zainstalowany język polski; czasem zdarza się też język angielski oraz inne. Przełączenia między językami (a więc równocześnie między układami klawiatur używanymi w różnych językach) można dokonać za pomocą podobnej kombinacji lewy ALT+SHIFT. Omyłkowe jej naciśnięcie powoduje zjawisko <em>&#8216;zniknęły mi polskie znaki&#8217;</em> &#8211; obcojęzyczne układy klawiatur zazwyczaj nie mają polskich znaków diakrytycznych pod klawiszem ALT.</p>
<p>Fakt, że bardzo mało osób zdaje się wiedzieć o przyczynie powyższych anomalii znakowych wydaje mi się związany przede wszystkim z brakiem wyraźnego powiadamiania użytkownika o zmianie układu klawiatury. Aktualnie używany język i układ reprezentowany jest przez małą ikonkę z prawej strony paska zadań, obok tzw. obszaru powiadomień (zwane także <em>tray</em>, chodzi to miejsce, gdzie mamy słoneczko z Gadu-Gadu <img src='http://temporal.pr0.pl/devblog/wp-includes/images/smilies/icon_wink.gif' alt=';)' class='wp-smiley' />  ) i zegara systemowego. Przełączenie układu klawiatury powoduje jedynie dyskretną zmianę napisu na wspomnianej ikonce, co samo w sobie wystarczy, żeby większość osób nie zorientowało się, że naciśnięcie CTRL+SHIFT / ALT+SHIFT cokolwiek robi. Może kiedyś ktoś zwróci Microsoftowi na to uwagę, a na razie pozostaje jedynie wyłączać te skróty lub wiedzieć, że one istnieją i informować o tym znajomych, którzy nie wiedzą <img src='http://temporal.pr0.pl/devblog/wp-includes/images/smilies/icon_smile.gif' alt=':)' class='wp-smiley' /> .</p>
<p>Podsumowując w formie krótkiego <acronym title="Frequently Asked Questions">FAQ</acronym>:<br />
<strong>Zniknęły mi polskie znaki, co mam zrobić?</strong> Stuknij w lewy ALT+SHIFT.<br />
<strong>Zamiast &#8216;y&#8217; wpisuje mi się &#8216;z&#8217;, co mam zrobić?</strong> Stuknij w CTRL+SHIFT.<br />
<strong>Da się to jakoś naprawić na stałe?</strong> Można wyłączyć reagowanie na powyższe klawiszowe. W systemie Windows Vista kliknij prawym przyciskiem na wspomnianą w poprzednim akapicie ikonkę i wybierz menu <em>Ustawienia&#8230;</em>; w zakładce <em>Zaawansowane ustawienia klawiszy</em> (pod Windows XP zakładka <em>Ustawienia</em>) można zmienić lub wyłączyć reagowanie na oba powyższe skróty.</p>
]]></content:encoded>
			<wfw:commentRss>http://temporal.pr0.pl/devblog/2009/02/12/uklady-klawiatury-gdy-mieszaja-sie-znaki/feed/</wfw:commentRss>
		<slash:comments>1</slash:comments>
		</item>
		<item>
		<title>Trzy kropki&#8230;</title>
		<link>http://temporal.pr0.pl/devblog/2009/02/10/trzy-kropki/</link>
		<comments>http://temporal.pr0.pl/devblog/2009/02/10/trzy-kropki/#comments</comments>
		<pubDate>Tue, 10 Feb 2009 12:28:49 +0000</pubDate>
		<dc:creator>Jacek Złydach</dc:creator>
				<category><![CDATA[Informatyka]]></category>
		<category><![CDATA[Varia]]></category>
		<category><![CDATA[interfejs użytkownika]]></category>
		<category><![CDATA[projektowanie]]></category>
		<category><![CDATA[UI]]></category>
		<category><![CDATA[Windows]]></category>

		<guid isPermaLink="false">http://temporal.pr0.pl/devblog/?p=202</guid>
		<description><![CDATA[W systemie Windows i aplikacjach Microsoftu (oraz zapewne w wielu innych) panuje konsekwentnie* stosowany zwyczaj, że pozycje w menu, które otwierają okno dialogowe (na przykład wymagają wprowadzenia dodatkowych danych) kończą się wielokropkiem. Prosty przykład &#8211; menu Plik w Twojej ulubionej przeglądarce &#8211; pozycje Otwórz plik, czy Zapisz stronę powinny kończyć się wielokropkiem. W moim osobistym [...]]]></description>
			<content:encoded><![CDATA[<p>W systemie Windows i aplikacjach Microsoftu (oraz zapewne w wielu innych) panuje konsekwentnie<a name="POST_TRZYKROPKI_MT_1" href="#POST_TRZYKROPKI_REF_1">*</a> stosowany zwyczaj, że pozycje w menu, które otwierają okno dialogowe (na przykład wymagają wprowadzenia dodatkowych danych) kończą się wielokropkiem. Prosty przykład &#8211; menu Plik w Twojej ulubionej przeglądarce &#8211; pozycje Otwórz plik, czy Zapisz stronę powinny kończyć się wielokropkiem. W moim osobistym odczuciu ten zwyczaj jest dobry i wart kultywowania, choć prawdopodobnie mało znany.</p>
<p><a name="POST_TRZYKROPKI_REF_1" href="#POST_TRZYKROPKI_MT_1">*</a> Ok, przesadziłem z tą konsekwencją &#8211; np. w przypadku <acronym title="Internet Explorer 7">IE7</acronym> pozycja Opcje internetowe menu Narzędzia nie kończy się wielokropkiem&#8230; Prawdopodobnie nowe pokolenie programistów zapomina o takich rzeczach (i nowe pokolenie <a href="http://en.wikipedia.org/wiki/Quality_assurance">QA</a> też).</p>
]]></content:encoded>
			<wfw:commentRss>http://temporal.pr0.pl/devblog/2009/02/10/trzy-kropki/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Sens życia</title>
		<link>http://temporal.pr0.pl/devblog/2009/02/09/sens-zycia/</link>
		<comments>http://temporal.pr0.pl/devblog/2009/02/09/sens-zycia/#comments</comments>
		<pubDate>Mon, 09 Feb 2009 17:10:11 +0000</pubDate>
		<dc:creator>Jacek Złydach</dc:creator>
				<category><![CDATA[Z życia]]></category>
		<category><![CDATA[przemyślenia]]></category>
		<category><![CDATA[sens życia]]></category>

		<guid isPermaLink="false">http://temporal.pr0.pl/devblog/?p=194</guid>
		<description><![CDATA[Niedawno przebywałem w towarzystwie studentów różnych uczelni odpoczywających po ostatnim egzaminie/całej sesji i usłyszałem przy tym kilka interesujących rzeczy. Zastanowiły mnie na przykład słowa jednego żaka, który stwierdził, że jeśliby miał dożyć 50 lat, to woli już wcześniej umrzeć. Stwierdził, że kobiety już nie te, i ogólnie w tym wieku życie jest beznadziejne. Podsumował swoją [...]]]></description>
			<content:encoded><![CDATA[<p>Niedawno przebywałem w towarzystwie studentów różnych uczelni odpoczywających po ostatnim egzaminie/całej sesji i usłyszałem przy tym kilka interesujących rzeczy. Zastanowiły mnie na przykład słowa jednego <a href="http://pl.wikipedia.org/wiki/Student">żaka</a>, który stwierdził, że jeśliby miał dożyć 50 lat, to woli już wcześniej umrzeć. Stwierdził, że kobiety już nie te, i ogólnie w tym wieku życie jest beznadziejne. Podsumował swoją wypowiedź myślą, że &#8216;życie toczy się tu i teraz, i teraz trzeba z niego korzystać&#8217;.</p>
<p>Kolejną ciekawą rzeczą, którą wtedy usłyszałem to historia o obozach wojskowych szkół średnich. Podobno jeden z uczestników tego obozu stwierdził, że największym marzeniem (i <a href="http://pl.wikipedia.org/wiki/De_facto">de facto</a> celem?) jego życia jest zdobyć na polu bitwy bliznę na skos przez całą twarz.</p>
<p>Ciekawe, czy są to tylko specyficzne przypadki, czy też podobne poglądy i przemyślenia ma więcej osób? Przypomina się w tym miejscu <a href="http://lelox.pl.wrzuta.pl/audio/jhbGJaBagJ/stacie_orrico_-_more_to_life">piosenka</a> <a href="http://pl.wikipedia.org/wiki/Stacie_Orrico">Stacie Orrico</a>:</p>
<blockquote><p>There&#8217;s gotta be more to life&#8230;<br />
Than chasing down every temporary high to satisfy me</p></blockquote>
]]></content:encoded>
			<wfw:commentRss>http://temporal.pr0.pl/devblog/2009/02/09/sens-zycia/feed/</wfw:commentRss>
		<slash:comments>1</slash:comments>
		</item>
		<item>
		<title>Upgrade!</title>
		<link>http://temporal.pr0.pl/devblog/2009/01/23/upgrade/</link>
		<comments>http://temporal.pr0.pl/devblog/2009/01/23/upgrade/#comments</comments>
		<pubDate>Fri, 23 Jan 2009 20:46:03 +0000</pubDate>
		<dc:creator>Jacek Złydach</dc:creator>
				<category><![CDATA[devBlog - Techniczne]]></category>
		<category><![CDATA[aktualizacje]]></category>
		<category><![CDATA[wordpress]]></category>

		<guid isPermaLink="false">http://temporal.pr0.pl/devblog/2009/01/23/upgrade/</guid>
		<description><![CDATA[WordPress zaktualizowany do wersji 2.7!   Blog jest już sprawny i można z niego korzystać. Jak na razie nie znalazłem nowych usterek, a dotychczasowe zostały opanowane. W tej chwili eksperymentuję sobie z tagami i chmurką tagów; jeśli będą wyglądać ładnie, to zostaną na stałe.
Wszystkim stałym i niestałym Czytelnikom życzę miłej lektury devBloga na nowym [...]]]></description>
			<content:encoded><![CDATA[<p>WordPress zaktualizowany do wersji 2.7! <img src='http://temporal.pr0.pl/devblog/wp-includes/images/smilies/icon_smile.gif' alt=':)' class='wp-smiley' />  Blog jest już sprawny i można z niego korzystać. Jak na razie nie znalazłem nowych usterek, a dotychczasowe zostały opanowane. W tej chwili eksperymentuję sobie z tagami i chmurką tagów; jeśli będą wyglądać ładnie, to zostaną na stałe.</p>
<p>Wszystkim stałym i niestałym Czytelnikom życzę miłej lektury devBloga na nowym silniku <img src='http://temporal.pr0.pl/devblog/wp-includes/images/smilies/icon_smile.gif' alt=':)' class='wp-smiley' /> .</p>
]]></content:encoded>
			<wfw:commentRss>http://temporal.pr0.pl/devblog/2009/01/23/upgrade/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Softimage&#124;XSI i Kaczka startująca z tafli lodu</title>
		<link>http://temporal.pr0.pl/devblog/2009/01/23/softimagexsi-i-kaczka-startujaca-z-tafli-lodu/</link>
		<comments>http://temporal.pr0.pl/devblog/2009/01/23/softimagexsi-i-kaczka-startujaca-z-tafli-lodu/#comments</comments>
		<pubDate>Fri, 23 Jan 2009 11:56:53 +0000</pubDate>
		<dc:creator>Jacek Złydach</dc:creator>
				<category><![CDATA[Grafika Komputerowa]]></category>
		<category><![CDATA[Projekty studenckie]]></category>
		<category><![CDATA[AGH]]></category>
		<category><![CDATA[Humor]]></category>
		<category><![CDATA[porady]]></category>
		<category><![CDATA[Softimage|XSI]]></category>

		<guid isPermaLink="false">http://temporal.pr0.pl/devblog/2009/01/23/softimagexsi-i-kaczka-startujaca-z-tafli-lodu/</guid>
		<description><![CDATA[Przedwczoraj Informatyka Stosowana oddawała prace zaliczeniowe na przedmiot Podstawy Grafiki Komputerowej. Tematem była animacja kaczki startującej z tafli lodu. Na laboratoriach z PGK uczyliśmy się obsługi programu Softimage&#124;XSI i większość prac powstała w tym właśnie programie.
Poradnik Softimage&#124;XSI Tips&#038;Tricks
Opublikowałem tutaj w formie artykułu poradnik, który zamieściłem na forum Informatyki Stosowanej. Mam nadzieję, że przyda się każdemu, [...]]]></description>
			<content:encoded><![CDATA[<p>Przedwczoraj Informatyka Stosowana oddawała prace zaliczeniowe na przedmiot Podstawy Grafiki Komputerowej. Tematem była animacja kaczki startującej z tafli lodu. Na laboratoriach z PGK uczyliśmy się obsługi programu <a href="http://en.wikipedia.org/wiki/Softimage_XSI">Softimage|XSI</a> i większość prac powstała w tym właśnie programie.</p>
<p><strong>Poradnik Softimage|XSI Tips&#038;Tricks</strong><br />
Opublikowałem tutaj w formie artykułu poradnik, który zamieściłem na forum Informatyki Stosowanej. Mam nadzieję, że przyda się każdemu, kto zaczyna lub będzie zaczynał modelowanie w XSI (zwłaszcza na projekt zaliczeniowy).<br />
<strong><a href="http://temporal.pr0.pl/devblog/artykuly/softimage-autodesk-xsi-tipstricks/">Link do poradnika</a></strong></p>
<p><strong>Animacje</strong><br />
Wiele grup oddało animacje na bardzo wysokim poziomie, dzięki czemu ostatnie zajęcia z grafiki komputerowej (spędzone na prezentowaniu projektów) były bardzo ciekawe i wesołe. Poniżej kilka prac, które szczególnie mi się podobały:<br />
<center><object width="425" height="344"><param name="movie" value="http://www.youtube.com/v/_2_t7FMa7R0&#038;hl=pl&#038;fs=1&#038;color1=0x006699&#038;color2=0x54abd6"></param><param name="allowFullScreen" value="true"></param><param name="allowscriptaccess" value="always"></param><embed src="http://www.youtube.com/v/_2_t7FMa7R0&#038;hl=pl&#038;fs=1&#038;color1=0x006699&#038;color2=0x54abd6" type="application/x-shockwave-flash" allowscriptaccess="always" allowfullscreen="true" width="425" height="344"></embed></object></center><br />
Autorzy powyższej animacji nieźle się postarali, żeby uniknąć niepotrzebnych animacji w XSI <img src='http://temporal.pr0.pl/devblog/wp-includes/images/smilies/icon_wink.gif' alt=';)' class='wp-smiley' /> .</p>
<p><center><object width="425" height="344"><param name="movie" value="http://www.youtube.com/v/Q9e4zsWh10E&#038;hl=pl&#038;fs=1&#038;color1=0x006699&#038;color2=0x54abd6"></param><param name="allowFullScreen" value="true"></param><param name="allowscriptaccess" value="always"></param><embed src="http://www.youtube.com/v/Q9e4zsWh10E&#038;hl=pl&#038;fs=1&#038;color1=0x006699&#038;color2=0x54abd6" type="application/x-shockwave-flash" allowscriptaccess="always" allowfullscreen="true" width="425" height="344"></embed></object></center><br />
Rakieta pierwszej klasy <img src='http://temporal.pr0.pl/devblog/wp-includes/images/smilies/icon_smile.gif' alt=':)' class='wp-smiley' /> </p>
<p><center><object width="480" height="295"><param name="movie" value="http://www.youtube.com/v/ZVjtuNHu70s&#038;hl=pl&#038;fs=1&#038;color1=0x006699&#038;color2=0x54abd6"></param><param name="allowFullScreen" value="true"></param><param name="allowscriptaccess" value="always"></param><embed src="http://www.youtube.com/v/ZVjtuNHu70s&#038;hl=pl&#038;fs=1&#038;color1=0x006699&#038;color2=0x54abd6" type="application/x-shockwave-flash" allowscriptaccess="always" allowfullscreen="true" width="480" height="295"></embed></object></center><br />
Cel-Shading na wysokim poziomie.</p>
<p><center><object width="425" height="344"><param name="movie" value="http://www.youtube.com/v/LSOWesx596E&#038;hl=pl&#038;fs=1&#038;color1=0x006699&#038;color2=0x54abd6"></param><param name="allowFullScreen" value="true"></param><param name="allowscriptaccess" value="always"></param><embed src="http://www.youtube.com/v/LSOWesx596E&#038;hl=pl&#038;fs=1&#038;color1=0x006699&#038;color2=0x54abd6" type="application/x-shockwave-flash" allowscriptaccess="always" allowfullscreen="true" width="425" height="344"></embed></object></center><br />
A ta praca powstała&#8230; w Blenderze <img src='http://temporal.pr0.pl/devblog/wp-includes/images/smilies/icon_smile.gif' alt=':)' class='wp-smiley' /> .</p>
<p><center><object width="425" height="344"><param name="movie" value="http://www.youtube.com/v/4XoL0tGDcY4&#038;hl=pl&#038;fs=1&#038;color1=0x006699&#038;color2=0x54abd6"></param><param name="allowFullScreen" value="true"></param><param name="allowscriptaccess" value="always"></param><embed src="http://www.youtube.com/v/4XoL0tGDcY4&#038;hl=pl&#038;fs=1&#038;color1=0x006699&#038;color2=0x54abd6" type="application/x-shockwave-flash" allowscriptaccess="always" allowfullscreen="true" width="425" height="344"></embed></object></center><br />
Trailer filmu <img src='http://temporal.pr0.pl/devblog/wp-includes/images/smilies/icon_smile.gif' alt=':)' class='wp-smiley' /> .</p>
<p>A na koniec moja:<br />
<center><object width="425" height="344"><param name="movie" value="http://www.youtube.com/v/_H1QGaP18-8&#038;hl=pl&#038;fs=1&#038;color1=0x006699&#038;color2=0x54abd6"></param><param name="allowFullScreen" value="true"></param><param name="allowscriptaccess" value="always"></param><embed src="http://www.youtube.com/v/_H1QGaP18-8&#038;hl=pl&#038;fs=1&#038;color1=0x006699&#038;color2=0x54abd6" type="application/x-shockwave-flash" allowscriptaccess="always" allowfullscreen="true" width="425" height="344"></embed></object></center></p>
]]></content:encoded>
			<wfw:commentRss>http://temporal.pr0.pl/devblog/2009/01/23/softimagexsi-i-kaczka-startujaca-z-tafli-lodu/feed/</wfw:commentRss>
		<slash:comments>12</slash:comments>
		</item>
		<item>
		<title>Metody numeryczne &#8211; zadania dodatkowe</title>
		<link>http://temporal.pr0.pl/devblog/2009/01/21/metody-numeryczne-zadania-dodatkowe/</link>
		<comments>http://temporal.pr0.pl/devblog/2009/01/21/metody-numeryczne-zadania-dodatkowe/#comments</comments>
		<pubDate>Wed, 21 Jan 2009 20:16:25 +0000</pubDate>
		<dc:creator>Jacek Złydach</dc:creator>
				<category><![CDATA[Matematyka]]></category>
		<category><![CDATA[Projekty studenckie]]></category>
		<category><![CDATA[AGH]]></category>
		<category><![CDATA[eliminacja Gaussa]]></category>
		<category><![CDATA[metody numeryczne]]></category>
		<category><![CDATA[SOR]]></category>
		<category><![CDATA[SPLINE]]></category>

		<guid isPermaLink="false">http://temporal.pr0.pl/devblog/2009/01/21/metody-numeryczne-zadania-dodatkowe/</guid>
		<description><![CDATA[Dla dobra Galaktyki podobnie jak w poprzednim przypadku publikuję dość obszerne opracowania następujących tematów:

Metoda Sukcesywnej Nadrelaksacji (teoria i praktyka)
Metoda eliminacji Gaussa z całkowitym wyborem elementu głównego (teoria i praktyka)
Wyprowadzenie i omówienie wzorów na interpolację SPLINE stopnia drugiego (teoria i praktyka)

Dodatkowo zamieszczam też erratę do dotychczasowych zadanek. Na wszelki wypadek wymienione w niej błędy zostały poprawione [...]]]></description>
			<content:encoded><![CDATA[<p>Dla dobra Galaktyki podobnie jak w <a href="http://temporal.pr0.pl/devblog/2009/01/08/sprawozdanka/">poprzednim przypadku</a> publikuję dość obszerne opracowania następujących tematów:</p>
<ul>
<li>Metoda Sukcesywnej Nadrelaksacji (<a href="http://temporal.pr0.pl/devblog/download/numerki/sprawozdanka/zad1_sor_teoria.pdf">teoria</a> i <a href="http://temporal.pr0.pl/devblog/download/numerki/sprawozdanka/sor%20-%20praktyka.pdf">praktyka</a>)</li>
<li>Metoda eliminacji Gaussa z całkowitym wyborem elementu głównego (<a href="http://temporal.pr0.pl/devblog/download/numerki/sprawozdanka/zad2_gauss_teoria.pdf">teoria</a> i <a href="http://temporal.pr0.pl/devblog/download/numerki/sprawozdanka/gauss%20-%20praktyka.pdf">praktyka</a>)</li>
<li>Wyprowadzenie i omówienie wzorów na interpolację SPLINE stopnia drugiego (<a href="http://temporal.pr0.pl/devblog/download/numerki/sprawozdanka/zad3_spline2_teoria.pdf">teoria</a> i <a href="http://temporal.pr0.pl/devblog/download/numerki/sprawozdanka/Mathcad%20-%20zad3_spline.pdf">praktyka</a>)</li>
</ul>
<p>Dodatkowo zamieszczam też <a href="http://temporal.pr0.pl/devblog/download/numerki/sprawozdanka/errata.pdf">erratę</a> do dotychczasowych zadanek. Na wszelki wypadek wymienione w niej błędy zostały poprawione w sprawozdaniach dostępnych w chwili obecnej na moim blogu.</p>
<p>Mam nadzieję, że te dokumenty &#8211; podobnie jak poprzednie &#8211; okażą się dla kogoś przydatne i/lub ciekawe <img src='http://temporal.pr0.pl/devblog/wp-includes/images/smilies/icon_smile.gif' alt=':)' class='wp-smiley' /> </p>
]]></content:encoded>
			<wfw:commentRss>http://temporal.pr0.pl/devblog/2009/01/21/metody-numeryczne-zadania-dodatkowe/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>IT Giants 2009 &#8211; przemyślenia studenta IS</title>
		<link>http://temporal.pr0.pl/devblog/2009/01/15/it-giants-2009-przemyslenia-studenta-is/</link>
		<comments>http://temporal.pr0.pl/devblog/2009/01/15/it-giants-2009-przemyslenia-studenta-is/#comments</comments>
		<pubDate>Thu, 15 Jan 2009 10:57:57 +0000</pubDate>
		<dc:creator>Jacek Złydach</dc:creator>
				<category><![CDATA[Informatyka]]></category>
		<category><![CDATA[Varia]]></category>
		<category><![CDATA[Z życia]]></category>
		<category><![CDATA[AGH]]></category>
		<category><![CDATA[GNU]]></category>
		<category><![CDATA[konferencje]]></category>
		<category><![CDATA[XKCD]]></category>

		<guid isPermaLink="false">http://temporal.pr0.pl/devblog/2009/01/15/it-giants-2009-przemyslenia-studenta-is/</guid>
		<description><![CDATA[Wczoraj, tj. 14.09.2009, odbyła się w Krakowie konferencja IT Giants. Zaciągnął mnie tam kolega z roku i po wysłuchaniu kilku wykładów, w tym pana Stallmana, chciałbym podzielić się paroma osobistymi przemyśleniami.
Na konferencję przybyliśmy po godzinie 15:00, w trakcie trwania wykładu pana profesora Krzysztofa Zielińskiego pt. &#8220;Free Software in Services Computing Infrastructure Implementation&#8221;. Powiem szczerze i [...]]]></description>
			<content:encoded><![CDATA[<p>Wczoraj, tj. 14.09.2009, odbyła się w Krakowie konferencja <a href="http://itgiants.org/itg2009/">IT Giants</a>. Zaciągnął mnie tam kolega z roku i po wysłuchaniu kilku wykładów, w tym pana <a href="http://pl.wikipedia.org/wiki/Richard_Stallman">Stallmana</a>, chciałbym podzielić się paroma osobistymi przemyśleniami.</p>
<p>Na konferencję przybyliśmy po godzinie 15:00, w trakcie trwania wykładu pana profesora Krzysztofa Zielińskiego pt. <em>&#8220;Free Software in Services Computing Infrastructure Implementation&#8221;</em>. Powiem szczerze i otwarcie, że z tego wykładu nic nie zrozumiałem <img src='http://temporal.pr0.pl/devblog/wp-includes/images/smilies/icon_smile.gif' alt=':)' class='wp-smiley' /> . Obfitował w dużą liczbę angielskich biznesowych terminów i schematów wprowadzanych przy założeniu, że wiemy o co chodzi. Jedyne, co udało mi się wyłapać to informacja, że te wszystkie wielkie-i-ważne-rzeczy implementuje się w Javie.</p>
<p>Kolejnym prelegentem był znany nam już z zeszłego semestru dr GJN &#8211; <a href="http://home.agh.edu.pl/~gjn/">doktor Grzegorz J. Nalepa</a>. Wygłosił wykład pt. <em>&#8220;Free Software at AGH UST &#8211; a personal perspective&#8221;</em>. Wykład bardzo ciekawy i równocześnie humorystyczny; przede wszystkim bardzo przystępny dla wszystkich odbiorców. Jako studenci <a href="http://www.eaie.agh.edu.pl/">EAIiE</a> mieliśmy dodatkowy komfort, bo z wieloma omawianymi rzeczami mamy styczność na codzień. Ogólne wrażenia: bardzo pozytywne <img src='http://temporal.pr0.pl/devblog/wp-includes/images/smilies/icon_smile.gif' alt=':)' class='wp-smiley' /> .</p>
<p>Następne przemówienie nosiło tytuł: <em>&#8220;Internet &#8211; przestrzeń wolności? Czy tylko dzięki otwartym rozwiązaniom?&#8221;</em>, a wygłosił je pan Łukasz Wejchert, prezes Onetu. Ważnym elementem tego wystąpienia było omówienie architektury Onetu oraz sposobu, w jaki radzą sobie z problemami bycia najczęściej (po Naszej-Klasie) odwiedzanym portalem w Polsce. Onet wyróżnił się w popołudniowej części (co się działo rano, nie wiem) bardzo pragmatycznym podejściem do kwestii wolnego i komercyjnego oprogramowania &#8211; ogólny klimat był bardzo pro-free software&#8217;owy, podczas gdy pan Łukasz podkreślił, że jego firma korzysta z tego oprogramowania, które jest w danym przypadku bardziej praktyczne. Po przemówieniu nastąpiła specyficzna sesja pytań i odpowiedzi. Dyskusja bardzo szybko przerodziła się w spór polityczny na temat wolności słowa; w moim odczuciu niektóre osoby skorzystały z faktu, że na sali pojawiły się kamery telewizyjne, wy wygłosić kilkuminutowe przemówienia na temat swoich poglądów. Na szczęście w pewnym momencie dwóch studentów AGH sprowadziło rozmowę z powrotem na tematy techniczne i burza emocji ucichła.</p>
<p>Potem wyszedłem po ciasteczka i spóźniłem się na przemówienie premiera RP <a href="http://pl.wikipedia.org/wiki/Waldemar_Pawlak">Waldemara Pawlaka</a> <img src='http://temporal.pr0.pl/devblog/wp-includes/images/smilies/icon_smile.gif' alt=':)' class='wp-smiley' /> . Przemówienie ciekawe, ale w moim odczuciu trudne do zrozumienia dla studenta nie znającego klimatów i terminologii politycznej.</p>
<p>W międzyczasie sala zaczęła się napełniać (a raczej przepełniać) i nastąpiło wyczekiwane przez wszystkich wystąpienie pana Stallmana w przemówieniu pod tytułem <em>&#8220;Copyright vs Community in the Age of Computer Networks&#8221;</em>. Stallman zwrócił uwagę na ciekawe problemy, jakie wynikły w związku z rozwojem techniki kopiowania danych &#8211; począwszy od przepisywania książek ręcznie, przez prasę drukarską, a na współczesnej technice cyfrowej skończywszy. Od strony formy pan Stallman prezentował bardzo elegencką i zrozumiałą wymowę angielskiego, ale równocześnie specyficzny język, moim zdaniem wręcz propagandowy. Stosował bardzo dużo górnolotnych haseł oraz wysnuwał kontrowersyjne etycznie i moralnie wnioski. Ogólnie ujmując celem wykładu było zapoznanie nas z (i ewentualnie przekonanie do) poglądem pana Stallmana na rzeczywistość, niekoniecznie czysto informatyczną. Wykład zakończył się sesją pytań oraz aukcją, na której za ok. 400zł sprzedano maskotkę antylopy GNU, a za 700zł książkę Stallmana zawierającą jego przemyślenia.</p>
<p>Stallman bardzo intensywnie podkreślał różnice między free software, a open-source (jeden z poprzednich mówców został nawet w sposób nie-wprost publicznie upomniany przez Stallmana za zbyt małe podkreślanie tej różnicy), wywołując przy okazji pod koniec kolejną polityczną dyskusję.</p>
<p>Ogólny nastrój popołudniowej części konferencji był mało informatyczny, a bardzo polityczny. Moje odczucia wyglądają następująco: <strong>konferencja to taki wykład, tylko większy, są ważniejsi i bardziej znani prelegenci, jest więcej słuchaczy, materiał jest trudniejszy, dużo mniej zrozumiały i dużo mniej przydatny do czegokolwiek</strong>.</p>
<p>PS. Stallman spytany o to, jak przeżył atak <a href="http://www.boingboing.net/2007/10/21/ninjas-attack-richar.html">Ninja z XKCD</a> odpowiedział, że w chwili ataku nie znał tego odcinka komiksu i nie rozumiał dowcipu, który został mu wytłumaczony dopiero później <img src='http://temporal.pr0.pl/devblog/wp-includes/images/smilies/icon_smile.gif' alt=':)' class='wp-smiley' /> .</p>
<p>PPS. Tyle się na konferencji mówiło o Free Software, ale jak okiem sięgnąć, wszyscy na laptopach mieli Windows Vista <img src='http://temporal.pr0.pl/devblog/wp-includes/images/smilies/icon_smile.gif' alt=':)' class='wp-smiley' /> .</p>
<p>PPPS. I dało się wejść na konferencję bez wcześniejszej rejestracji na stronie <img src='http://temporal.pr0.pl/devblog/wp-includes/images/smilies/icon_smile.gif' alt=':)' class='wp-smiley' /> .</p>
]]></content:encoded>
			<wfw:commentRss>http://temporal.pr0.pl/devblog/2009/01/15/it-giants-2009-przemyslenia-studenta-is/feed/</wfw:commentRss>
		<slash:comments>2</slash:comments>
		</item>
		<item>
		<title>Sprawozdanka</title>
		<link>http://temporal.pr0.pl/devblog/2009/01/08/sprawozdanka/</link>
		<comments>http://temporal.pr0.pl/devblog/2009/01/08/sprawozdanka/#comments</comments>
		<pubDate>Thu, 08 Jan 2009 18:29:46 +0000</pubDate>
		<dc:creator>Jacek Złydach</dc:creator>
				<category><![CDATA[Matematyka]]></category>
		<category><![CDATA[Projekty studenckie]]></category>
		<category><![CDATA[AGH]]></category>
		<category><![CDATA[aproksymacja]]></category>
		<category><![CDATA[eliminacja Gaussa]]></category>
		<category><![CDATA[metody numeryczne]]></category>
		<category><![CDATA[SPLINE]]></category>

		<guid isPermaLink="false">http://temporal.pr0.pl/devblog/2009/01/08/sprawozdanka/</guid>
		<description><![CDATA[Z okazji zbliżającego się kolokwium z numerków oraz dla szeroko rozumianego Dobra Galaktyki postanowiłem udostępnić swoje ostatnie sprawozdanka z Metod Numerycznych. W stworzenie ich włożyłem dość dużo czasu i wysiłku, ale mam nadzieję, że przydadza się każdemu, kto nie lubi uczyć się matematyki z samych wzorów i woli przy okazji poczytać jakąś &#8216;bajeczkę&#8217;  .
Sprawozdanie [...]]]></description>
			<content:encoded><![CDATA[<p>Z okazji zbliżającego się kolokwium z numerków oraz dla szeroko rozumianego Dobra Galaktyki postanowiłem udostępnić swoje ostatnie sprawozdanka z Metod Numerycznych. W stworzenie ich włożyłem dość dużo czasu i wysiłku, ale mam nadzieję, że przydadza się każdemu, kto nie lubi uczyć się matematyki z samych wzorów i woli przy okazji poczytać jakąś &#8216;bajeczkę&#8217; <img src='http://temporal.pr0.pl/devblog/wp-includes/images/smilies/icon_wink.gif' alt=';)' class='wp-smiley' /> .</p>
<p><a href="http://temporal.pr0.pl/devblog/download/numerki/sprawozdanka/Rownanka%20-%20teoria.pdf">Sprawozdanie III &#8211; Układy równań liniowych (teoria)</a><br />
<a href="http://temporal.pr0.pl/devblog/download/numerki/sprawozdanka/rownanka%20-%20praktyka.pdf">Sprawozdanie III &#8211; Układy równań liniowych (praktyka)</a></p>
<p><a href="http://temporal.pr0.pl/devblog/download/numerki/sprawozdanka/Aproksyksy%20-%20teoria.pdf">Sprawozdanie IV &#8211; Aproksymacja (teoria)</a><br />
<a href="http://temporal.pr0.pl/devblog/download/numerki/sprawozdanka/aproksyksy%20-%20praktyka.pdf">Sprawozdanie IV &#8211; Aproksymacja (praktyka)</a></p>
<p><strong>EDIT &#8211; Errata</strong><br />
Sprawozdanka już dorobiły się erraty <img src='http://temporal.pr0.pl/devblog/wp-includes/images/smilies/icon_smile.gif' alt=':)' class='wp-smiley' />  &#8211; jak się błędów zbierze więcej, to poprawię i podepnę nowe pliki. Na razie zostało mieć tylko nadzieję, że prowadzący z Metod Numerycznych nie zauważą <img src='http://temporal.pr0.pl/devblog/wp-includes/images/smilies/icon_smile.gif' alt=':)' class='wp-smiley' /> .</p>
<ul>
<li><strong>Sprawozdanie IV (Aproksymacja) &#8211; Teoria, str. 3, ak.1</strong> &#8211; wykreślić zdanie w nawiasie (&#8220;warto zauważyć, że &#8230;&#8221;) &#8211; ostatecznie nie jestem pewien tego twierdzenia.</li>
</ul>
]]></content:encoded>
			<wfw:commentRss>http://temporal.pr0.pl/devblog/2009/01/08/sprawozdanka/feed/</wfw:commentRss>
		<slash:comments>2</slash:comments>
		</item>
		<item>
		<title>Uwarunkowanie macierzy</title>
		<link>http://temporal.pr0.pl/devblog/2008/12/12/uwarunkowanie-macierzy/</link>
		<comments>http://temporal.pr0.pl/devblog/2008/12/12/uwarunkowanie-macierzy/#comments</comments>
		<pubDate>Fri, 12 Dec 2008 13:48:37 +0000</pubDate>
		<dc:creator>Jacek Złydach</dc:creator>
				<category><![CDATA[Matematyka]]></category>
		<category><![CDATA[macierze]]></category>
		<category><![CDATA[metody numeryczne]]></category>
		<category><![CDATA[uwarunkowanie]]></category>

		<guid isPermaLink="false">http://temporal.pr0.pl/devblog/2008/12/12/uwarunkowanie-macierzy/</guid>
		<description><![CDATA[Ten post jest matematyczny więc ostrzegam, że nie każdy może mieć ochotę go czytać  . Mnie by się nie chciało  
Ostatnimi czasy na studiach daje mi w kość przedmiot zwany Metodami Numerycznymi. Niedługo poprawa kolokwium, egzamin połówkowy i takie tam inne  . W związku z tym zacząłem zgłębiać temat uwarunkowania macierzy i [...]]]></description>
			<content:encoded><![CDATA[<p><em><strong>Ten post jest matematyczny więc ostrzegam, że nie każdy może mieć ochotę go czytać <img src='http://temporal.pr0.pl/devblog/wp-includes/images/smilies/icon_razz.gif' alt=':P' class='wp-smiley' /> . Mnie by się nie chciało <img src='http://temporal.pr0.pl/devblog/wp-includes/images/smilies/icon_wink.gif' alt=';)' class='wp-smiley' /> </strong></em></p>
<p>Ostatnimi czasy na studiach daje mi w kość przedmiot zwany Metodami Numerycznymi. Niedługo poprawa kolokwium, egzamin połówkowy i takie tam inne <img src='http://temporal.pr0.pl/devblog/wp-includes/images/smilies/icon_smile.gif' alt=':)' class='wp-smiley' /> . W związku z tym zacząłem zgłębiać temat uwarunkowania macierzy i doszedłem do dość dziwnych obserwacji.</p>
<p>Zacznijmy od podstaw teoretycznych, czyli jak definiujemy uwarunkowanie macierzy:</p>
<p><img src="http://temporal.pr0.pl/devblog/download/numerki/uwarunkowanie/wzor_1.PNG" alt="Wzór na współczynnik uwarunkowania macierzy" /></p>
<p>gdzie zapis ||A|| oznacza normę macierzy A. Norm możemy ustalić wiele; w przypadku macierzy stosuje się często normy: <strong>wierszową</strong>, <strong>kolumnową </strong>i <strong>spektralną</strong>. Nie będę tu ich tłumaczył, szkoda miejsca <img src='http://temporal.pr0.pl/devblog/wp-includes/images/smilies/icon_wink.gif' alt=';)' class='wp-smiley' /> .<br />
Wobec powyższego powstaje naturalne pytanie: <em>której normy użyć do obliczeń współczynnika uwarunkowania?</em></p>
<p>W wykładach i książkach (Fortuna <img src='http://temporal.pr0.pl/devblog/wp-includes/images/smilies/icon_wink.gif' alt=';)' class='wp-smiley' />  ) niewiele znalazłem, Wikipedia też nie pomaga. Jako leniwy ale kreatywny student postanowiłem nie szukać intensywnie odpowiedzi po forach matematycznych, tylko przeprowadzić małe badania. Zadałem pytania:</p>
<ul>
<li><strong>Właściwie jak to jest z tymi normami? Czy dla danej macierzy te trzy normy są identyczne albo chociaż podobne?</strong></li>
<li><strong>Jak różnią się od siebie współczynniki uwarunkowania macierzy w zależności od wybranej normy?</strong></li>
</ul>
<p>W znalezieniu odpowiedzi pomógł <a href="http://pl.wikipedia.org/wiki/MATLAB">MATLAB</a>. Skrypt, którym przeprowadziłem badania można pobrać tutaj: <a href="http://temporal.pr0.pl/devblog/download/numerki/uwarunkowanie/uwarunkowania.m">[SKRYPT]</a> (<a href="http://pl.wikipedia.org/wiki/GNU_Octave">Octave</a>-compatibile <img src='http://temporal.pr0.pl/devblog/wp-includes/images/smilies/icon_smile.gif' alt=':)' class='wp-smiley' />  ). W doświadczeniu tym generowałem po 10 losowych macierzy NxN, gdzie N zmieniało się od 2 do 300. Pozwala to tak z grubsza wyrobić sobie jakąś opinię na temat tego, jak rosną normy i współczynniki uwarunkowania zależnie od rozmiaru macierzy.<br />
Poniżej garść obrazków z MATLABa:</p>
<p><center><br />
<a href="http://temporal.pr0.pl/devblog/download/numerki/uwarunkowanie/normy_fragment.png"><img src="http://temporal.pr0.pl/devblog/download/numerki/uwarunkowanie/normy_fragment_128.png" alt="Fragment wykresu norm macierzy" style="border: solid black 1px;" height="100px" /></a><a href="http://temporal.pr0.pl/devblog/download/numerki/uwarunkowanie/uwarunkowania.png"><img src="http://temporal.pr0.pl/devblog/download/numerki/uwarunkowanie/uwarunkowania_128.png" alt="Współczynniki uwarunkowania" style="border: solid black 1px;" height="100px" /></a></p>
<p><a href="http://temporal.pr0.pl/devblog/download/numerki/uwarunkowanie/uwarunkowania_log.png"><img src="http://temporal.pr0.pl/devblog/download/numerki/uwarunkowanie/uwarunkowania_log_128.png" alt="Współczynniki uwarunkowania - skala logarytmiczna" style="border: solid black 1px;" height="100px" /></a><a href="http://temporal.pr0.pl/devblog/download/numerki/uwarunkowanie/uwarunkowania_logpoints.png"><img src="http://temporal.pr0.pl/devblog/download/numerki/uwarunkowanie/uwarunkowania_logpoints_128.png" alt="Współczynniki uwarunkowania - skala logarytmiczna, zaznaczone punkty" style="border: solid black 1px;" height="100px" /></a><br />
</center></p>
<p><strong>Wnioski:</strong></p>
<ul>
<li>Normy wierszowe i kolumnowe (<strong>rys. 1</strong>, odpowiednio czerwona i zielona linia) są do siebie podobne, rosną mniej więcej liniowo.<br />
Norma spektralna (niebieska linia) również rośnie z grubsza liniowo wraz z rozmiarem macierzy, ale robi to dużo wolniej od pozostałych.</li>
<li>Normy macierzy odwrotnych do macierzy A są raczej niewielkie, trzymają się blisko zera, ale rozsiane są bardzo chaotycznie. Gdzieniegdzie jakaś norma wyskoczy bardzo wysoko.</li>
<li>Współczynniki uwarunkowania dla norm wierszowych i kolumnowych (<strong>rys. 2</strong>, kolory jak na poprzednim) są bardzo zbliżone do siebie, podobnie jak same normy. Uwarunkowanie dla normy spektralnej jest o rząd wielkości mniejsze (<strong>rys. 3</strong>, to samo w skali logarytmicznej na osi y).</li>
<li>Współczynniki uwarunkowania dla wszystkich norm razem rosną i maleją (<strong>rys. 4</strong>, tzn. wzrost współczynnika uwarunkowania dla norm wierszowej i kolumnowej wiąże się ze wzrostem tegoż współczynnika dla normy spektralnej).</li>
</ul>
<p>Pomimo powyższych przemyśleń dalej pozostaje dla mnie nierozwiązaną jedna kwestia: <strong>której normy używać do policzenia uwarunkowania macierzy w metodach numerycznych, kiedy chcę określić uwarunkowanie zadania?</strong> Może mi ktoś z Czytelników pomoże <img src='http://temporal.pr0.pl/devblog/wp-includes/images/smilies/icon_smile.gif' alt=':)' class='wp-smiley' /> .</p>
]]></content:encoded>
			<wfw:commentRss>http://temporal.pr0.pl/devblog/2008/12/12/uwarunkowanie-macierzy/feed/</wfw:commentRss>
		<slash:comments>3</slash:comments>
		</item>
		<item>
		<title>Zobaczyć podczerwień.</title>
		<link>http://temporal.pr0.pl/devblog/2008/12/08/zobaczyc-podczerwien/</link>
		<comments>http://temporal.pr0.pl/devblog/2008/12/08/zobaczyc-podczerwien/#comments</comments>
		<pubDate>Mon, 08 Dec 2008 16:48:02 +0000</pubDate>
		<dc:creator>Jacek Złydach</dc:creator>
				<category><![CDATA[Applied Science]]></category>
		<category><![CDATA[Pragmatyzm]]></category>
		<category><![CDATA[Sztuczki (Life Hacks)]]></category>
		<category><![CDATA[life hacks]]></category>
		<category><![CDATA[matryca CCD]]></category>
		<category><![CDATA[podczerwień]]></category>
		<category><![CDATA[porady]]></category>

		<guid isPermaLink="false">http://temporal.pr0.pl/devblog/2008/12/08/zobaczyc-podczerwien/</guid>
		<description><![CDATA[Jestem zaskoczony tym, jak mało osób (wliczając w to prowadzącego laboratoria z Elektroniki Cyfrowej oraz panią w lokalnym sklepie elektronicznym) wie, że matryce CCD potrafią rejestrować promieniowanie podczerwone. Tak drogi Czytelniku, Twój aparat cyfrowy, także ten w telefonie, potrafi zobaczyć podczerwień. Zjawisko to prezentują poniższe zdjęcia pilota od telewizora zrobione telefonem komórkowym.

Pierwsze zdjęcie przedstawia przód [...]]]></description>
			<content:encoded><![CDATA[<p>Jestem zaskoczony tym, jak mało osób (wliczając w to prowadzącego laboratoria z Elektroniki Cyfrowej oraz panią w lokalnym sklepie elektronicznym) wie, że matryce <a href="http://pl.wikipedia.org/wiki/Matryca_CCD">CCD</a> potrafią rejestrować promieniowanie podczerwone. <strong>Tak drogi Czytelniku, Twój aparat cyfrowy, także ten w telefonie, potrafi zobaczyć podczerwień.</strong> Zjawisko to prezentują poniższe zdjęcia pilota od telewizora zrobione telefonem komórkowym.</p>
<p><center><a href="http://temporal.pr0.pl/devblog/download/varia/tvpilot1.jpg" style="padding-right: 30px;"><img src="http://temporal.pr0.pl/devblog/download/varia/tvpilot1-small.jpg" alt="Pilot TV" /></a><a href="http://temporal.pr0.pl/devblog/download/varia/tvpilot2.jpg" style="padding-left: 30px;"><img src="http://temporal.pr0.pl/devblog/download/varia/tvpilot2-small.jpg" alt="Pilot TV z naciśniętym przyciskiem" /></a></center></p>
<p>Pierwsze zdjęcie przedstawia przód pilota. Drugie zdjęcie przedstawia tego samego pilota, przy naciśniętym przycisku. Widzimy, że dioda, której światło jest nie widoczne gołym okiem, została doskonale zarejestrowana przez aparat. Znajomość tej sztuczki przyda się każdemu do testowania sprawności pilotów od sprzętu RTV. W ten sposób można chociażby łatwo sprawdzić, które przyciski nie stykają (albo czy panowie z serwisu faktycznie naprawili nam pilot). </p>
<p>Zastosowania są oczywiście szersze &#8211; zjawisko to wykorzystuje się w kamerach <acronym title="Close-Circuit TV">CCTV</acronym> do ochrony obiektów &#8211; w nocy taka kamera może pracować w trybie czarno-białym i doświetlać teren podczerwienią. Podobnie spotykane coraz częściej wideofony zawierają zestaw diod <acronym title="Light Emitting Diode">LED</acronym>, które służą do oświetlania podczerwienią, dzięki czemu kamera dobrze rejestruje rozmówcę niezależnie od zewnętrznego oświetlenia (np. w nocy). Jeden z moich kolegów przeprowadził niegdyś eksperyment &#8211; za pomocą diody podczerwonej wysokiej mocy (3W chyba) mógł widzieć przez wyświetlacz aparatu cyfrowego obiekty w odległości ok. 2-3 metrów w kompletnej ciemności.</p>
]]></content:encoded>
			<wfw:commentRss>http://temporal.pr0.pl/devblog/2008/12/08/zobaczyc-podczerwien/feed/</wfw:commentRss>
		<slash:comments>7</slash:comments>
		</item>
		<item>
		<title>Tworzenie gier na AGH</title>
		<link>http://temporal.pr0.pl/devblog/2008/12/07/tworzenie-gier-na-agh/</link>
		<comments>http://temporal.pr0.pl/devblog/2008/12/07/tworzenie-gier-na-agh/#comments</comments>
		<pubDate>Sun, 07 Dec 2008 13:37:16 +0000</pubDate>
		<dc:creator>Jacek Złydach</dc:creator>
				<category><![CDATA[Informatyka]]></category>
		<category><![CDATA[Tworzenie gier]]></category>
		<category><![CDATA[AGH]]></category>

		<guid isPermaLink="false">http://temporal.pr0.pl/devblog/2008/12/07/tworzenie-gier-na-agh/</guid>
		<description><![CDATA[Jeszcze nie umarłem, czasem zdarzy mi się coś napisać   .
W ostatnim miesiącu na AGH odbyły się dwa seminaria (taka mądra nazwa na wykład) na temat tworzenia gier, zorganizowane przez koło naukowe Glider a prowadzone przez pracowników firmy Reality Pump. Na pierwszym spotkaniu omówiono różne techniki sztucznej inteligencji w grach oraz ich zastosowanie w [...]]]></description>
			<content:encoded><![CDATA[<p>Jeszcze nie umarłem, czasem zdarzy mi się coś napisać <img src='http://temporal.pr0.pl/devblog/wp-includes/images/smilies/icon_smile.gif' alt=':)' class='wp-smiley' />  .</p>
<p>W ostatnim miesiącu na <a href="http://agh.edu.pl/">AGH</a> odbyły się dwa seminaria <em>(taka mądra nazwa na wykład)</em> na temat tworzenia gier, zorganizowane przez <a href="http://www.glider.agh.edu.pl/">koło naukowe Glider</a> a prowadzone przez pracowników firmy <a href="http://pl.wikipedia.org/wiki/Reality_Pump_Studios">Reality Pump</a>. Na pierwszym spotkaniu omówiono różne techniki sztucznej inteligencji w grach oraz ich zastosowanie w aktualnie tworzonej przez Reality Pump grze <a href="http://www.2-worlds.com/">Two Worlds: The Temptation</a>. Drugie spotkanie było ogólnym wstępem w świat tworzenia gier typu retail (dużych produkcji, które trafiają na półki sklepowe). Można było też dowiedzieć się, w którym kierunku mogą rozwijać się początkujący twórcy gier oraz jak i dlaczego zacząć pracę z <a href="http://pl.wikipedia.org/wiki/XNA">XNA</a>. Dodatkowym elementem spotkania była prezentacja gry <em>Two Worlds: The Temptation</em>, połączona z sesją pytań.</p>
<p>Wykłady te są dla mnie bardzo miłą niespodzianką i z radością informuję, że nie jest to koniec &#8211; koło naukowe Glider planuje dalszą współpracę z panami z Reality Pump; na stronie koła niedługo pojawi się ankieta, za pomocą której wybrany zostanie temat kolejnego spotkania. Wszystkich zainteresowanych będę informował o terminach i miejscach, jak tylko się o nich dowiem <img src='http://temporal.pr0.pl/devblog/wp-includes/images/smilies/icon_smile.gif' alt=':)' class='wp-smiley' /> .</p>
<p>Oczywiście nie wszystko było różowe; pomimo zapewnień, że wykłady są dla wszystkich, choćby minimalne doświadczenie z grami i programowaniem grafiki jest potrzebne, by zrozumieć żargon, którym posługują się prowadzący. Jest to być może &#8216;zboczenie zawodowe&#8217;, którego wspomniani prelegenci już nie zauważają, ale w wykładzie często pojawiały się angielskie terminy i wyrażenia, takie jak &#8216;raytracing&#8217;, &#8216;gameplay&#8217;, &#8216;<acronym title="Level of Details">LOD</acronym>&#8216; czy &#8216;<acronym title="Non-Player Character">NPC</acronym>&#8216;, które skutecznie utrudniły odbiór osobom &#8216;nie z branży&#8217;.</p>
<p>Podsumowując &#8211; wszystkich obecnych i przyszłych game developerów zapraszamy na AGH <img src='http://temporal.pr0.pl/devblog/wp-includes/images/smilies/icon_smile.gif' alt=':)' class='wp-smiley' /> .</p>
]]></content:encoded>
			<wfw:commentRss>http://temporal.pr0.pl/devblog/2008/12/07/tworzenie-gier-na-agh/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Sprawna zmiana nazw plików</title>
		<link>http://temporal.pr0.pl/devblog/2008/09/30/sprawna-zmiana-nazw-plikow/</link>
		<comments>http://temporal.pr0.pl/devblog/2008/09/30/sprawna-zmiana-nazw-plikow/#comments</comments>
		<pubDate>Tue, 30 Sep 2008 13:57:55 +0000</pubDate>
		<dc:creator>Jacek Złydach</dc:creator>
				<category><![CDATA[Applied Science]]></category>
		<category><![CDATA[Informatyka]]></category>
		<category><![CDATA[Pragmatyzm]]></category>
		<category><![CDATA[Sztuczki (Life Hacks)]]></category>
		<category><![CDATA[life hacks]]></category>
		<category><![CDATA[porady]]></category>
		<category><![CDATA[Windows]]></category>

		<guid isPermaLink="false">http://temporal.pr0.pl/devblog/2008/09/30/sprawna-zmiana-nazw-plikow/</guid>
		<description><![CDATA[Czasem zdarza się, że musimy zmieniać nazwy grupie plików w jakimś katalogu. Niedawno przypadkiem odkryłem (nacisnąłem zły klawisz   ) sztuczkę, która ułatwia ten proces. Przetestowana na Windows Vista, nie wiem czy działa na starszych (i czy ktoś ją skopiował do *nix&#8217;ów).
Jak wiadomo   , skrótem do zmiany nazwy zaznaczonego pliku jest klawisz [...]]]></description>
			<content:encoded><![CDATA[<p>Czasem zdarza się, że musimy zmieniać nazwy grupie plików w jakimś katalogu. Niedawno przypadkiem odkryłem (nacisnąłem zły klawisz <img src='http://temporal.pr0.pl/devblog/wp-includes/images/smilies/icon_wink.gif' alt=';)' class='wp-smiley' />  ) sztuczkę, która ułatwia ten proces. Przetestowana na Windows Vista, nie wiem czy działa na starszych (i czy ktoś ją skopiował do *nix&#8217;ów).</p>
<p>Jak wiadomo <img src='http://temporal.pr0.pl/devblog/wp-includes/images/smilies/icon_wink.gif' alt=';)' class='wp-smiley' />  , skrótem do zmiany nazwy zaznaczonego pliku jest klawisz F2. Po jego naciśnięciu najczęściej wpisujemy nazwę, po czym wciskamy ENTER i wybieramy inny plik, lub od razu klikamy na tym pliku. Potem kolejne F2 lub kliknięcie, co zabiera nam jakąś sekundę. Zamiast tego, gdy skończymy wpisywać nazwę, wystarczy nacisnąć klawisz TAB, by przeskoczyć na kolejny plik, od razu w trybie zmiany nazwy. Czyli wklepujemy nazwę, TAB, i wklepujemy kolejną <img src='http://temporal.pr0.pl/devblog/wp-includes/images/smilies/icon_wink.gif' alt=';)' class='wp-smiley' /> . Hope that helps.</p>
]]></content:encoded>
			<wfw:commentRss>http://temporal.pr0.pl/devblog/2008/09/30/sprawna-zmiana-nazw-plikow/feed/</wfw:commentRss>
		<slash:comments>5</slash:comments>
		</item>
		<item>
		<title>DropBox &#8211; wygodne współdzielenie plików</title>
		<link>http://temporal.pr0.pl/devblog/2008/09/28/dropbox-wygodne-wspoldzielenie-plikow/</link>
		<comments>http://temporal.pr0.pl/devblog/2008/09/28/dropbox-wygodne-wspoldzielenie-plikow/#comments</comments>
		<pubDate>Sun, 28 Sep 2008 20:10:35 +0000</pubDate>
		<dc:creator>Jacek Złydach</dc:creator>
				<category><![CDATA[Informatyka]]></category>
		<category><![CDATA[Pragmatyzm]]></category>
		<category><![CDATA[Dropbox]]></category>
		<category><![CDATA[narzędzia]]></category>
		<category><![CDATA[Windows]]></category>

		<guid isPermaLink="false">http://temporal.pr0.pl/devblog/2008/09/28/dropbox-wygodne-wspoldzielenie-plikow/</guid>
		<description><![CDATA[Dzielenie się plikami to temat znany chyba każdemu developerowi. Dzielimy się naszymi grami, programami. Dzielimy się screenami, logami. Pracujemy wspólnie nad kodem. Stosujemy w tym celu wiele metod &#8211; strony typu Rapidshare, własne lub kupione serwery FTP, narzędzia kontroli wersji (CVS, SVN). Ludzie z Warsztatu stworzyli nawet program ScreenUp &#8211; wygodne narzędzie do wrzucania screenów. [...]]]></description>
			<content:encoded><![CDATA[<p>Dzielenie się plikami to temat znany chyba każdemu developerowi. Dzielimy się naszymi grami, programami. Dzielimy się screenami, logami. Pracujemy wspólnie nad kodem. Stosujemy w tym celu wiele metod &#8211; strony typu <a href="http://rapidshare.com/">Rapidshare</a>, własne lub kupione serwery FTP, narzędzia kontroli wersji (<a href="http://pl.wikipedia.org/wiki/CVS">CVS</a>, <a href="http://pl.wikipedia.org/wiki/SVN">SVN</a>). Ludzie z <a href="http://gamedev.pl">Warsztatu</a> stworzyli nawet program <a href="http://screenup.pl/">ScreenUp</a> &#8211; wygodne narzędzie do wrzucania screenów. Chciałem dziś napisać o kolejnym &#8216;wynalazku&#8217; w tej dziedzinie.</p>
<p>Niedawno odkryłem ciekawe narzędzie &#8211; <strong>DropBox</strong>. W założeniu jest to prosta metoda przechowywania i współdzielenia plików. Jak w praktyce to działa?<br />
Wchodzimy na stronę <a href="http://getdropbox.com/">http://getdropbox.com/</a> i ściągamy klienta. Dostępny jest on w wersjach dla Windows, Linux i Mac. Po instalacji w systemie Windows zakładamy konto, podając swój adres e-mail (używany jako login na stronę), hasło i inne opcjonalne dane. Przy instalacji można też wybrać lokalizację katalogu DropBox.</p>
<p>No dobrze, ale o co chodzi? Mamy w systemie teraz specjalny katalog, który jest automatycznie synchronizowany ze stroną DropBox. Wszystkie pliki wgrywane są automatycznie na serwer, <a href="https://www.getdropbox.com/tour?p=0#3">wszystkie zmiany przesyłane metodą inkrementalną (dogrywane są jedynie zmienione fragmenty)</a>. Do podkatalogu Public wrzucamy pliki, które chcemy udostępniać całemu światu. <a href="http://dl.getdropbox.com/u/216352/czysty_warsztat.jpg">Tak jak ten</a> <img src='http://temporal.pr0.pl/devblog/wp-includes/images/smilies/icon_smile.gif' alt=':)' class='wp-smiley' /> . Podkatalog Photos pełni rolę zbioru galerii fotograficznych (wrzucamy foldery), które również może oglądać każdy, komu damy odpowiednie linki. Wreszcie istnieje możliwość tworzenia i współdzielenia katalogów z innymi użytkownikami DropBox. Oznacza to, że każda zmiana w takim katalogu będzie synchronizowana u wszystkich osób, które mają do niego dostęp.</p>
<p>Wszystkie te rzeczy są zintegrowane z Eksploaratorem Windows (o pozostałych systemach wiem tylko tyle, że na pewno integruje się z GNOME), dzięki czemu obsługa całej mechaniki DropBox&#8217;a to po prostu przerzucanie plików między swoimi folderami, a folderem DropBox. Program dodaje do menu kontekstowego swoje podmenu z kilkoma użytecznymi funkcjami, jak np. <em>Copy Public Link</em>.</p>
<p>DropBox oferuje dwa rodzaje kont. Darmowe ma ograniczoną pojemność do 2GB, płatne &#8211; do 50GB ($9.99 / miesiąc lub $99 / rok). Cały projekt jest na razie w fazie beta (chociaż patrząc na Google, słowo &#8220;beta&#8221; chyba straciło już swoje znaczenie&#8230;), więc można spodziewać się jeszcze wielu zmian (omawianych na <a href="http://forums.getdropbox.com/">forum DropBox&#8217;a</a>).</p>
]]></content:encoded>
			<wfw:commentRss>http://temporal.pr0.pl/devblog/2008/09/28/dropbox-wygodne-wspoldzielenie-plikow/feed/</wfw:commentRss>
		<slash:comments>1</slash:comments>
		</item>
		<item>
		<title>Ponieważ każdy Technik ma swoje Słoneczko&#8230;</title>
		<link>http://temporal.pr0.pl/devblog/2008/09/26/poniewaz-kazdy-technik-ma-swoje-sloneczko/</link>
		<comments>http://temporal.pr0.pl/devblog/2008/09/26/poniewaz-kazdy-technik-ma-swoje-sloneczko/#comments</comments>
		<pubDate>Thu, 25 Sep 2008 22:38:13 +0000</pubDate>
		<dc:creator>Jacek Złydach</dc:creator>
				<category><![CDATA[Z życia]]></category>
		<category><![CDATA[Słoneczko]]></category>

		<guid isPermaLink="false">http://temporal.pr0.pl/devblog/2008/09/26/poniewaz-kazdy-technik-ma-swoje-sloneczko/</guid>
		<description><![CDATA[
&#8230; Słoneczko, które oświetla go swym blaskiem,
&#8230; w którym widać jego prawdziwą naturę&#8230;
&#8230; cały potencjał i wszystkie wady.
Każdy Technik ma swoje Słoneczko.
Tylko jedno.
Z legend Techników, rozdział I.
Dziękuję tym, którzy pomagali.
Tym, dzięki którym to jedno marzenie choć na chwilę stało się rzeczywistością.
I przede wszystkim, dziękuję Słoneczku.
Nie widzę już nic, nic a nic, biało mi.
Idź dalej niezłomnie, [...]]]></description>
			<content:encoded><![CDATA[<p><img src="http://temporal.pr0.pl/devblog/download/sloneczko_nt.png" alt="Kochane Słoneczko" /><br />
<em>&#8230; Słoneczko, które oświetla go swym blaskiem,<br />
&#8230; w którym widać jego prawdziwą naturę&#8230;<br />
&#8230; cały potencjał i wszystkie wady.<br />
Każdy Technik ma swoje Słoneczko.<br />
Tylko jedno.</em><br />
<strong>Z legend Techników, rozdział I.</strong></p>
<p>Dziękuję tym, którzy pomagali.<br />
Tym, dzięki którym to jedno marzenie choć na chwilę stało się rzeczywistością.</p>
<p>I przede wszystkim, dziękuję Słoneczku.<br />
<em>Nie widzę już nic, nic a nic, biało mi.<br />
Idź dalej niezłomnie, a mnie zostaw sny.<br />
Nic nie jest stracone, skończone też nie,<br />
Gdy droga przed Tobą, a sam jesteś w tle.</em><br />
</em></p>
]]></content:encoded>
			<wfw:commentRss>http://temporal.pr0.pl/devblog/2008/09/26/poniewaz-kazdy-technik-ma-swoje-sloneczko/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Bonus #2 &#8211; We Work for GLaDOS Now</title>
		<link>http://temporal.pr0.pl/devblog/2008/09/05/bonus-2-we-work-for-glados-now/</link>
		<comments>http://temporal.pr0.pl/devblog/2008/09/05/bonus-2-we-work-for-glados-now/#comments</comments>
		<pubDate>Fri, 05 Sep 2008 08:29:27 +0000</pubDate>
		<dc:creator>Jacek Złydach</dc:creator>
				<category><![CDATA[Humor]]></category>
		<category><![CDATA[Varia]]></category>
		<category><![CDATA[Gry]]></category>
		<category><![CDATA[Portal]]></category>

		<guid isPermaLink="false">http://temporal.pr0.pl/devblog/2008/09/05/bonus-2-we-work-for-glados-now/</guid>
		<description><![CDATA[Coś o jednej z najlepszych grup NPC w historii gier komputerowych.
For all those, who&#8217;re &#8216;thinking with portals&#8217;  .
]]></description>
			<content:encoded><![CDATA[<p>Coś o jednej z najlepszych grup <acronym title="Non-Player Character">NPC</acronym> w historii gier komputerowych.<br />
For all those, who&#8217;re &#8216;thinking with portals&#8217; <img src='http://temporal.pr0.pl/devblog/wp-includes/images/smilies/icon_wink.gif' alt=';)' class='wp-smiley' /> .</p>
<p><object width="480" height="387"><param name="movie" value="http://www.wegame.com/static/flash/player2.swf?tag=We_Work_for_GLaDOS_Now"></param><param name="wmode" value="transparent"></param><embed src="http://www.wegame.com/static/flash/player2.swf?tag=We_Work_for_GLaDOS_Now" type="application/x-shockwave-flash" wmode="transparent" width="480" height="387""></embed></object></p>
]]></content:encoded>
			<wfw:commentRss>http://temporal.pr0.pl/devblog/2008/09/05/bonus-2-we-work-for-glados-now/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Large Hadron Rap</title>
		<link>http://temporal.pr0.pl/devblog/2008/09/02/large-hadron-rap/</link>
		<comments>http://temporal.pr0.pl/devblog/2008/09/02/large-hadron-rap/#comments</comments>
		<pubDate>Tue, 02 Sep 2008 20:05:09 +0000</pubDate>
		<dc:creator>Jacek Złydach</dc:creator>
				<category><![CDATA[Humor]]></category>
		<category><![CDATA[Pragmatyzm]]></category>
		<category><![CDATA[Varia]]></category>
		<category><![CDATA[Fizyka]]></category>

		<guid isPermaLink="false">http://temporal.pr0.pl/devblog/2008/09/02/large-hadron-rap/</guid>
		<description><![CDATA[Bonus na dobranoc, uśmiech w stronę fizyków  .

Na uwagę zasługuje fragment w opisie tego filmiku na Youtube.
&#8220;The sound should be slightly better on this version &#8211; we&#8217;ve tried to get round YouTube&#8217;s new extreme audio dynamic range compression by layering a 20kHz sine wave over the top of the soundtrack.&#8221;
To jest podejście prawdziwego Technika! [...]]]></description>
			<content:encoded><![CDATA[<p>Bonus na dobranoc, uśmiech w stronę fizyków <img src='http://temporal.pr0.pl/devblog/wp-includes/images/smilies/icon_smile.gif' alt=':)' class='wp-smiley' /> .<br />
<object width="425" height="344"><param name="movie" value="http://www.youtube.com/v/T3iryBLZCOQ&#038;hl=en&#038;fs=1"></param><param name="allowFullScreen" value="true"></param><embed src="http://www.youtube.com/v/T3iryBLZCOQ&#038;hl=en&#038;fs=1" type="application/x-shockwave-flash" allowfullscreen="true" width="425" height="344"></embed></object></p>
<p>Na uwagę zasługuje fragment w opisie <a href="http://www.youtube.com/watch?v=T3iryBLZCOQ">tego filmiku na Youtube</a>.<br />
<em>&#8220;The sound should be slightly better on this version &#8211; we&#8217;ve tried to get round YouTube&#8217;s new extreme audio dynamic range compression by layering a 20kHz sine wave over the top of the soundtrack.&#8221;</em><br />
To jest podejście prawdziwego Technika! Chak de planet~! <img src='http://temporal.pr0.pl/devblog/wp-includes/images/smilies/icon_smile.gif' alt=':)' class='wp-smiley' /> .</p>
]]></content:encoded>
			<wfw:commentRss>http://temporal.pr0.pl/devblog/2008/09/02/large-hadron-rap/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Na krawędzi lustra</title>
		<link>http://temporal.pr0.pl/devblog/2008/09/02/na-krawedzi-lustra/</link>
		<comments>http://temporal.pr0.pl/devblog/2008/09/02/na-krawedzi-lustra/#comments</comments>
		<pubDate>Tue, 02 Sep 2008 13:55:55 +0000</pubDate>
		<dc:creator>Jacek Złydach</dc:creator>
				<category><![CDATA[Varia]]></category>
		<category><![CDATA[Gry]]></category>
		<category><![CDATA[Mirror's Edge]]></category>
		<category><![CDATA[tapety]]></category>

		<guid isPermaLink="false">http://temporal.pr0.pl/devblog/2008/09/02/na-krawedzi-lustra/</guid>
		<description><![CDATA[Ostatnimi czasy moją uwagę przykuła gra Mirror&#8217;s Edge. Myślę, że nie ma sensu się tu rozpisywać &#8211; polecam przeczytanie opisu na Wiki, i przede wszystkim ściągnięcie i oglądnięcie filmików (1, 2, 3; uwaga &#8211; Quicktime). Polecam zwłaszcza pierwszy filmik. Ja wiem, że to dość duży download, ale nie ma sensu oszczędzać &#8211; w klimat można [...]]]></description>
			<content:encoded><![CDATA[<p>Ostatnimi czasy moją uwagę przykuła gra <strong>Mirror&#8217;s Edge</strong>. Myślę, że nie ma sensu się tu rozpisywać &#8211; polecam przeczytanie opisu na <a href="http://en.wikipedia.org/wiki/Mirror's_Edge">Wiki</a>, i przede wszystkim ściągnięcie i oglądnięcie filmików (<a href="http://www1.on-mirrors-edge.com/on-mirrors-edge_dot_com_debut_trailer_720p.zip">1</a>, <a href="http://www1.on-mirrors-edge.com/on-mirrors-edge_dot_com_e308_gameplay_trailer_720p.zip">2</a>, <a href="http://www1.on-mirrors-edge.com/on-mirrors-edge_dot_com_story_trailer_720p.zip">3</a>; uwaga &#8211; Quicktime). Polecam zwłaszcza pierwszy filmik. Ja wiem, że to dość duży download, ale nie ma sensu oszczędzać &#8211; w klimat można się czuć jedynie wtedy, gdy video jest odpowiedniej jakości. Powiem krótko &#8211; zarówno pomysł jak i wykonanie mnie powaliło i niecierpliwie czekam na wydanie <img src='http://temporal.pr0.pl/devblog/wp-includes/images/smilies/icon_wink.gif' alt=';)' class='wp-smiley' /> .</p>
<p>Tymczasem będąc zachwycony jednym z filmików promocyjnych postanowiłem zmajstrować tapetkę z Mirror&#8217;s Edge, której <a href="http://www.google.com/search?q=mirrors+edge+wallpaper">nie mogłem znaleźć w sieci</a>. Proponuję trzy wersje &#8211; <a href="http://temporal.pr0.pl/devblog/download/galleries/mirrorsedge/me3.jpg">bez napisów</a>, <a href="http://temporal.pr0.pl/devblog/download/galleries/mirrorsedge/me2.jpg">z logiem gry</a> lub <a href="http://temporal.pr0.pl/devblog/download/galleries/mirrorsedge/me1.jpg">z logiem gry i copyrightem EA </a> <img src='http://temporal.pr0.pl/devblog/wp-includes/images/smilies/icon_smile.gif' alt=':)' class='wp-smiley' /> . Obrazki są w oryginale 1280&#215;720, ale dodałem dodatkowe 30 pikseli do wysokości w postaci czarnego paska, dzięki czemu tapeta ładnie wygląda w rozdzielczości 1280&#215;800 (ustawiamy opcję wycentruj, a nie rozciągnij!).</p>
<p>Pozdrawiam <img src='http://temporal.pr0.pl/devblog/wp-includes/images/smilies/icon_smile.gif' alt=':)' class='wp-smiley' /> .</p>
]]></content:encoded>
			<wfw:commentRss>http://temporal.pr0.pl/devblog/2008/09/02/na-krawedzi-lustra/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Still alive</title>
		<link>http://temporal.pr0.pl/devblog/2008/07/22/still-alive/</link>
		<comments>http://temporal.pr0.pl/devblog/2008/07/22/still-alive/#comments</comments>
		<pubDate>Tue, 22 Jul 2008 13:23:25 +0000</pubDate>
		<dc:creator>Jacek Złydach</dc:creator>
				<category><![CDATA[Tworzenie gier]]></category>
		<category><![CDATA[Varia]]></category>
		<category><![CDATA[Z życia]]></category>
		<category><![CDATA[wordpress]]></category>

		<guid isPermaLink="false">http://temporal.pr0.pl/devblog/2008/07/22/still-alive/</guid>
		<description><![CDATA[Udało mi się dostać do phpMyAdmin na pr0.pl i wreszcie naprawiłem devBlog&#8217;a  . W wyniku jeszcze nie wyjaśnionego zjawiska wyłączyły się ramki na kod źródłowy i znikły wszystkie strony (zostały jedynie posty).
&#8220;I&#8217;m doing science&#8221; &#8211; tj. wciąż jestem studentem. Nie wiem jak długo, ale jeszcze  .
Nie obiecuję na razie nic konkretnego na devBlog&#8217;u. [...]]]></description>
			<content:encoded><![CDATA[<p>Udało mi się dostać do phpMyAdmin na pr0.pl i wreszcie naprawiłem devBlog&#8217;a <img src='http://temporal.pr0.pl/devblog/wp-includes/images/smilies/icon_smile.gif' alt=':)' class='wp-smiley' /> . W wyniku jeszcze nie wyjaśnionego zjawiska wyłączyły się ramki na kod źródłowy i znikły wszystkie strony (zostały jedynie posty).</p>
<p>&#8220;I&#8217;m doing science&#8221; &#8211; tj. wciąż jestem studentem. Nie wiem jak długo, ale jeszcze <img src='http://temporal.pr0.pl/devblog/wp-includes/images/smilies/icon_smile.gif' alt=':)' class='wp-smiley' /> .</p>
<p>Nie obiecuję na razie nic konkretnego na devBlog&#8217;u. Bo też i niewiele w dziedzinach technicznych ostatnio czyniłem.<br />
Ponieważ na <a href="http://gamedev.pl">Warsztacie</a> modny jest ostatnio temat <acronym title="Virtual File System">VFS</acronym>, to wrzucam <a href="http://temporal.pr0.pl/devblog/sar4/sar4-archive-format">linka do formatu PAK</a> używanego w grach z serii Search and Rescue 4. Taki mały reverse engineering, którym zajmowałem się kiedyś z <a href="http://wawszczak.pr0.pl/">kolegą</a> (chciało się poprawić SAR&#8217;a <img src='http://temporal.pr0.pl/devblog/wp-includes/images/smilies/icon_wink.gif' alt=';)' class='wp-smiley' />  ).</p>
]]></content:encoded>
			<wfw:commentRss>http://temporal.pr0.pl/devblog/2008/07/22/still-alive/feed/</wfw:commentRss>
		<slash:comments>2</slash:comments>
		</item>
		<item>
		<title>Arkanoid może być fajny :)</title>
		<link>http://temporal.pr0.pl/devblog/2008/01/13/arkanoid-moze-byc-fajny/</link>
		<comments>http://temporal.pr0.pl/devblog/2008/01/13/arkanoid-moze-byc-fajny/#comments</comments>
		<pubDate>Sat, 12 Jan 2008 23:23:19 +0000</pubDate>
		<dc:creator>Jacek Złydach</dc:creator>
				<category><![CDATA[Tworzenie gier]]></category>

		<guid isPermaLink="false">http://temporal.pr0.pl/devblog/2008/01/13/arkanoid-moze-byc-fajny/</guid>
		<description><![CDATA[Chciałem się podzielić stronką, na którą trafiłem: http://www.alphabounce.com/
Polecam poświęcić kilka minut i pooglądać demko. Przyznam, że zarówno efekty jak i niektóre pomysły zrobiły na mnie wrażenie (np. to, że jakiś bloczek jest wieżyczką i strzela do Ciebie!)
]]></description>
			<content:encoded><![CDATA[<p>Chciałem się podzielić stronką, na którą trafiłem: <a href="http://www.alphabounce.com/">http://www.alphabounce.com/</a><br />
Polecam poświęcić kilka minut i pooglądać demko. Przyznam, że zarówno efekty jak i niektóre pomysły zrobiły na mnie wrażenie (np. to, że jakiś bloczek jest wieżyczką i strzela do Ciebie!)</p>
]]></content:encoded>
			<wfw:commentRss>http://temporal.pr0.pl/devblog/2008/01/13/arkanoid-moze-byc-fajny/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Niedoszły Arkanoid w Delphi na zaliczenie</title>
		<link>http://temporal.pr0.pl/devblog/2008/01/12/niedoszly-arkanoid-w-delphi-na-zaliczenie/</link>
		<comments>http://temporal.pr0.pl/devblog/2008/01/12/niedoszly-arkanoid-w-delphi-na-zaliczenie/#comments</comments>
		<pubDate>Fri, 11 Jan 2008 22:47:32 +0000</pubDate>
		<dc:creator>Jacek Złydach</dc:creator>
				<category><![CDATA[Projekty studenckie]]></category>
		<category><![CDATA[Tworzenie gier]]></category>
		<category><![CDATA[Varia]]></category>
		<category><![CDATA[AGH]]></category>
		<category><![CDATA[Delphi]]></category>

		<guid isPermaLink="false">http://temporal.pr0.pl/devblog/2008/01/12/niedoszly-arkanoid-w-delphi-na-zaliczenie/</guid>
		<description><![CDATA[W ramach magicznego przedmiotu zwanego &#8220;Podstawy Informatyki&#8221; piszę projekty zaliczeniowe. Według planu przedświątecznego miałem napisać Arkanoida; jednak przez ostatnie wolne praktycznie nic nie zrobiłem w tym temacie (z różnych powodów), to postanowiłem wykonać coś mniejszego. Arkanoid ten, o nazwie kodowej YAAAC &#8211; Yet Another Academic Arkanoid Clone, doczekał się kilkunastostronicowej dokumentacji i w połowie zrobionego [...]]]></description>
			<content:encoded><![CDATA[<p>W ramach magicznego przedmiotu zwanego &#8220;Podstawy Informatyki&#8221; piszę projekty zaliczeniowe. Według planu przedświątecznego miałem napisać Arkanoida; jednak przez ostatnie wolne praktycznie nic nie zrobiłem w tym temacie (z różnych powodów), to postanowiłem wykonać coś mniejszego. Arkanoid ten, o nazwie kodowej <strong>YAAAC</strong> &#8211; <strong>Yet Another Academic Arkanoid Clone</strong>, doczekał się kilkunastostronicowej dokumentacji i w połowie zrobionego frameworka &#8211; nazwanego <strong>uAnything</strong> (czyt. <em>Micro-Anything</em>) &#8211; będącego uproszczoną implementacją koncepcji mojego frameworka <a href="http://temporal.pr0.pl/devblog/projekty/anything/">Anything</a>. Postanowiłem upublicznić tą całą twórczość, w celach edukacyjnych &#8211; może komuś się przyda.<br />
<a href="http://temporal.pr0.pl/devblog/download/projects/YAAAC/yaaac.zip">Link do archiwum</a>. W pakiecie kod, exe, <strong>dokument projektowy</strong> ( <img src='http://temporal.pr0.pl/devblog/wp-includes/images/smilies/icon_wink.gif' alt=';)' class='wp-smiley' />  ) i mały schemat pseudo-UML (moje pierwsze zabawy z Visio <img src='http://temporal.pr0.pl/devblog/wp-includes/images/smilies/icon_wink.gif' alt=';)' class='wp-smiley' />  ).</p>
<p>PS. Projekt ten został raz <a href="http://www.gamedev.pl/humor.php?x=view&#038;id=558">dyskretnie wspomniany na Warsztacie</a> <img src='http://temporal.pr0.pl/devblog/wp-includes/images/smilies/icon_wink.gif' alt=';)' class='wp-smiley' /> .</p>
]]></content:encoded>
			<wfw:commentRss>http://temporal.pr0.pl/devblog/2008/01/12/niedoszly-arkanoid-w-delphi-na-zaliczenie/feed/</wfw:commentRss>
		<slash:comments>1</slash:comments>
		</item>
		<item>
		<title>Wciąż &#8216;w branży&#8217; &#8211; GPG 6</title>
		<link>http://temporal.pr0.pl/devblog/2008/01/08/wciaz-w-branzy-gpg-6/</link>
		<comments>http://temporal.pr0.pl/devblog/2008/01/08/wciaz-w-branzy-gpg-6/#comments</comments>
		<pubDate>Tue, 08 Jan 2008 00:09:58 +0000</pubDate>
		<dc:creator>Jacek Złydach</dc:creator>
				<category><![CDATA[Rozwój osobisty]]></category>
		<category><![CDATA[Tworzenie gier]]></category>
		<category><![CDATA[książki]]></category>

		<guid isPermaLink="false">http://temporal.pr0.pl/devblog/2008/01/08/wciaz-w-branzy-gpg-6/</guid>
		<description><![CDATA[
Ostatnimi czasy niektóre osoby z rozmów ze mną mogły odnieść wrażenie, że trochę wypadam z gamedev&#8216;u, skłaniam się ku innym dziedzinom informatyki. Zobaczymy jak to będzie w przyszłości, ale na razie decyduję się wciąż być w temacie. W tym celu zakupiłem długo oczekiwany szósty tom znanej serii Perełki Programowania Gier.
&#8230;no dobra, zakupiłem pod wpływem przypływu [...]]]></description>
			<content:encoded><![CDATA[<p style="text-align: left; float: left; margin-right: 15px; "><img src="http://helion.pl/okladki/181x236/ppgvp6.jpg" alt="Perełki Programowania Gier - Tom 6 - okładka" /></p>
<p>Ostatnimi czasy niektóre osoby z rozmów ze mną mogły odnieść wrażenie, że trochę wypadam z <a href="http://en.wikipedia.org/wiki/Game_development">gamedev</a>&#8216;u, skłaniam się ku innym dziedzinom informatyki. Zobaczymy jak to będzie w przyszłości, ale na razie decyduję się wciąż być w temacie. W tym celu zakupiłem długo oczekiwany <a href="http://helion.pl/ksiazki/ppgvp6.htm">szósty tom</a> znanej serii <a href="http://wiki.gamedev.pl/Perełki_programowania_gier">Perełki Programowania Gier</a>.<br />
&#8230;no dobra, zakupiłem pod wpływem przypływu euforii <img src='http://temporal.pr0.pl/devblog/wp-includes/images/smilies/icon_wink.gif' alt=';)' class='wp-smiley' /> . Po dwóch wstępnych przekartkowaniach stwierdzam, że ten tom jest dla mnie osobiście szczególnie interesujący; oprócz mojego ulubionej pierwszej części, dotyczącej programowania ogólnego, pojawił się bardzo ciekawy dział czwarty &#8211; Skrypty i systemy sterowane danymi. Dodatkowy komentarz do książki wystawię dopiero jak zapoznam się z treścią przynajmniej tych dwóch działów tematycznych. Teraz nadmienię jedynie, że ładnie pachnie <img src='http://temporal.pr0.pl/devblog/wp-includes/images/smilies/icon_wink.gif' alt=';)' class='wp-smiley' /> .</p>
<p>PS. Dodam tylko, że nie kupiłbym tej książki gdyby nie spostrzegawczość <a href="http://www.asmoduesz.net/">Asmodeusza</a>, który prawie instynktownie wyczuł jej obecność na wystawie gdy przechodziliśmy obok księgarni <img src='http://temporal.pr0.pl/devblog/wp-includes/images/smilies/icon_smile.gif' alt=':)' class='wp-smiley' /> .</p>
]]></content:encoded>
			<wfw:commentRss>http://temporal.pr0.pl/devblog/2008/01/08/wciaz-w-branzy-gpg-6/feed/</wfw:commentRss>
		<slash:comments>2</slash:comments>
		</item>
		<item>
		<title>Chronienie funkcji</title>
		<link>http://temporal.pr0.pl/devblog/2008/01/03/chronienie-funkcji/</link>
		<comments>http://temporal.pr0.pl/devblog/2008/01/03/chronienie-funkcji/#comments</comments>
		<pubDate>Thu, 03 Jan 2008 12:17:45 +0000</pubDate>
		<dc:creator>Jacek Złydach</dc:creator>
				<category><![CDATA[Informatyka]]></category>
		<category><![CDATA[Pragmatyzm]]></category>
		<category><![CDATA[Tworzenie gier]]></category>
		<category><![CDATA[C++]]></category>
		<category><![CDATA[porady]]></category>

		<guid isPermaLink="false">http://temporal.pr0.pl/devblog/2008/01/03/chronienie-funkcji/</guid>
		<description><![CDATA[Chronienie funkcji to ciekawe zastosowanie metody obsługi sytuacji wyjątkowych, dzięki któremu możemy w chwili wystąpienia błędu uzyskać dokładne informacje o miejscu awarii. Samą technikę podpatrzyłem dawno temu w publicznym kodzie gry Unreal Tournament. Przykładowy komunikat błędu prezentuje poniższy screen:

Jak widać, komunikat zawiera historię wywołań funkcji, które doprowadziły do miejsca wystąpienia błędu (tak zwany call-stack).
Napiszmy dwa [...]]]></description>
			<content:encoded><![CDATA[<p>Chronienie funkcji to ciekawe zastosowanie metody obsługi sytuacji wyjątkowych, dzięki któremu możemy w chwili wystąpienia błędu uzyskać dokładne informacje o miejscu awarii. Samą technikę podpatrzyłem dawno temu w publicznym kodzie gry <a href="http://en.wikipedia.org/wiki/Unreal_Tournament">Unreal Tournament</a>. Przykładowy komunikat błędu prezentuje poniższy screen:</p>
<p style="text-align: center"><a href="http://temporal.pr0.pl/devblog/download/posts/guarding/guarding_mbox.png"><img src="http://temporal.pr0.pl/devblog/download/posts/guarding/guarding_mbox-200px.png" alt="Komunikat o błędzie pokazujący stos wywołań." /></a></p>
<p>Jak widać, komunikat zawiera historię wywołań funkcji, które doprowadziły do miejsca wystąpienia błędu (tak zwany call-stack).</p>
<p>Napiszmy dwa pomocnicze makra oraz przykład użycia</p>
<div class="codecolorer-container cpp default" style="overflow:auto;white-space:nowrap;border:1px solid #9F9F9F;width:435px;"><div class="cpp codecolorer" style="padding:5px;font:normal 12px/1.4em Monaco, Lucida Console, monospace;white-space:nowrap"><span style="color: #339900;">#define GUARD(functionName) {static const char __GUARDED_FUNCTION_NAME__[] = #functionName; try{</span><br />
<span style="color: #339900;">#define UNGUARD } catch(...) { Framework-&gt;GetErrorManager()-&gt;AddCallHistory(__GUARDED_FUNCTION_NAME__); throw; } }</span><br />
<span style="color: #666666;">//przyklad uzycia</span><br />
<span style="color: #0000ff;">void</span> funkcja_chroniona<span style="color: #008000;">&#40;</span><span style="color: #008000;">&#41;</span><br />
<span style="color: #008000;">&#123;</span><br />
&nbsp; &nbsp; GUARD<span style="color: #008000;">&#40;</span>funkcja_chroniona<span style="color: #008000;">&#41;</span><span style="color: #008080;">;</span><br />
&nbsp; &nbsp; <span style="color: #666666;">//jakies operacje</span><br />
&nbsp; &nbsp; UNGUARD<span style="color: #008000;">&#40;</span>funkcja_chroniona<span style="color: #008000;">&#41;</span><span style="color: #008080;">;</span><br />
<span style="color: #008000;">&#125;</span></div></div>
<p>Makra te ujmują kod zawarty między nimi w blok try-catch. Kiedy chcemy zasygnalizować wystąpienie bardzo poważnego błędu, który powinien spowodować przerwanie działania programu, wówczas rzucamy wyjątek. W chwili złapania wyjątku w makrze UNGUARD, nazwa podana do makra GUARD zostaje zapisana w systemie obsługi błędów ( to proszę napisać sobie samemu <img src='http://temporal.pr0.pl/devblog/wp-includes/images/smilies/icon_wink.gif' alt=';)' class='wp-smiley' />  ), po czym wyjątek zostaje rzucony dalej. Jeśli zabezpieczymy w ten sposób wiele funkcji, to rzucony wyjątek przeleci przez nie wszystkie aż do miejsca, w którym zostanie obsłużony i zatrzymany. Takim miejscem może być np. pętla główna gry. Przykład:</p>
<div class="codecolorer-container cpp default" style="overflow:auto;white-space:nowrap;border:1px solid #9F9F9F;width:435px;"><div class="cpp codecolorer" style="padding:5px;font:normal 12px/1.4em Monaco, Lucida Console, monospace;white-space:nowrap"><span style="color: #666666;">//punkt obslugi, fragment jakiejs funkcji</span><br />
<span style="color: #666666;">//...</span><br />
<span style="color: #0000ff;">try</span><br />
<span style="color: #008000;">&#123;</span><br />
&nbsp; &nbsp; EnterMainLoop<span style="color: #008000;">&#40;</span><span style="color: #008000;">&#41;</span><span style="color: #008080;">;</span><br />
<span style="color: #008000;">&#125;</span><br />
<span style="color: #0000ff;">catch</span><span style="color: #008000;">&#40;</span>std<span style="color: #008080;">::</span><span style="color: #007788;">exception</span><span style="color: #000040;">&amp;</span> exc<span style="color: #008000;">&#41;</span><br />
<span style="color: #008000;">&#123;</span><br />
&nbsp; &nbsp; errorSystem<span style="color: #000040;">-</span><span style="color: #000080;">&gt;</span>DisplayException<span style="color: #008000;">&#40;</span><span style="color: #FF0000;">&quot;STL exception&quot;</span>, exc.<span style="color: #007788;">what</span><span style="color: #008000;">&#40;</span><span style="color: #008000;">&#41;</span><span style="color: #008000;">&#41;</span><span style="color: #008080;">;</span><br />
<span style="color: #008000;">&#125;</span><br />
<span style="color: #0000ff;">catch</span><span style="color: #008000;">&#40;</span>CMyException<span style="color: #000040;">&amp;</span> exc<span style="color: #008000;">&#41;</span><br />
<span style="color: #008000;">&#123;</span><br />
&nbsp; &nbsp; errorSystem<span style="color: #000040;">-</span><span style="color: #000080;">&gt;</span>DisplayException<span style="color: #008000;">&#40;</span>exc.<span style="color: #007788;">type</span><span style="color: #008000;">&#40;</span><span style="color: #008000;">&#41;</span>, exc.<span style="color: #007788;">what</span><span style="color: #008000;">&#40;</span><span style="color: #008000;">&#41;</span><span style="color: #008000;">&#41;</span><span style="color: #008080;">;</span><br />
<span style="color: #008000;">&#125;</span><br />
<span style="color: #0000ff;">catch</span><span style="color: #008000;">&#40;</span>...<span style="color: #008000;">&#41;</span><br />
<span style="color: #008000;">&#123;</span><br />
&nbsp; &nbsp; errorSystem<span style="color: #000040;">-</span><span style="color: #000080;">&gt;</span>DisplayException<span style="color: #008000;">&#40;</span><span style="color: #FF0000;">&quot;Unknown exception&quot;</span>, <span style="color: #FF0000;">&quot;Unknown error&quot;</span><span style="color: #008000;">&#41;</span><span style="color: #008080;">;</span><br />
<span style="color: #008000;">&#125;</span><br />
<span style="color: #666666;">//...</span></div></div>
<p>Z metodą tą wiążą się też pewne niedogodności:</p>
<ul>
<li>Każdą chronioną funkcję / blok kodu trzeba zawierać w makrach GUARD/UNGUARD</li>
<li>Blok try/catch powoduje zwiększenie czasu wykonania funkcji</li>
<li>Utrudnione lub wręcz uniemożliwione jest używanie w kodzie wyjątków w celach innych niż obsługa błędów krytycznych, powodujących awaryjne zakończenie pracy programu</li>
</ul>
<p>Równoważone są one jednak przez korzyść wynikającą ze znajomości dokładnej historii wywołań funkcji prowadzącej do miejsca wystąpienia błędu. Oczywiście makr tych nie stosujemy we wszystkich możliwych funkcjach; na przykład nie powinno się ich używać w prostych funkcjach wymagających bardzo dużej wydajności (np. iloczyn wektorowy).</p>
<p>Możliwe usprawnienia podanego przykładu:</p>
<ul>
<li>Zastosowanie dyrektyw #ifdef / #else / #endif do warunkowej kompilacji makr GUARD/UNGUARD, dzięki czemu można będzie je łatwo wyłączyć</li>
<li>Stworzenie dodatkowej pary makr GUARD_SLOW i UNGUARD_SLOW, które będą automatycznie wyłączane w wersji wydaniowej (patrz punkt poprzedni), a które stosowane będą w funkcjach wymagających możliwie wysokiej wydajności</li>
<li>Połączenie chronienia funkcji z własnymi makrami Assert/Verify, dzięki czemu przerywając pracę programu uzyskamy dokładne informacje o miejscu naruszenia asercji i drodze do tego miejsca. Własne makra Assert/Verify opiszę w przyszłości.</li>
<li>Połączenie makra GUARD z loggerem, dzięki czemu nazwa funkcji będzie automatycznie dopisywana do komunikatu. Jest to duże udogodnienie, jeśli ktoś zapisuje nazwy funkcji do loga.</li>
<li>Przerobienie makr, by system <a href="http://temporal.pr0.pl/devblog/2007/10/04/unicode-w-programowaniu-gier-podstawy/">działał w oparciu o Unicode</a> (w przypadku kodu, który w całości jest oparty o to kodowanie znaków)</li>
</ul>
<p>Osobiście z powodzeniem stosuje koncepcję chronienia funkcji w kodzie od dość długiego czasu. Zintegrowała się ona na stałe z silnikami i frameworkami, których pisania się podejmowałem. Z wymienionych wyżej usprawnień nie udało mi się jedynie połączyć chronienia funkcji z loggerem.</p>
]]></content:encoded>
			<wfw:commentRss>http://temporal.pr0.pl/devblog/2008/01/03/chronienie-funkcji/feed/</wfw:commentRss>
		<slash:comments>5</slash:comments>
		</item>
		<item>
		<title>FlashBlock &#8211; precz z niepotrzebnym flash&#8217;em!</title>
		<link>http://temporal.pr0.pl/devblog/2007/12/20/flashblock-precz-z-niepotrzebnym-flashem/</link>
		<comments>http://temporal.pr0.pl/devblog/2007/12/20/flashblock-precz-z-niepotrzebnym-flashem/#comments</comments>
		<pubDate>Thu, 20 Dec 2007 11:41:21 +0000</pubDate>
		<dc:creator>Jacek Złydach</dc:creator>
				<category><![CDATA[Informatyka]]></category>
		<category><![CDATA[Pragmatyzm]]></category>
		<category><![CDATA[Varia]]></category>
		<category><![CDATA[FlashBlock]]></category>
		<category><![CDATA[narzędzia]]></category>
		<category><![CDATA[porady]]></category>

		<guid isPermaLink="false">http://temporal.pr0.pl/devblog/2007/12/20/flashblock-precz-z-niepotrzebnym-flashem/</guid>
		<description><![CDATA[
Odkąd Flash stał się popularną technologią, namnożyło się w sieci reklam, które tańczą, grają, śpiewają oraz kradną zasoby systemowe. Czasem to tylko denerwuje, a czasem nawet spowalnia przeglądarkę lub zupełnie uniemożliwia pracę.
Postanowiłem ten problem jakoś rozwiązać. Chciałem napisać plugin do FireFox&#8217;a, który zablokuje ładowanie animacji Flash a w ich miejsce wyświetli małą ikonkę, której kliknięcie [...]]]></description>
			<content:encoded><![CDATA[<p><img src="http://temporal.pr0.pl/devblog/download/noflash/noflash.png" alt="Precz z Flash'em!" style="float: left; margin-right: 5px;" /></p>
<p>Odkąd <a href="http://pl.wikipedia.org/wiki/Adobe_Flash">Flash</a> stał się popularną technologią, namnożyło się w sieci reklam, które <a href="http://j-klimek.ovh.org/">tańczą, grają, śpiewają</a> oraz kradną zasoby systemowe. Czasem to tylko denerwuje, a czasem nawet spowalnia przeglądarkę lub zupełnie uniemożliwia pracę.</p>
<p>Postanowiłem ten problem jakoś rozwiązać. Chciałem napisać plugin do FireFox&#8217;a, który zablokuje ładowanie animacji Flash a w ich miejsce wyświetli małą ikonkę, której kliknięcie spowoduje załadowanie animacji na życzenie. Plugin powinien pozwalać na dodawanie niektórych animacji lub witryn do &#8216;białej listy&#8217; tak, żeby nie trzeba było klikać przy każdym wejściu na stronę. Postanowiłem jednak sprawdzić najpierw, czy ktoś czegoś takiego nie zrobił wcześniej&#8230;</p>
<p><a href="http://temporal.pr0.pl/devblog/download/noflash/noflash-screen.png"<img src="http://temporal.pr0.pl/devblog/download/noflash/noflash-screen-150px.png" alt="Działanie FlashBlock" style="float: right; margin-left: 5px;" /></a></p>
<p>&#8230; i ku mojej radości rzeczywiście dokładnie taki plugin powstał. Nazywa się <strong>FlashBlock</strong>. Niestety, jest wciąż to wersja rozwojowa, jednak jest kompatybilna z FireFox&#8217;ami 2.x.x. Działa wyśmienicie i nareszcie mam spokój od denerwujących animacji flash <img src='http://temporal.pr0.pl/devblog/wp-includes/images/smilies/icon_wink.gif' alt=';)' class='wp-smiley' /> .<br />
<strong>Strona projektu</strong>:<br />
<a href="http://flashblock.mozdev.org">http://flashblock.mozdev.org</a></p>
]]></content:encoded>
			<wfw:commentRss>http://temporal.pr0.pl/devblog/2007/12/20/flashblock-precz-z-niepotrzebnym-flashem/feed/</wfw:commentRss>
		<slash:comments>6</slash:comments>
		</item>
		<item>
		<title>OneNote &#8211; użycie</title>
		<link>http://temporal.pr0.pl/devblog/2007/12/19/onenote/</link>
		<comments>http://temporal.pr0.pl/devblog/2007/12/19/onenote/#comments</comments>
		<pubDate>Wed, 19 Dec 2007 14:26:11 +0000</pubDate>
		<dc:creator>Jacek Złydach</dc:creator>
				<category><![CDATA[Informatyka]]></category>
		<category><![CDATA[Pragmatyzm]]></category>
		<category><![CDATA[life hacks]]></category>
		<category><![CDATA[narzędzia]]></category>
		<category><![CDATA[OneNote]]></category>
		<category><![CDATA[porady]]></category>
		<category><![CDATA[Windows]]></category>

		<guid isPermaLink="false">http://temporal.pr0.pl/devblog/2007/12/19/onenote/</guid>
		<description><![CDATA[
Microsoft Office OneNote, o którym wspominałem już kiedyś na devBlogu, jest bardzo przydatnym narzędziem do organizowania pracy i zbierania różnych informacji. Na uwagę zasługują przede wszystkim wygoda użycia i duża funkcjonalność. Oto tylko kilka ciekawszych cech i zastosowań tego programu, z którymi warto się zapoznać:

Windows + N &#8211; szybkie notatki. Użycie tego skrótu powoduje otwarcie [...]]]></description>
			<content:encoded><![CDATA[<p><a href="http://en.wikipedia.org/wiki/Microsoft_OneNote"><img src="http://upload.wikimedia.org/wikipedia/en/8/8f/1note2007.PNG" alt="Logo OneNote" width="128" height="128"  style="float: left; margin-right: 5px;" /></a></p>
<p><strong>Microsoft Office OneNote</strong>, o którym <a href="http://temporal.pr0.pl/devblog/2007/10/20/notatniki-i-organizery-nowej-generacji/">wspominałem już kiedyś na devBlogu</a>, jest bardzo przydatnym narzędziem do organizowania pracy i zbierania różnych informacji. Na uwagę zasługują przede wszystkim wygoda użycia i duża funkcjonalność. Oto tylko kilka ciekawszych cech i zastosowań tego programu, z którymi warto się zapoznać:</p>
<p><a href="http://temporal.pr0.pl/devblog/download/onenote/onenote-small-note.png"><img src="http://temporal.pr0.pl/devblog/download/onenote/onenote-small-note-150px.png" alt="OneNote - mała notka w stylu post-it"  style="float: right; margin-left: 5px;" /></a></p>
<p><strong>Windows + N &#8211; szybkie notatki</strong>. Użycie tego skrótu powoduje otwarcie małego okienka z nową notatką w OneNote (coś na wzór <a href="http://forum.geizhals.at/files/97038/postit.jpg">samoprzylepnych karteczek post-it</a>). W okienku tym możemy zanotować co chcemy, a potem je zamknąć. Wszystkie tak stworzone notatki automatycznie zapisują się w dziale &#8220;Unfiled Notes&#8221;.</p>
<p><strong>OneNote dobrze skaluje treść strony</strong>, żeby sensownie zmieścić się na kartce. Oczywiście jeśli tekstu jest za dużo, to kartek do druku będzie więcej, ale OneNote stara się optymalnie zagospodarować przestrzeń skalując przy drukowaniu treść.</p>
<p><a href="http://temporal.pr0.pl/devblog/download/onenote/onenote-schematics.png"><img src="http://temporal.pr0.pl/devblog/download/onenote/onenote-schematics-150px.png" alt="OneNote - schematy w notatkach"  style="float: left; margin-right: 5px;" /></a></p>
<p> <strong>Łatwość tworzenia notatek</strong> &#8211; wystarczy kliknąć w dowolnym miejscu &#8216;kartki&#8217; i pisać. Teksty można pisać w dowolnym miejscu i rozmieszczać względem siebie w dowolny sposób. Użycie bardziej przypomina edytor grafiki niż program tekstowy. Łatwo też rysuje się schematy przy użyciu prostych narzędzi rysunkowych.</p>
<p><strong>Wygoda formatowania tabelek i list</strong>. Klawisz TAB w sposób automagiczny pozwala nam tworzyć tabelki bardzo łatwo i przyjemnie. Obsługa jest intuicyjna. Także tworzenie list wypunktowanych i numerowanych jest o wiele prostsze niż w normalnych edytorach tekstowych. Używając klawisza TAB/SHIFT+TAB można zmieniać &#8216;głębokość&#8217; danego punktu w listach. Podobny efekt można uzyskać przy użyciu myszki.</p>
<p><strong>Intuicyjna obsługa myszką</strong>. Wszystkie elementy można przeciągać, łączyć ze sobą i rozdzielać. Myszką można bardzo intuicyjnie zmieniać głębokość list wypunktowanych.</p>
<p><a href="http://temporal.pr0.pl/devblog/download/onenote/onenote-screenclipping.png"><img src="http://temporal.pr0.pl/devblog/download/onenote/onenote-screenclipping-150px.png" alt="OneNote - screen clipping tekstu z Wikipedii"  style="float: right; margin-left: 5px;" /></a></p>
<p><strong>Screen Clipping</strong>, dostępny pod skrótem <em>Windows+S</em> pozwala nam zarysować na ekranie ramkę, której zawartość zostanie wklejona do OneNote jako nowa notatka w &#8216;Unfiled Notes&#8217;. Ot, taki zrzut dowolnej części ekranu.</p>
<p><strong>Świetne wsparcie dla schowka</strong>. Przyznam, że ta cecha OneNote zrobiła na mnie największe wrażenie. Wkleić można praktycznie wszystko. Obrazki, teksty, nawet całe strony WWW &#8211; OneNote zachowa ich formatowanie, a na dole umieści dodatkowy komentarz podający źródło. Przykładowo, wklejenie schematu z programu MS Visio powoduje osadzenie w OneNote wektorowego obrazku z tym schematem.</p>
<p><strong>Dodanie OneNote jako wirtualnej drukarki </strong> pozwala na drukowanie dowolnego dokumentu wprost do OneNote. Jest to bardzo przydatne do obchodzenia problemów ze schowkiem w niektórych programach albo brakiem funkcji eksportu grafiki. Osobiście eksport schematu z Visio do pliku JPG robiłem przez wydrukowanie go do OneNote i z OneNote zapisanie jako grafikę.</p>
<p><strong>Zaawansowane opcje tworzenia notatek</strong> pozwalają ograniczyć rozmiar do rozmiaru różnego rodaju papieru.</p>
<p><strong>Office 2007 ma bardzo ładne czcionki ClearType <img src='http://temporal.pr0.pl/devblog/wp-includes/images/smilies/icon_wink.gif' alt=';)' class='wp-smiley' /> </strong></p>
<p>Zostało więc tylko pytanie &#8211; skąd wziąć OneNote? Odpowiedzi mam dwie. Jeśli jesteś studentem to sprawdź, czy Twoja uczelnia współpracuje z Microsoftem w programie <a href="http://www.microsoft.com/poland/edukacja/uczelnie/default.mspx">MSDN Academic Alliance</a>. Jeśli tak, możesz za darmo ściągnąć OneNote 2007. Jeśli nie, zostaje opcja kupienia pakietu Office 2007 w promocji za ok. 300zł (pod warunkiem, że promocja jeszcze trwa).</p>
]]></content:encoded>
			<wfw:commentRss>http://temporal.pr0.pl/devblog/2007/12/19/onenote/feed/</wfw:commentRss>
		<slash:comments>7</slash:comments>
		</item>
		<item>
		<title>Jak wyłączyć restart przy aktualizacji Windows&#8217;a?</title>
		<link>http://temporal.pr0.pl/devblog/2007/12/13/jak-wylaczyc-restart-przy-aktualizacji-windowsa/</link>
		<comments>http://temporal.pr0.pl/devblog/2007/12/13/jak-wylaczyc-restart-przy-aktualizacji-windowsa/#comments</comments>
		<pubDate>Thu, 13 Dec 2007 11:10:22 +0000</pubDate>
		<dc:creator>Jacek Złydach</dc:creator>
				<category><![CDATA[Informatyka]]></category>
		<category><![CDATA[Pragmatyzm]]></category>
		<category><![CDATA[aktualizacje]]></category>
		<category><![CDATA[porady]]></category>
		<category><![CDATA[Windows]]></category>

		<guid isPermaLink="false">http://temporal.pr0.pl/devblog/2007/12/13/jak-wylaczyc-restart-przy-aktualizacji-windowsa/</guid>
		<description><![CDATA[
Wygląda strasznie, nie?  
Jest to jeden z najbardziej denerwujących mnie osobiście składników systemu Windows. Bardzo łatwo przez przypadek zrestartować sobie system. Piszemy sobie kod i możemy potwierdzić komunikat np. klawiszem &#8216;N&#8217;, nawet go nie zauważając. Windows ma też denerwującą tendencję do zaczynania po krótkiej chwili odliczania do przymuszonego restartu. Dziś rano odszedłem na chwilę [...]]]></description>
			<content:encoded><![CDATA[<p style="text-align:center;"><img src="http://temporal.pr0.pl/devblog/download/varia/autoreboot.png" alt="Auto-Reboot after Windows Update" /></p>
<p>Wygląda strasznie, nie? <img src='http://temporal.pr0.pl/devblog/wp-includes/images/smilies/icon_wink.gif' alt=';)' class='wp-smiley' /> </p>
<p>Jest to jeden z najbardziej denerwujących mnie osobiście składników systemu Windows. Bardzo łatwo przez przypadek zrestartować sobie system. Piszemy sobie kod i możemy potwierdzić komunikat np. klawiszem &#8216;N&#8217;, nawet go nie zauważając. Windows ma też denerwującą tendencję do zaczynania po krótkiej <a href="http://www.thecleverest.com/countdown.swf">chwili odliczania</a> do przymuszonego restartu. Dziś rano odszedłem na chwilę od komputera tylko po to, by robiąc sobie śniadanie usłyszeć dźwięk PC-Speaker&#8217;a sygnalizujący mi, że komputer się boot&#8217;uje.</p>
<p>Dzięki tej &#8216;użytecznej&#8217; funkcji łatwo możemy stracić pracę, czas i postrzępić sobie nerwy. Pytanie &#8211; co zrobić z tym problemem?</p>
<p>Jest kilka metod, żeby pozbyć się tego problemu. Na <a href="http://www.codinghorror.com/blog/archives/000294.html">jednej ze stron</a> podano następujące dwie:</p>
<p><strong>Wyłączyć jednorazowo usługę Windows Update</strong><br />
W konsoli (albo start+uruchom) wpisujemy: <code class="codecolorer text default"><span class="text">net stop wuauserv</span></code> lub <code class="codecolorer text default"><span class="text">net stop &quot;automatic updates&quot;</span></code>. Możemy też posłużyć się <a href="http://en.wikipedia.org/wiki/Microsoft_Management_Console">MMC</a>. Po wyłączeniu usługi Windows Update możemy spokojnie pracować, po czym dokonać restartu systemu kiedy nam się spodoba. Po restarcie usługa aktualizacji i tak się włączy <img src='http://temporal.pr0.pl/devblog/wp-includes/images/smilies/icon_wink.gif' alt=';)' class='wp-smiley' /> .</p>
<p><strong>Wyłączyć auto-restartowanie w opcjach group policy.</strong><br />
Używamy do tego MMC. Uruchamiamy <code class="codecolorer text default"><span class="text">gpedit.msc</span></code> i przechodzimy do:</p>
<div class="codecolorer-container text default" style="overflow:auto;white-space:nowrap;border:1px solid #9F9F9F;width:435px;"><div class="text codecolorer" style="padding:5px;font:normal 12px/1.4em Monaco, Lucida Console, monospace;white-space:nowrap">Local Computer Policy -&gt; Computer Configuration -&gt; Administrative Templates -&gt; Windows Components -&gt; Windows Update</div></div>
<p>W dostępnych tam opcjach możemy albo włączyć <em>No auto-restart for schedule Automatic Updates installations</em>, albo ustawić <em>Re-prompt for restart with scheduled installations</em> na jakiś długi czas, np. 1440 minut.</p>
<p>Istnieje <strong>jeszcze jedno rozwiązanie</strong>, <a href="http://www.emailbattles.com/2006/01/11/vuln_aacgjahfig_ib/">podane na innej stronie</a>. Należy wyłączyć Windows Update (patrz sposób pierwszy), zakończyć wszystkie instancje procesu wuauclt.exe, i dokonać następującej zmiany w rejestrze:<br />
W kluczu <code class="codecolorer text default"><span class="text">HKEY_LOCAL_MACHINE\Software\Policies\Microsoft\ Windows\WindowsUpdate\AU</span></code> tworzymy (lub zmieniamy, jeśli istnieje) wartość <em>NoAutoRebootWithLoggedOnUsers</em> na 1.</p>
]]></content:encoded>
			<wfw:commentRss>http://temporal.pr0.pl/devblog/2007/12/13/jak-wylaczyc-restart-przy-aktualizacji-windowsa/feed/</wfw:commentRss>
		<slash:comments>3</slash:comments>
		</item>
		<item>
		<title>Świeże Bułeczki &#8211; jak pisać specyfikacje</title>
		<link>http://temporal.pr0.pl/devblog/2007/12/13/swieze-buleczki-jak-pisac-specyfikacje/</link>
		<comments>http://temporal.pr0.pl/devblog/2007/12/13/swieze-buleczki-jak-pisac-specyfikacje/#comments</comments>
		<pubDate>Wed, 12 Dec 2007 23:24:36 +0000</pubDate>
		<dc:creator>Jacek Złydach</dc:creator>
				<category><![CDATA[Informatyka]]></category>
		<category><![CDATA[Pragmatyzm]]></category>
		<category><![CDATA[Projekty studenckie]]></category>
		<category><![CDATA[Tworzenie gier]]></category>
		<category><![CDATA[AGH]]></category>
		<category><![CDATA[Bułka]]></category>
		<category><![CDATA[porady]]></category>
		<category><![CDATA[projektowanie]]></category>
		<category><![CDATA[specyfikacje]]></category>

		<guid isPermaLink="false">http://temporal.pr0.pl/devblog/2007/12/13/swieze-buleczki-jak-pisac-specyfikacje/</guid>
		<description><![CDATA[Kilka dobrych rad prosto z ostatnich minut wtorkowego wykładu dr Bułki. Rady te dotyczą przede wszystkim specyfikacji pisanych dla większych projektów, realizowanych w zespołach. Myślę jednak, że przydadzą się każdemu, kto zabiera się za jakikolwiek (jedno lub wieloosobowy) projekt informatyczny &#8211; w końcu dobry design document to podstawa  .
Rady podstawowe

Za specyfikację odpowiedzialna jest jedna [...]]]></description>
			<content:encoded><![CDATA[<p>Kilka dobrych rad prosto z ostatnich minut wtorkowego wykładu dr Bułki. Rady te dotyczą przede wszystkim specyfikacji pisanych dla większych projektów, realizowanych w zespołach. Myślę jednak, że przydadzą się każdemu, kto zabiera się za jakikolwiek (jedno lub wieloosobowy) projekt informatyczny &#8211; w końcu dobry design document to podstawa <img src='http://temporal.pr0.pl/devblog/wp-includes/images/smilies/icon_smile.gif' alt=':)' class='wp-smiley' /> .</p>
<p><strong>Rady podstawowe</strong></p>
<ul>
<li>Za specyfikację odpowiedzialna jest <strong>jedna osoba</strong>. Za jej dostępność, za wprowadzane do niej poprawki. Osoba ta rozwiązuje też sytuacje konfliktowe. Przykład z wykładu &#8211; kiedy przychodzi Project Manager do programisty i mówi, że ma być tak a tak, a on na to &#8211; <em>&#8220;sorry, ale ta żaba to no way&#8221;</em>. Osoba odpowiedzialna za spec&#8217;a podejmuje ostateczną decyzję co ma być.</li>
<li>Specyfikacja jest <strong>jednolita dla zespołu</strong>. Project Manager, programiści, QA, dostawca pizzy &#8211; wszyscy korzystają z tego samego dokumentu.</li>
<li>Należy stosować jakiś <strong>sposób oznaczania rzeczy, które są niejasne</strong>, zostaną uzgodnione w przyszłości. Przyjęło się oznaczać takie miejsca magicznym <em>FIXME</em>.</li>
<li>Specyfikacja przedstawia system <strong>z punktu widzenia użytkownika</strong>. Nie opisujemy szczegółów implementacji, ale to, jak system działa i wygląda dla tego, kto z niego korzysta.</li>
</ul>
<p><strong>Składowe specyfikacji</strong></p>
<ul>
<li><strong>Wprowadzenie</strong> &#8211; ogólny opis systemu, tzw. The Big Picture. Co to jest, do czego to ma służyć.</li>
<li><strong>Scenariusze Użycia</strong> &#8211; jak użytkownik może korzystać z systemu, opisane na konkretnych przykładach, z konkretnymi (nazwanymi) uczestnikami. Ot tata Adam ma syna Jasia, którego chce zapisać do przedszkola (jeśli piszemy system elektronicznej rejestracji do przedszkoli). Co robi? Jak zachowuje się nasz system?</li>
<li><em><strong>&#8220;niecele&#8221;</strong></em> &#8211; czyli to, czego system na pewno NIE będzie robił. Jest to bardzo ważne dla naszego klienta, a dla nas jest gwarancją spokojnego snu. Ot, przykładowy klient przychodzi do nas z pretensjami, czemu właśnie wyprodukowany system nie robi tego-a-tego. Pokazujemy mu spec&#8217;a i mówimy, że <em>&#8216;jest tu wyraźnie napisane, że system tego robić nie będzie; a pan się pod tym podpisał&#8230;&#8217;</em> <img src='http://temporal.pr0.pl/devblog/wp-includes/images/smilies/icon_wink.gif' alt=';)' class='wp-smiley' /> . Jest to często pomijana, a tak na prawdę kluczowa składowa dobrego spec&#8217;a. Wraz z dobrym określeniem tego co system będzie robił, pomaga zarysować granice funkcjonalności projektu.</li>
<li><strong>Opis</strong> &#8211; czym jest projekt, z punktu widzenia. Tu ma miejsce podział systemu na różne fragmenty. Ale uwaga &#8211; to nie jest miejsce na <a href="http://pl.wikipedia.org/wiki/Eliza_Orzeszkowa">Elizę Orzeszkową</a> &#8211; mimo wszystko trzeba pisać o konkretach i unikać opisów pogody nad Niemnem. </li>
<li><strong>Składowe systemu</strong> &#8211; szczegółowy opis fragmentów, na jakie podzieliliśmy projekt. Jak powinny wyglądać, jak mają działać &#8211; ale cały czas z punktu widzenia użytkownika. Pożądane są tu wszelkiego rodzaju rysunki, screeny, concept art&#8217;y, itp.</li>
</ul>
<p><strong>Porada końcowa</strong><br />
<strong>Luźne stwierdzenia</strong> w spec&#8217;u są jak najbardziej pożądane. Oczywiście przesadzać nie można, ale odrobinę sensownego humoru nie zaszkodzi.</p>
<p>Tyle moich notatek z wykładu. Jak dane mi będzie zdobyć więcej informacji, to również się nimi podzielę. Poważnie też zastanawiam się nad zamieszczeniem notatek i wniosków z poprzednich wykładów dr Bułki &#8211; dotyczących prezentacji multimedialnych i przekazu reklamowego w ogóle. Ze swojej strony odniosę się jeszcze do terminu &#8220;niecel&#8221;. Nie mogliśmy znaleźć na wykładzie żadnego dobrego polskiego określenia. Ale tak w tej chwili wydaje mi się, że lepiej brzmiącym słowem &#8211; aczkolwiek troszkę mniej mówiącym &#8211; byłoby &#8216;antycel&#8217;.</p>
]]></content:encoded>
			<wfw:commentRss>http://temporal.pr0.pl/devblog/2007/12/13/swieze-buleczki-jak-pisac-specyfikacje/feed/</wfw:commentRss>
		<slash:comments>6</slash:comments>
		</item>
		<item>
		<title>&#8220;Odcinanie centymetra&#8221; &#8211; miernik sukcesu</title>
		<link>http://temporal.pr0.pl/devblog/2007/12/12/odcinanie-centymetra-miernik-sukcesu/</link>
		<comments>http://temporal.pr0.pl/devblog/2007/12/12/odcinanie-centymetra-miernik-sukcesu/#comments</comments>
		<pubDate>Wed, 12 Dec 2007 17:46:41 +0000</pubDate>
		<dc:creator>Jacek Złydach</dc:creator>
				<category><![CDATA[Pragmatyzm]]></category>
		<category><![CDATA[Rozwój osobisty]]></category>
		<category><![CDATA[life hacks]]></category>
		<category><![CDATA[porady]]></category>

		<guid isPermaLink="false">http://temporal.pr0.pl/devblog/2007/12/12/odcinanie-centymetra-miernik-sukcesu/</guid>
		<description><![CDATA[Na forum proaktywnie.pl jedna z uczestniczek zaproponowała dość ciekawą metodę na mierzenie postępu nad wszelkiego rodzaju projektami. Przygotowujemy sobie długi prostokątny kawałek papieru i robimy na nim podziałkę. W każdej &#8216;komórce&#8217; wpisujemy kolejny krok do ukończenia (szeroko rozumianego) projektu &#8211; np. liczba dni do jakiejś nagrody, kolejne etapy projektowania, kolejne rzeczy do napisania, etc. Całość [...]]]></description>
			<content:encoded><![CDATA[<p>Na forum proaktywnie.pl <a href="http://www.forum.proaktywnie.pl/viewtopic.php?id=13">jedna z uczestniczek zaproponowała</a> dość ciekawą metodę na mierzenie postępu nad wszelkiego rodzaju projektami. Przygotowujemy sobie długi prostokątny kawałek papieru i robimy na nim podziałkę. W każdej &#8216;komórce&#8217; wpisujemy kolejny krok do ukończenia (szeroko rozumianego) projektu &#8211; np. liczba dni do jakiejś nagrody, kolejne etapy projektowania, kolejne rzeczy do napisania, etc. Całość przypomina trochę centymetr krawiecki. Tak przygotowany miernik wieszamy sobie np. nad biurkiem, i z każdym ukończonym krokiem odrywamy końcówkę. <em>&#8220;Im krótszy papierek tym bliżej do celu <img src='http://temporal.pr0.pl/devblog/wp-includes/images/smilies/icon_smile.gif' alt=':)' class='wp-smiley' /> &#8221;</em></p>
]]></content:encoded>
			<wfw:commentRss>http://temporal.pr0.pl/devblog/2007/12/12/odcinanie-centymetra-miernik-sukcesu/feed/</wfw:commentRss>
		<slash:comments>1</slash:comments>
		</item>
		<item>
		<title>Delphied :)</title>
		<link>http://temporal.pr0.pl/devblog/2007/11/27/delphied/</link>
		<comments>http://temporal.pr0.pl/devblog/2007/11/27/delphied/#comments</comments>
		<pubDate>Tue, 27 Nov 2007 10:45:55 +0000</pubDate>
		<dc:creator>Jacek Złydach</dc:creator>
				<category><![CDATA[Informatyka]]></category>
		<category><![CDATA[Tworzenie gier]]></category>
		<category><![CDATA[AGH]]></category>
		<category><![CDATA[Delphi]]></category>

		<guid isPermaLink="false">http://temporal.pr0.pl/devblog/2007/11/27/delphied/</guid>
		<description><![CDATA[I stało się. Nie myślałem, że przytrafi mi się to kiedykolwiek. Wczoraj wgrałem Borland Delphi 7 Personal. Nie, nie przesiadam się na Object Pascala  . Wszystko przez przedmiot na studiach, zwany &#8220;Podstawy Informatyki&#8221;. W dużym skrócie są to algorytmy w Pascalu. Wczoraj wykładowca podał tematy projektów zaliczeniowych, które trzeba wykonać (w dużym skrócie ocenę [...]]]></description>
			<content:encoded><![CDATA[<p>I stało się. Nie myślałem, że przytrafi mi się to kiedykolwiek. Wczoraj wgrałem <a href="http://www.dhost.info/download/details.php?id=4145572340">Borland Delphi 7 Personal</a>. Nie, nie przesiadam się na Object Pascala <img src='http://temporal.pr0.pl/devblog/wp-includes/images/smilies/icon_wink.gif' alt=';)' class='wp-smiley' /> . Wszystko przez przedmiot na studiach, zwany &#8220;Podstawy Informatyki&#8221;. W dużym skrócie są to algorytmy w Pascalu. Wczoraj wykładowca podał tematy projektów zaliczeniowych, które trzeba wykonać (w dużym skrócie ocenę liczy z 20 punktów, na które składa się 10 punktów za kolokwium i 10 punktów za projekty). Na szczęście, im bardziej ambitne projekty (czyt. te za 7 lub 10 punktów) tym więcej tematów to gry <img src='http://temporal.pr0.pl/devblog/wp-includes/images/smilies/icon_wink.gif' alt=';)' class='wp-smiley' /> . Postanowiłem napisać Arkanoida w Delphi (wymóg przedmiotu: Pascal albo Delphi) i OpenGL. <a href="http://temporal.pr0.pl/devblog/projekty/arkanoid/">Arkanoida</a> kiedyś już pisałem, co prawda w C++, ale przynajmniej wiem o co chodzi <img src='http://temporal.pr0.pl/devblog/wp-includes/images/smilies/icon_smile.gif' alt=':)' class='wp-smiley' /> .</p>
<p>Tutaj warto wspomnieć o ciekawej pomyłce. Lista tematów wymieniała Arkanoida dwukrotnie, za każdym razem pod nazwą &#8220;Archanoid&#8221;, którą to potraktowano jako nazwę gatunku. Jestem przekonany, skąd wzięła się ta skądinąd ciekawa pomyłka; tylko co na to powie <a href="http://student.agh.edu.pl/~koshmaar/homepage/content/games.php">Koshmaar</a> <img src='http://temporal.pr0.pl/devblog/wp-includes/images/smilies/icon_smile.gif' alt=':)' class='wp-smiley' /> .</p>
]]></content:encoded>
			<wfw:commentRss>http://temporal.pr0.pl/devblog/2007/11/27/delphied/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>My phone of choice.</title>
		<link>http://temporal.pr0.pl/devblog/2007/11/04/my-phone-of-choice/</link>
		<comments>http://temporal.pr0.pl/devblog/2007/11/04/my-phone-of-choice/#comments</comments>
		<pubDate>Sat, 03 Nov 2007 22:59:14 +0000</pubDate>
		<dc:creator>Jacek Złydach</dc:creator>
				<category><![CDATA[Applied Science]]></category>
		<category><![CDATA[Informatyka]]></category>
		<category><![CDATA[Pragmatyzm]]></category>
		<category><![CDATA[Z życia]]></category>
		<category><![CDATA[telefon]]></category>

		<guid isPermaLink="false">http://temporal.pr0.pl/devblog/2007/11/04/my-phone-of-choice/</guid>
		<description><![CDATA[Nie jestem na bieżąco z telefonią GSM. W obecnej chwili spłacam już chyba trzeci rok (straciłem rachubę po dwóch) Motorolę C651 w MixPlusie oraz korzystam z Nokii 6060 do nadużywania tzw. &#8220;SMSów za jeden grosz w POPie&#8221;. Nie są to za ambitne maszynki, ale do komunikacji sprawdzają się dobrze. Przyglądam się jednak czasami skokom w [...]]]></description>
			<content:encoded><![CDATA[<p>Nie jestem na bieżąco z telefonią GSM. W obecnej chwili spłacam już chyba trzeci rok (straciłem rachubę po dwóch) <a href="http://www.mgsm.pl/katalog/motorola/c651/">Motorolę C651</a> w MixPlusie oraz korzystam z <a href="http://www.mgsm.pl/katalog/nokia/6060/">Nokii 6060</a> do nadużywania tzw. &#8220;SMSów za jeden grosz w POPie&#8221;. Nie są to za ambitne maszynki, ale do komunikacji sprawdzają się dobrze. Przyglądam się jednak czasami skokom w dziedzinie telefonii GSM w kręgu popularnym (czyt. telefony dostępne w przystępnej cenie dla szarego mieszkańca kraju). Ostatnio coraz większą popularność zdobywają muzyczne telefony Nokii oraz nowe Sony Ericsson&#8217;y. <a href="http://www.mgsm.pl/katalog/sonyericsson/k800i/">K800i</a> to prawdziwy kombajn, a wbudowany aparat 3.2MP pozwala robić zdjęcia lepsze niż z taniej cyfrówki. Patrzę się tak, oglądam i czasem smutno się robi, że znani mi użytkownicy nie wykorzystują możliwości swoich nowych telefonów nawet w 20%. Ale to zawodzenie kogoś, kto żyje bez cyfrówki i MP3 playera <img src='http://temporal.pr0.pl/devblog/wp-includes/images/smilies/icon_smile.gif' alt=':)' class='wp-smiley' /> .</p>
<p>Dzięki <a href="http://nawias.com/">RaV</a>&#8216;owi odkryłem dziś nowy telefon &#8211; <a href="http://blog.i64.pl/BlogPio/200710/19-neo1973-pierwsze-wrazenia/">Neo1973</a>. Jest to projekt rewolucyjny. Mamy do czynienia z wygodnym w obsłudze telefonem (ekran dotykowy + stylus) kategorii tych &#8216;lepszych&#8217; modeli. Różnica między nim a pozostałymi jest jedna, i bardzo ważna. Telefon ten pracuje pod kontrolą Linuxa i pozwala w dużym skrócie na zrobienie z nim co się tylko podoba. Pracujemy na nim jak na normalnym Linuxie &#8211; tj. możemy chociażby skorzystać z konsoli czy kompilować i instalować własne programy w różnych językach programowania. Polecam przeglądnąć <a href="htt