<?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/"
	>

<channel>
	<title>xion.log &#187; Applications</title>
	<atom:link href="http://xion.org.pl/category/it/apps/feed/" rel="self" type="application/rss+xml" />
	<link>http://xion.org.pl</link>
	<description>Programming on (many) different levels of abstraction</description>
	<lastBuildDate>Thu, 10 May 2012 18:44:29 +0000</lastBuildDate>
	<language>en</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
	<generator>http://wordpress.org/?v=3.3.2</generator>
		<item>
		<title>DreamPie with virtualenv</title>
		<link>http://xion.org.pl/2012/05/10/dreampie-with-virtualenv/</link>
		<comments>http://xion.org.pl/2012/05/10/dreampie-with-virtualenv/#comments</comments>
		<pubDate>Thu, 10 May 2012 18:44:29 +0000</pubDate>
		<dc:creator>Xion</dc:creator>
				<category><![CDATA[Applications]]></category>
		<category><![CDATA[Programming]]></category>
		<category><![CDATA[bash]]></category>
		<category><![CDATA[DreamPie]]></category>
		<category><![CDATA[Linux]]></category>
		<category><![CDATA[Python]]></category>
		<category><![CDATA[virtualenv]]></category>

		<guid isPermaLink="false">http://xion.org.pl/?p=3556</guid>
		<description><![CDATA[If you haven't heard about it, DreamPie is an awesome GUI application layered on top of standard Python shell. I use it for elaborate prototyping where its multi-line input box is a significant advance over raw, terminal UX of IPython. However, up until recently I didn't know how to make DreamPie cooperate with virtualenv. Because [...]]]></description>
			<content:encoded><![CDATA[<p>If you haven't heard about it, <a href="http://dreampie.sourceforge.net/">DreamPie</a> is an awesome GUI application layered on top of standard Python shell. I use it for elaborate prototyping where its multi-line input box is a significant advance over raw, terminal UX of <a href="http://ipython.org/">IPython</a>.</p>
<p><img style="float:right; margin: 7px" src="http://xion.org.pl/wp-content/uploads/2012/05/dreampie-cloud.png" alt="" />However, up until recently I didn't know how to make DreamPie cooperate with <a href="http://www.virtualenv.org/">virtualenv</a>. Because it's a GUI program, I scoured its menu and all the preference windows, searching for any trace of option that would allow me to set the Python executable. Having failed, I was convinced that authors didn't think about including it - which was rather surprising, though.</p>
<p>But hey, DreamPie is open source! So I went to look around its <a href="http://bazaar.launchpad.net/~dreampie-devel/dreampie/trunk/files">code</a> to see whether I can easily enhance it with an ability to specify Python binary. It wasn't too long before I <a href="http://bazaar.launchpad.net/~dreampie-devel/dreampie/trunk/view/head:/dreampielib/gui/__init__.py">stumbled</a> into this vital fragment:</p>
<div class="syntax_hilite">
<div id="python-4">
<div class="python"><span style="color: #ff7700;font-weight:bold;">def</span> main<span style="color: black;">&#40;</span><span style="color: black;">&#41;</span>:<br />
&nbsp; &nbsp; usage = <span style="color: #483d8b;">"%prog [options] [python-executable]"</span><br />
&nbsp; &nbsp; version = <span style="color: #483d8b;">'DreamPie %s'</span> % __version__<br />
&nbsp; &nbsp; <span style="color: #dc143c;">parser</span> = OptionParser<span style="color: black;">&#40;</span>usage=usage, version=version<span style="color: black;">&#41;</span><br />
&nbsp; &nbsp; <span style="color: #808080; font-style: italic;"># ...</span><br />
&nbsp; &nbsp; opts, args = <span style="color: #dc143c;">parser</span>.<span style="color: black;">parse_args</span><span style="color: black;">&#40;</span><span style="color: black;">&#41;</span></div>
</div>
</div>
<p>
The conclusions we could draw from this anecdote are thereby as follows:</p>
<ul>
<li>It is indeed true that source code is often the best documentation...</li>
<li>...especially for open source programs where <em>actual</em> docs often suck.</li>
</ul>
<p>With this newfound knowledge about <kbd>dreampie</kbd> arguments, it wasn't very hard to make it use current virtualenv:</p>
<div class="syntax_hilite">
<div id="code-5">
<div class="code">$ dreampie $<span style="color:#006600; font-weight:bold;">&#40;</span>which python<span style="color:#006600; font-weight:bold;">&#41;</span></div>
</div>
</div>
<p>
And after doing <a href="http://superuser.com/questions/177218/how-to-start-gui-linux-programs-from-the-command-line-but-separate-from-the-com">some</a> more <a href="http://stackoverflow.com/questions/876239/bash-redirect-and-append-both-stdout-and-stderr">research</a>, I ended up adding the following line to my <em>~/.bash_aliases</em>:</p>
<div class="syntax_hilite">
<div id="code-6">
<div class="code">alias dp=<span style="color:#CC0000;">'(dreampie $(which python) &amp;&gt;/dev/null &amp;)'</span></div>
</div>
</div>
<p>
Now I can simply type <kbd>dp</kbd> to get a DreamPie instance operating within current virtualenv but independent from terminal session. Very useful!</p>
]]></content:encoded>
			<wfw:commentRss>http://xion.org.pl/2012/05/10/dreampie-with-virtualenv/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Self-Replacing Script Blocks for Dynamic Lists</title>
		<link>http://xion.org.pl/2012/01/17/self-replacing-script-blocks-for-dynamic-lists/</link>
		<comments>http://xion.org.pl/2012/01/17/self-replacing-script-blocks-for-dynamic-lists/#comments</comments>
		<pubDate>Tue, 17 Jan 2012 07:52:19 +0000</pubDate>
		<dc:creator>Xion</dc:creator>
				<category><![CDATA[Applications]]></category>
		<category><![CDATA[Internet]]></category>
		<category><![CDATA[AJAX]]></category>
		<category><![CDATA[Django]]></category>
		<category><![CDATA[HTML]]></category>
		<category><![CDATA[JavaScript]]></category>
		<category><![CDATA[Jinja]]></category>
		<category><![CDATA[jQuery]]></category>
		<category><![CDATA[JSON]]></category>
		<category><![CDATA[templates]]></category>

		<guid isPermaLink="false">http://xion.org.pl/?p=3316</guid>
		<description><![CDATA[On contemporary websites and web applications, it is extremely common task to display a list of items on page. In any reasonable framework and/or templating engine, this can be accomplished rather trivially. Here's how it could look like in Jinja or Django templates: &#60;ul&#62; &#123;% for item in items %&#125; &#160; &#160; &#60;li&#62;&#123;&#123; item &#125;&#125;&#60;/li&#62; [...]]]></description>
			<content:encoded><![CDATA[<p>On contemporary websites and web applications, it is extremely common task to display a list of items on page. In any reasonable framework and/or templating engine, this can be accomplished rather trivially. Here's how it could look like in Jinja or Django templates:</p>
<div class="syntax_hilite">
<div id="code-12">
<div class="code">&lt;ul&gt;<br />
<span style="color:#006600; font-weight:bold;">&#123;</span>% for item in items %<span style="color:#006600; font-weight:bold;">&#125;</span><br />
&nbsp; &nbsp; &lt;li&gt;<span style="color:#006600; font-weight:bold;">&#123;</span><span style="color:#006600; font-weight:bold;">&#123;</span> item <span style="color:#006600; font-weight:bold;">&#125;</span><span style="color:#006600; font-weight:bold;">&#125;</span>&lt;/li&gt;<br />
<span style="color:#006600; font-weight:bold;">&#123;</span>% endfor %<span style="color:#006600; font-weight:bold;">&#125;</span><br />
&lt;/ul&gt;</div>
</div>
</div>
<p>
But it's usually not too long before our list grows big and it becomes unfeasible to render it all on the server. Or maybe, albeit less likely, we want it to be updated in real-time, without having to reload the whole page. Either case requires to incorporate some JavaScript code, talking to the server and obtaining next portion of data whenever it's needed.</p>
<p>Obviously, that data has to be rendered as well, and there is one option of doing it on the server side, serving actual HTML directly to JS. An arguably better solution is to respond with JSON or similar representation of our items. This is conceptually simpler, feels less messy and is potentially reusable as a part of website's external API. There is just one drawback: it forces rendering to be done also in JavaScript.<br />
<span id="more-3316"></span><br />
While it isn't a hindrance by itself (there are many great tools to help, including <a href="https://github.com/janl/mustache.js">Mustache</a> or - sadly discontinued - <a href="http://api.jquery.com/category/plugins/templates/">jQuery Templates</a>), it raises an issue of code duplication. Ideally, we would still want some initial data to be displayed just when the page itself is loaded. And at first, this seems as to require <em>both</em> server-side <em>and</em> client-side rendering functions... I hope I do not really have to explain why it would be a mighty bad idea to create, use and (try to) maintain them.</p>
<h3>Client is king</h3>
<p>That's why we would opt for rendering exclusively in the browser. Fortunately, it is not only possible, but also quite easy if we already have the logic for handling AJAX calls. Using it, we can prepare initial items in JSON format and put them directly inside some <code>&lt;script></code> block:</p>
<div class="syntax_hilite">
<div id="javascript-13">
<div class="javascript">&lt;script type=<span style="color: #3366CC;">"text/javascript"</span>&gt;<br />
&nbsp; &nbsp; $<span style="color: #66cc66;">&#40;</span>document<span style="color: #66cc66;">&#41;</span>.<span style="color: #006600;">ready</span><span style="color: #66cc66;">&#40;</span><span style="color: #003366; font-weight: bold;">function</span><span style="color: #66cc66;">&#40;</span><span style="color: #66cc66;">&#41;</span> <span style="color: #66cc66;">&#123;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #003366; font-weight: bold;">var</span> items = <span style="color: #66cc66;">&#123;</span><span style="color: #66cc66;">&#123;</span> items|json <span style="color: #66cc66;">&#125;</span><span style="color: #66cc66;">&#125;</span>;<br />
&nbsp; &nbsp; &nbsp; &nbsp; renderItems<span style="color: #66cc66;">&#40;</span>$<span style="color: #66cc66;">&#40;</span><span style="color: #3366CC;">'#items'</span><span style="color: #66cc66;">&#41;</span>, items<span style="color: #66cc66;">&#41;</span>;<br />
&nbsp; &nbsp; <span style="color: #66cc66;">&#125;</span><span style="color: #66cc66;">&#41;</span>;<br />
&lt;/script&gt;</div>
</div>
</div>
<p>
Here, the <code>|json</code> filter represents the before mentioned logic, while <code>renderItems</code> draws the objects-turned items as children of given element. What it does inside can vary from manipulating HTML strings directly (eww!), creating DOM objects (slightly better) or invoking some JS templating engine (best).</p>
<h3>Striving for modularity</h3>
<p>A simple solution, outlined above, looks sufficient for many practical applications. It is far from ideal, though. For one, it suffers from an acute disconnection, since the actual place where the data is displayed (<code>$('#items')</code>) can be arbitrarily far from the <code>&lt;script></code> tag. But more importantly, it scales poorly and lacks modularity: should we need to use our list on more than one site, we may need to carefully tailor several moving parts - such as the <code>'#items'</code> selector.</p>
<p>Incidentally, both of those issues can be resolved at once. Let's create a <em>self-replacing</em> <code>&lt;script></code>: quite similar to the one above, but with some interesting twists. Rather than referencing some DOM element via hard-coded selector, it shall render the items "where they stand": exactly where the very <code>&lt;script></code> is located. And just as a final touch, the script will even remove itself from the DOM tree when it's no longer needed.</p>
<h3>The solution...</h3>
<p>Sounds like a pretty clever trick, but it's not exactly complicated at all. In its entirety, it can look somewhat like this:</p>
<div class="syntax_hilite">
<div id="javascript-14">
<div class="javascript">&lt;script type=<span style="color: #3366CC;">"text/javascript"</span>&gt;<br />
&nbsp; &nbsp; <span style="color: #66cc66;">&#40;</span><span style="color: #003366; font-weight: bold;">function</span><span style="color: #66cc66;">&#40;</span><span style="color: #66cc66;">&#41;</span> <span style="color: #66cc66;">&#123;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #003366; font-weight: bold;">var</span> $script = $<span style="color: #66cc66;">&#40;</span><span style="color: #3366CC;">'script'</span><span style="color: #66cc66;">&#41;</span>.<span style="color: #006600;">last</span><span style="color: #66cc66;">&#40;</span><span style="color: #66cc66;">&#41;</span>;<br />
&nbsp; &nbsp; &nbsp; &nbsp; $<span style="color: #66cc66;">&#40;</span>document<span style="color: #66cc66;">&#41;</span>.<span style="color: #006600;">ready</span><span style="color: #66cc66;">&#40;</span><span style="color: #003366; font-weight: bold;">function</span><span style="color: #66cc66;">&#40;</span><span style="color: #66cc66;">&#41;</span> <span style="color: #66cc66;">&#123;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #003366; font-weight: bold;">var</span> items = <span style="color: #66cc66;">&#123;</span><span style="color: #66cc66;">&#123;</span> items|json <span style="color: #66cc66;">&#125;</span><span style="color: #66cc66;">&#125;</span>;<br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; renderItems<span style="color: #66cc66;">&#40;</span>$script.<span style="color: #006600;">parent</span><span style="color: #66cc66;">&#40;</span><span style="color: #66cc66;">&#41;</span>, items<span style="color: #66cc66;">&#41;</span>;<br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; $script.<span style="color: #006600;">remove</span><span style="color: #66cc66;">&#40;</span><span style="color: #66cc66;">&#41;</span>;<br />
&nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #66cc66;">&#125;</span><span style="color: #66cc66;">&#41;</span>;<br />
&nbsp; &nbsp; <span style="color: #66cc66;">&#125;</span><span style="color: #66cc66;">&#41;</span><span style="color: #66cc66;">&#40;</span><span style="color: #66cc66;">&#41;</span>;<br />
&lt;/script&gt;</div>
</div>
</div>
<p>
What makes it work is the fact that <code>var $script = ...;</code> line lies <em>outside</em> of the <code>$document.ready</code> function. Thanks to that, it is executed as soon as the <code>&lt;script></code> block is parsed - before the rest of document is processed, and way before the <code>$(document).ready</code> callback is invoked.<br />
At that early time, this script is therefore the last <code>&lt;script></code> element in the DOM tree. In other words, it's exactly what <code>$('script').last()</code> will return! What we are doing in the first line is therefore nothing else, but obtaining a reference to the enclosing <code>&lt;script></code>.</p>
<p>How's that useful, though?... Well, if we have indeed dropped this <code>&lt;script></code> right where we wanted our dynamic list to display, its <code>parent()</code> would be the element to render our items in. And because we don't mind cleaning up after ourselves when done, we finish this by <code>remove()</code>-ing the script. Nice and tidy.</p>
<h3>...and how to use it</h3>
<p>What makes it a pretty powerful technique is easy and flexible integration with modern templating engines. We can almost effortlessly made this snippet into a reusable template part, such as Jinja macro:</p>
<div class="syntax_hilite">
<div id="javascript-15">
<div class="javascript"><span style="color: #66cc66;">&#123;</span>% macro render<span style="color: #66cc66;">&#40;</span>items<span style="color: #66cc66;">&#41;</span> %<span style="color: #66cc66;">&#125;</span><br />
&lt;script type=<span style="color: #3366CC;">"text/javascript"</span>&gt;<br />
&nbsp; &nbsp; <span style="color: #66cc66;">&#40;</span><span style="color: #003366; font-weight: bold;">function</span><span style="color: #66cc66;">&#40;</span><span style="color: #66cc66;">&#41;</span> <span style="color: #66cc66;">&#123;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #003366; font-weight: bold;">var</span> $script = $<span style="color: #66cc66;">&#40;</span><span style="color: #3366CC;">'script'</span><span style="color: #66cc66;">&#41;</span>.<span style="color: #006600;">last</span><span style="color: #66cc66;">&#40;</span><span style="color: #66cc66;">&#41;</span>;<br />
&nbsp; &nbsp; &nbsp; &nbsp; $<span style="color: #66cc66;">&#40;</span>document<span style="color: #66cc66;">&#41;</span>.<span style="color: #006600;">ready</span><span style="color: #66cc66;">&#40;</span><span style="color: #003366; font-weight: bold;">function</span><span style="color: #66cc66;">&#40;</span><span style="color: #66cc66;">&#41;</span> <span style="color: #66cc66;">&#123;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #003366; font-weight: bold;">var</span> items = <span style="color: #66cc66;">&#123;</span><span style="color: #66cc66;">&#123;</span> items|json <span style="color: #66cc66;">&#125;</span><span style="color: #66cc66;">&#125;</span>;<br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; renderItems<span style="color: #66cc66;">&#40;</span>$script.<span style="color: #006600;">parent</span><span style="color: #66cc66;">&#40;</span><span style="color: #66cc66;">&#41;</span>, items<span style="color: #66cc66;">&#41;</span>;<br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; $script.<span style="color: #006600;">remove</span><span style="color: #66cc66;">&#40;</span><span style="color: #66cc66;">&#41;</span>;<br />
&nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #66cc66;">&#125;</span><span style="color: #66cc66;">&#41;</span>;<br />
&nbsp; &nbsp; <span style="color: #66cc66;">&#125;</span><span style="color: #66cc66;">&#41;</span><span style="color: #66cc66;">&#40;</span><span style="color: #66cc66;">&#41;</span>;<br />
&lt;/script&gt;<br />
<span style="color: #66cc66;">&#123;</span>% endmacro %<span style="color: #66cc66;">&#125;</span></div>
</div>
</div>
<p>
The final usage would be then extremely clean and simple:</p>
<div class="syntax_hilite">
<div id="html-16">
<div class="html"><span style="color: #009900;"><a href="http://december.com/html/4/element/div.html"><span style="color: #000000; font-weight: bold;">&lt;div</span></a> <span style="color: #000066;">class</span>=<span style="color: #ff0000;">"items"</span><span style="color: #000000; font-weight: bold;">&gt;</span></a></span><br />
&nbsp; &nbsp; {{ render(items) }}<br />
<span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;/div&gt;</span></span></div>
</div>
</div>
<p></p>
]]></content:encoded>
			<wfw:commentRss>http://xion.org.pl/2012/01/17/self-replacing-script-blocks-for-dynamic-lists/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Proste formaty tekstowe</title>
		<link>http://xion.org.pl/2011/09/02/proste-formaty-tekstowe/</link>
		<comments>http://xion.org.pl/2011/09/02/proste-formaty-tekstowe/#comments</comments>
		<pubDate>Fri, 02 Sep 2011 21:02:47 +0000</pubDate>
		<dc:creator>Xion</dc:creator>
				<category><![CDATA[Applications]]></category>
		<category><![CDATA[Programming]]></category>
		<category><![CDATA[data formats]]></category>
		<category><![CDATA[documentation]]></category>
		<category><![CDATA[text]]></category>

		<guid isPermaLink="false">http://xion.org.pl/?p=2933</guid>
		<description><![CDATA[Wprawdzie dobry kod znaczy więcej niż tysiąc słów, ale czasami kawałek dokumentacji jest po prostu nieodzowny. Osobiście uważam, że w tym względzie liczy się prostota i zaprzęganie do pracy takich formatów jak .doc czy nawet .pdf jest niemal zawsze grubą przesadą. Jest o wiele łatwiej, jeśli dokument daje się edytować zwyczajnym edytorem tekstowym. Ale nawet [...]]]></description>
			<content:encoded><![CDATA[<p>Wprawdzie dobry kod znaczy więcej niż tysiąc słów, ale czasami kawałek dokumentacji jest po prostu nieodzowny. Osobiście uważam, że w tym względzie liczy się prostota i zaprzęganie do pracy takich formatów jak <em>.doc</em> czy nawet <em>.pdf</em> jest niemal zawsze grubą przesadą. Jest o wiele łatwiej, jeśli dokument daje się edytować zwyczajnym edytorem tekstowym.</p>
<p>Ale nawet wśród czysto tekstowych formatów występuje całkiem spora różnorodność. Mamy chociażby kilka opartych na XML-u - takich jak <a href="http://en.wikipedia.org/wiki/DocBook">DocBook</a> - że nie wspominając o nieśmiertelnym <img src="http://xion.org.pl/wp-content/ql-cache/quicklatex.com-852cf88d55d765155a5796ba4fc0bfad_l3.png" class="ql-img-inline-formula" alt="&#92;&#116;&#97;&#117;&#92;&#101;&#112;&#115;&#105;&#108;&#111;&#110;&#92;&#99;&#104;&#105;" title="Rendered by QuickLaTeX.com" style="vertical-align: -3px;"/>-u. Te i im podobne są <strong>językami znacznikowymi</strong> (<em>markup languages</em>) i poza sporymi możliwościami mają jedną wadę: są rozwlekłe. Stosunek "sygnału do szumu" nie jest w nich specjalnie wysoki, przez co w swojej surowej formie są one trudniejsze w czytaniu - a więc i w edycji.</p>
<p>Tej w wady są w dużym stopniu pozbawione formaty w stylu wiki, przypominające trochę różne spontaniczne pomysły na formatowanie czystego tekstu spacjami, myślnikami i gwiazdkami. Czasami nie mają one często zaawansowanych możliwości pozwalających na przykład na wstawianie tabel, ale w zakresie oferowanej funkcjonalności są zaskakująco często wystarczające. Z pewnością wystarczają chociażby do postów na forach czy <em>ticketów</em> w systemach do śledzenia błędów.</p>
<p>Jest tylko pewien szkopuł: jest ich <strong>mnóstwo</strong>. Poza kilkoma wariantami składni wiki, mamy też takie wynalazki jak <a href="http://daringfireball.net/projects/markdown/">Markdown</a> albo <a href="http://docutils.sourceforge.net/rst.html">reStructuredText</a>. W sumie jednak stanowią one tylko część <a href="http://en.wikipedia.org/wiki/Lightweight_markup_language">tych co bardziej znanych</a>. Sytuacja przypomina tu trochę <a href="http://xkcd.com/927/">pewien szczególny komiks z <em>xkcd</em></a>. Skutkiem tego jest często konieczność sprawdzania, jakiej to składni używa akurat ta konkretna strona, na której piszemy post lub komentarz, jeśli tylko nie robimy tego regularnie.</p>
<p>Na szczęście przyswojenie sobie nowej składni tego rodzaju nie jest przeraźliwie wyczerpującym wysiłkiem umysłowym ;-) Niekiedy sprawę upraszcza też fakt wspierania przez dany serwis więcej niż jednego standardu - tak robi na przykład <a href="https://github.com/github/markup/blob/master/README.md">GitHub</a>. I dlatego nawet istnienie kilkunastu podobnych formatów nie wydaje się być jakimś szczególnie wielkim problemem.<br />
Porównajmy to chociażby z hipotetyczną sytuacją, gdy w użyciu jest kilka formatów podobnie rozbudowanych i skomplikowanych co XML... Brr :)</p>
]]></content:encoded>
			<wfw:commentRss>http://xion.org.pl/2011/09/02/proste-formaty-tekstowe/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Automatyzacja językami programowania</title>
		<link>http://xion.org.pl/2011/07/28/automatyzacja-jezykami-programowania/</link>
		<comments>http://xion.org.pl/2011/07/28/automatyzacja-jezykami-programowania/#comments</comments>
		<pubDate>Thu, 28 Jul 2011 19:11:48 +0000</pubDate>
		<dc:creator>Xion</dc:creator>
				<category><![CDATA[Applications]]></category>
		<category><![CDATA[Programming]]></category>
		<category><![CDATA[automation]]></category>
		<category><![CDATA[bash]]></category>
		<category><![CDATA[PowerShell]]></category>
		<category><![CDATA[Python]]></category>
		<category><![CDATA[scripting languages]]></category>

		<guid isPermaLink="false">http://xion.org.pl/?p=2844</guid>
		<description><![CDATA[Zwykłego użytkownika od power usera dobrze odróżnia sposób radzenia sobie z powtarzalnymi zadaniami. Perspektywa zmiany nazwy N plików, skonwertowania N obrazków czy skatalogowania N utworów muzycznych jest odstręczająca już dla niewielkich wartości N, jeśli mielibyśmy wykonywać te czynności ręcznie. Zaawansowany użytkownik w tym celu zakasze jednak rękawy i wysmaży odpowiedni skrypt, który może nie będzie [...]]]></description>
			<content:encoded><![CDATA[<p>Zwykłego użytkownika od <em>power usera</em> dobrze odróżnia sposób radzenia sobie z powtarzalnymi zadaniami. Perspektywa zmiany nazwy <em>N</em> plików, skonwertowania <em>N</em> obrazków czy skatalogowania <em>N</em> utworów muzycznych jest odstręczająca już dla niewielkich wartości <em>N</em>, jeśli mielibyśmy wykonywać te czynności ręcznie. Zaawansowany użytkownik w tym celu zakasze jednak rękawy i wysmaży odpowiedni skrypt, który może nie będzie działał od razu, ale za to w końcu poradzi sobie z zadaniem całkowicie automatycznie. Niekoniecznie musi to w sumie zająć mniej czasu niż procedura ręczna, ale na pewno będzie mniej męczące :)</p>
<p><img style="float:right; margin:5px" src="http://xion.org.pl/wp-content/uploads/2011/07/automation-scripts.png" alt=""/>Dlatego też niemal zawsze staram się wybierać programową automatyzację. Wiąże się z tym jednak pewien problem. Otóż języki powłok systemowych (<em>shelli</em>) to nie jest coś, z czym koder ma intensywny kontakt na co dzień. Należą one raczej do obszaru zainteresowań administratorów. W związku z tym wyprodukowanie jakiegoś działającego kawałka skryptu jest często poprzedzone co najmniej krótkim przypominaniem sobie składni i semantyki danego języka. Zasadniczo jest to strata czasu lub - wyrażając się nieco inaczej - czynnik zwiększający minimalną wartość <em>N</em>, od której automatyzacja ma sens.</p>
<p>Ale jeśli nie języki <em>shellowe</em>, to co? Ano to, czego używamy na co dzień, czyli zwykłe języki programowania. Tu niestety nie ma sprawiedliwości: niektóre z nich nadają się do zadania nieporównywalnie lepiej niż inne. Część tych drugich ma swoje interpretowane, skryptowe wersje; przykładem jest choćby javowy <a href="http://www.beanshell.org/">BeanShell</a>. Ich odpowiedniość do wersji pełnych nie jest jednak wcale zapewniona. Inne języki zwyczajnie nie mają podobnych narzędzi i zostawiają nas z koniecznością wyprodukowania kompletnego programu.<br />
Tutaj ujawnia się przewaga Perla, Pythona, Ruby'ego i podobnych im języków interpretowanych, które nie wymagają do uruchomienia niczego poza plikiem z "czystym" kodem.  Jest to dokładnie taka sama sytuacja, jak w przypadku <em>basha</em> czy innych języków powłoki. Korzyść jest jednak oczywista, jeśli tylko któryś z tych języków jest nam znany: nie ma tu bariery składniowej.</p>
<p>Nie znaczy to oczywiście, że jeśli ktoś potrafi jednym zaklęciem złożonym z <code>ls</code>, <code>xargs</code> i <code>grep</code>a przetworzyć tysiąc plików tekstowych, to powinien porzucić tę sztukę i zwrócić się ku Prawdziwemu Programowaniu&trade;. Zapewne też dobry programista będzie potrafił w końcu wyprodukować ową magiczną formułę, pod warunkiem spędzenia odpowiednio długiego czasu nad stronami <em>mana</em>. Jeśli jednak alternatywą jest napisanie kilkunastu linijek w znanym sobie języku, które zrobią to samo, będą miały spore szanse działać za pierwszym razem i zajmą w sumie co najwyżej kilka minut... to czemu nie? Warto korzystać ze swoich umiejętności nie tylko w ich ściśle ograniczonym obszarze zastosowań.</p>
<p>A jeśli przypadkiem ktoś właśnie zechciał akurat nauczyć się któregoś z wymienionych ze mnie języków, to... tak, polecam Pythona :)</p>
]]></content:encoded>
			<wfw:commentRss>http://xion.org.pl/2011/07/28/automatyzacja-jezykami-programowania/feed/</wfw:commentRss>
		<slash:comments>10</slash:comments>
		</item>
		<item>
		<title>Terminologia rozproszonych systemów kontroli wersji</title>
		<link>http://xion.org.pl/2011/06/06/terminologia-rozproszonych-systemow-kontroli-wersji/</link>
		<comments>http://xion.org.pl/2011/06/06/terminologia-rozproszonych-systemow-kontroli-wersji/#comments</comments>
		<pubDate>Mon, 06 Jun 2011 17:31:37 +0000</pubDate>
		<dc:creator>Xion</dc:creator>
				<category><![CDATA[Applications]]></category>
		<category><![CDATA[Programming]]></category>
		<category><![CDATA[Git]]></category>
		<category><![CDATA[Mercurial]]></category>
		<category><![CDATA[version control systems]]></category>

		<guid isPermaLink="false">http://xion.org.pl/?p=2716</guid>
		<description><![CDATA[W ostatnich latach rozproszone systemy kontroli wersji (w skrócie DVCS) stały się popularne, zwłaszcza w środowiskach związanych z open source. Warto je jednak znać nie tylko wtedy, gdy pracujemy nad projektami z otwartym źródłem. Jak bowiem pisałem wcześniej, mogą być one przydatne chociażby do małych jednoosobowych projektów. Ponadto bywają nierzadko używane w większych oraz mniejszych [...]]]></description>
			<content:encoded><![CDATA[<p><img style="float:right; margin:5px" src="http://xion.org.pl/wp-content/uploads/2011/06/sync-icon.png" alt="" />W ostatnich latach rozproszone systemy kontroli wersji (w skrócie <abbr title="Distributed Version Control Systems">DVCS</abbr>) stały się popularne, zwłaszcza w środowiskach związanych z <em>open source</em>. Warto je jednak znać nie tylko wtedy, gdy pracujemy nad projektami z otwartym źródłem. Jak bowiem <a href="http://xion.org.pl/2010/10/20/rozproszone-systemy-kontroli-wersji/">pisałem wcześniej</a>, mogą być one przydatne chociażby do małych jednoosobowych projektów. Ponadto bywają nierzadko używane w większych oraz mniejszych firmach. Ogólnie mamy więc duże szanse, aby prędzej lub później zetknąć się z takimi systemami.<br />
Ten post jest adresowany przede wszystkim do osób, które nie miały wcześniej dłuższej styczności rozproszonymi systemami kontroli wersji. Ma on na celu wyjaśnienie wielu spośród tych tajemniczo brzmiących słówek, na jakie nieustannie można się natknąć, gdy pracujemy z DVCS-ami. Istnieje oczywiście szansa, że bardziej zaawansowani użytkownicy również wyciągną nowe wiadomości z lektury (albo chociaż przejrzenia) niniejszej notki. A jeśli nawet nie, to powtórzenie znanej sobie wiedzy na pewno im nie zaszkodzi ;)<br />
<span id="more-2716"></span><br />
Dobrym pojęciem na początek - bo prostym - jest <strong>repozytorium</strong>, czyli miejsce składowania wszystkich wersji wszystkich plików źródłowych naszego projektu. Ponieważ zawartości repozytorium zwykle nie edytuje się bezpośrednio, do pracy nad projektem wykorzystujemy <strong>kopię roboczą</strong> (<em>working copy</em>): lustrzane odbicie którejś z jego wersji (zwykle najnowszej), będące zwykłym zbiorem plików i katalogów. Do nich właśnie wprowadzamy zmiany, które potem ewentualnie będziemy chcieli zachować.<br />
Zapisywanie zmian w repozytorium odbywa się operacją <strong><em>commit</em></strong>, dla której nie ma żadnego dobrego polskiego odpowiednika. Po jej zakończeniu powstaje w repozytorium nowa wersja projektu, a nasza kopia robocza staje się tym samym jej odbiciem. Możliwa jest też operacja odwrotna, gdy to z repozytorium pozyskujemy kopię roboczą, czyli wykonujemy <strong>uaktualnienie</strong> (<em>update</em> lub <em>checkout</em>). Dzieje się tak zwykle wtedy, gdy chcemy dalej edytować wersję utworzoną ("<em>zcommitowaną</em>") przez kogoś innego,</p>
<p>Powyższe pojęcia (<em>commit</em>, <em>update</em>, itd.) występują w każdym systemie kontroli wersji, niekoniecznie rozproszonym. Jeśli jednak mówimy o systemach zdecentralizowanych - takich jak Git czy Mercurial - to pojawia się też kilka nowych terminów związanych z interakcją <strong>między repozytoriami</strong>. Trzeba powiem pamiętać, że istotą takich systemów jest właśnie fakt, że w grę wchodzi w nich wiele repozytoriów naraz; typowo na przykład każdy programista ma swoje własne, lokalne. Stąd też potrzebne są sposoby na wymianę danych (czyli wersji) między nimi.<br />
Odbywa się to za pomocą operacji <strong>synchronizacji zmian</strong> między dwoma repozytoriami. Jest ona właściwie symetryczna, ale zwykle wyróżnia się dwa jej aspekty, zależne od punktu... ekhm... siedzenia :) Możemy mianowicie wprowadzać zmiany zapisane w "naszym" (np. lokalnym) repozytorium do innego (np. zdalnego). Taki efekt wywołuje użycie komendy <strong><kbd>push</kbd></strong> ("pchaj") i właśnie pod tym mianem znany jest ten koniec procesu synchronizacji. Z drugiej strony możliwe jest pobranie zmian z innego repozytorium i wprowadzenie do naszego - używa się wtedy polecenia <strong><kbd>pull</kbd></strong> ("ciągnij") lub <strong><kbd>fetch</kbd></strong> ("weź"). Dlaczego terminologia tych operacji kojarzy się raczej z próbą wydostania samochodu zakopanego w śniegu - to pewnie pozostanie tajemnicą twórcą DVCS-ów ;]</p>
<p>Po synchronizacji może okazać się, że w repozytorium powstały nam dodatkowe <strong>gałęzie</strong> (<em>branches</em>), czyli osobne ścieżki wprowadzania zmian do projektu. W przeciwieństwie np. do SVN-a, systemy rozproszone mają wbudowane wsparcie dla rozgałęziania procesu tworzenia, więc nie będzie to w żaden sposób sytuacją nadzwyczajną. Jeśli jednak rozgałęzienie nie było celowe, wtedy typowym wyjściem jest <strong>złączenie</strong> (<em>merge</em>) dwóch ścieżek z powrotem w jedną. Po tej operacji - do której wlicza się rozwiązanie ewentualnych konfliktów - liczbą gałęzi zmniejsza się o jeden, a czynność łączenia rejestrowana jest jako osobny <em>commit</em>.</p>
<p>Kończąc to krótkie wprowadzenie/powtórzenie warto jeszcze wspomnieć o... początku, czyli pozyskaniu własnego repozytorium, aby móc dołączyć się do całej tej rozproszonej zabawy. Jeśli sami zaczynamy projekt, to możemy utworzyć je jako puste (poleceniem <kbd>init</kbd> w katalogu projektu) i wypełnić pierwszym <em>commitem</em>.<br />
Częściej jednak będziemy <strong>klonowali</strong> (<em>clone</em>) już istniejące repozytorium, tworząc jego własną (lokalną) kopię. Będzie ona identyczna, zawierać będzie pełną kopię projektu wraz z całą historią zmian i pozwoli tym samym na wprowadzanie (i testowanie!) własnych modyfikacji. Właśnie ta własność rozproszonych systemów kontroli wersji sprawia zresztą, że są one tak popularne w projektach z otwartym źródłem.</p>
<p>Jeśli chcemy dowiedzieć się więcej o wspomnianych tutaj operacjach, pojęciach, działaniu DVCS-ów i pracy z nimi, to polecam którąś z dwóch poniższych książek (dostępnym za darmo <em>online</em>), w zależności od systemu, który nas interesuje:</p>
<ul>
<li><a href="http://hgbook.red-bean.com/"><em>Mercurial: The Definitive Guide</em></a></li>
<li><a href="http://book.git-scm.com/"><em>Git Community Book</em></a></li>
</ul>
]]></content:encoded>
			<wfw:commentRss>http://xion.org.pl/2011/06/06/terminologia-rozproszonych-systemow-kontroli-wersji/feed/</wfw:commentRss>
		<slash:comments>3</slash:comments>
		</item>
		<item>
		<title>Proste gesty dotykowe</title>
		<link>http://xion.org.pl/2011/04/20/proste-gesty-dotykowe/</link>
		<comments>http://xion.org.pl/2011/04/20/proste-gesty-dotykowe/#comments</comments>
		<pubDate>Wed, 20 Apr 2011 17:38:57 +0000</pubDate>
		<dc:creator>Xion</dc:creator>
				<category><![CDATA[Applications]]></category>
		<category><![CDATA[Programming]]></category>
		<category><![CDATA[gestures]]></category>
		<category><![CDATA[mobile apps]]></category>
		<category><![CDATA[touchscreen]]></category>

		<guid isPermaLink="false">http://xion.org.pl/?p=2580</guid>
		<description><![CDATA[Urządzenia, w których jedyną lub główną metodą interakcji jest ekran dotykowy prezentują interesują wyzwanie w zakresie sterowania i interfejsu użytkownika. Naiwne w rozwiązania zwykle sprawdzają się słabo, czego przykładem może być wydzielenie części ekranu na przyciski kontrolne. Brak skoku oraz fizycznych krawędzi klawiszy sprawia, że stosunkowo łatwo tutaj o pomyłkę i niezamierzone wciśnięcie błędnego klawisza. [...]]]></description>
			<content:encoded><![CDATA[<p>Urządzenia, w których jedyną lub główną metodą interakcji jest ekran dotykowy prezentują interesują wyzwanie w zakresie sterowania i interfejsu użytkownika. Naiwne w rozwiązania zwykle sprawdzają się słabo, czego przykładem może być wydzielenie części ekranu na przyciski kontrolne. Brak skoku oraz fizycznych krawędzi klawiszy sprawia, że stosunkowo łatwo tutaj o pomyłkę i niezamierzone wciśnięcie błędnego klawisza.<br />
Dlatego też ta forma komunikacji użytkownika z urządzeniem wymaga nieco innego podejścia, które wykorzystuje jego mocne punkty i pozwala jakoś żyć z jego słabymi stronami. Można na przykład zauważyć, że palec użytkownika jeżdżący po ekranie (pozwolę sobie pominąć tutaj <em>multitouch</em> :)) przypomina pod wieloma względami kursor myszki i często można z powodzeniem traktować go jako taki. Podstawową różnicą jest brak wykrywalnego ruchu między miejscami interesującymi użytkownika, a co za tym idzie brak również zdarzeń typu <em>hover</em> (<em>mouseover</em>), służących często do wyświetlania podpowiedzi.</p>
<div style="float:right; margin:5px; text-align:center"><img style="margin-bottom:4px" src="http://xion.org.pl/wp-content/uploads/2011/04/tap.png" /><br/><small>Jak się tapuje :) (<a href="http://www.microsoft.com/windowsphone/en-us/howto/wp7/start/gestures-flick-pan-and-stretch.aspx">Źródło</a>)</small></div>
<p>Jest więc podobnie, ale inaczej :) Ponieważ nie mażemy palcem po ekranie przez cały czas, interakcja użytkownika z urządzeniem przebiega wyłącznie za pośrednictwem zamierzonych <strong>gestów</strong>. Częściowo przypominają one kliknięcia lub przeciąganie wykonywane jednoprzyciskową myszą, ale ich wachlarz jest nieco szerszy. Wśród nich mamy bowiem takie gesty jak:</p>
<ul>
<li><em>Tap</em>, czyli po polsku 'tapnięcie' ;-) Jest to krótkie naciśnięcie (albo wręcz puknięcie) ekranu. To najkrótszy i prawdopodobnie najprostszy gest (chociaż słyszałem też opinie wprost przeciwne), który służy standardowo do wyboru wskazanego elementu. W ten sposób uruchamia się aplikacje lub przechodzi do stron wskazywanych przez linki. Gest ten jest więc funkcjonalnym odpowiednikiem pojedynczego lub podwójnego kliknięcia w przypadku zwykłej myszki.</li>
<li><em>Long press</em>, czyli dłuższe wciśnięcie. Polega ono na naciśnięciu ekranu i przytrzymaniu palca w jednym miejscu, zwykle około sekundę. Taki gest często daje dostęp do drugorzędnej akcji związanej z wciskanym elementem, a czasami po prostu otwiera menu zawierające większą liczbę opcji. Przybliżonym odpowiednikiem <em>long pressa</em> w przypadku myszki jest więc kliknięcie prawym przyciskiem.</li>
<li><em>Double tap</em>, czyli podwójne tapnięcie. Oznacza to wykonanie dwóch <em>tapów</em> w krótkim odstępie czasu i przestrzeni (na ekranie). Chociaż wydaje się to podobne do dwukrotnego kliknięcia, analogia jest raczej błędna. Podwójny <em>tap</em> wykorzystywany więc bowiem stosunkowo rzadko i raczej tylko w dość specjalnych przypadkach. Jednym z powodów jest fakt, że obsługa tego gestu opóźniałaby każdy zwykły (pojedynczy) <em>tap</em>, gdyż użytkownik potrzebowałby okienka czasowego na "zdecydowanie się" na ewentualne drugie tapnięcie.<br />
Dlatego też często stosowaną strategią jest obsługa <em>double tapu</em> tylko w obrębie przestrzeni między interaktywnymi elementami. Wtedy gest ten służy do przełączania między widokiem zwykłym a przybliżonym/powiększonym - czyli po prostu do <strong>zoomowania</strong>.</li>
<li><em>Swipe</em> lub <em>fling</em>, czyli przeciąganie. Podobnie jak w <em>long pressie</em> tu też wciskamy ekran na dłużej, ale tym razem przeciągamy palec w inne miejsce bez jego odrywania. Ten gest w rzeczywistości tysiąc razy prostszy niż nawet ten jednozdaniowy opis i niezwykle intuicyjny, więc używa się go w bardzo wielu miejscach. Obejmuje to: przechodzenie do następnego/poprzedniego elementu, przewijanie długich list, przeciąganie elementów w stylu <em>drag &#038; drop</em> i pewnie jeszcze sporo innych zastosowań. Łatwo więc zauważyć, że odpowiednikiem dla zwykłej myszki może tu być zarówno standardowe przeciąganie z wciśniętym przyciskiem, jak i kręcenie rolką.</li>
</ul>
<p>Jak widać, istnieją pewnie nieformalne standardy obsługi poszczególnych gestów w taki sposób, aby interfejs użytkownika był w miarę spójny. Zdaje mi się jednak, że ekrany dotykowe - mimo postulowanej intuicyjności - wciąż mogą niedoświadczonym użytkownikom wydawać się nieco zagadkowe w obsłudze. Spójna obsługa powyższych gestów w aplikacjach pomogłaby oczywiście w eliminacji tego problemu.</p>
]]></content:encoded>
			<wfw:commentRss>http://xion.org.pl/2011/04/20/proste-gesty-dotykowe/feed/</wfw:commentRss>
		<slash:comments>2</slash:comments>
		</item>
		<item>
		<title>Przenośne aplikacje mobilne</title>
		<link>http://xion.org.pl/2011/04/05/przenosne-aplikacje-mobilne/</link>
		<comments>http://xion.org.pl/2011/04/05/przenosne-aplikacje-mobilne/#comments</comments>
		<pubDate>Tue, 05 Apr 2011 20:07:39 +0000</pubDate>
		<dc:creator>Xion</dc:creator>
				<category><![CDATA[Applications]]></category>
		<category><![CDATA[Internet]]></category>
		<category><![CDATA[Programming]]></category>
		<category><![CDATA[Android]]></category>
		<category><![CDATA[iOS]]></category>
		<category><![CDATA[jQuery]]></category>
		<category><![CDATA[Windows Phone]]></category>

		<guid isPermaLink="false">http://xion.org.pl/?p=2539</guid>
		<description><![CDATA[Odkryłem niedawno bardzo ciekawy projekt o nazwie jQuery Mobile. Jego założeniem jest uproszczenie procesu tworzenia aplikacji na różne platformy mobilne poprzez dostarczenie odpowiednio przenośnego frameworka webowego. Powstałe przy jego pomocy "aplikacje" (a tak naprawdę odpowiednio spreparowane strony) mają wyglądać i działać tak samo na większości przenośnych urządzeń takich jak smartphone'y i tablety. Całkiem interesujące, prawda? [...]]]></description>
			<content:encoded><![CDATA[<p><img style="float:left; margin:5px" src="http://xion.org.pl/wp-content/uploads/2011/04/jqm-logo.png" alt="" title="jQuery Mobile" />Odkryłem niedawno bardzo ciekawy projekt o nazwie <a href="http://jquerymobile.com/">jQuery Mobile</a>. Jego założeniem jest uproszczenie procesu tworzenia aplikacji na różne platformy mobilne poprzez dostarczenie odpowiednio przenośnego <em>frameworka</em> webowego. Powstałe przy jego pomocy "aplikacje" (a tak naprawdę odpowiednio spreparowane strony) mają wyglądać i działać tak samo na większości przenośnych urządzeń takich jak <em>smartphone</em>'y i tablety.</p>
<p>Całkiem interesujące, prawda? Jeszcze ciekawsze jest to, że mimo bycia wciąż w stadium <em>alpha</em> (wersję <em>alpha 4</em> wydano parę dni temu) całość działa już bardzo dobrze i rzeczywiście spełnia większość swoich obietnic. Oczywiście nie każdemu może uśmiechać się "programowanie w HTML" (;D), ale tutaj jest ono dość ładnie zorganizowane w warstwę interfejsu (odpowiednio spreparowane tagi HTML) i logiki (kod JavaScript wykorzystujący <a href="http://jquery.com">jQuery</a>). Ta pierwsza pozwala między innymi na umieszczanie kilku stron w jednym pliku i efektowne przełączanie miedzy nimi:</p>
<div class="syntax_hilite">
<div id="html-18">
<div class="html"><span style="color: #009900;"><a href="http://december.com/html/4/element/div.html"><span style="color: #000000; font-weight: bold;">&lt;div</span></a> data-role=<span style="color: #ff0000;">"page"</span> <span style="color: #000066;">id</span>=<span style="color: #ff0000;">"menu"</span><span style="color: #000000; font-weight: bold;">&gt;</span></a></span><br />
&nbsp; &nbsp; <span style="color: #009900;"><a href="http://december.com/html/4/element/div.html"><span style="color: #000000; font-weight: bold;">&lt;div</span></a> data-role=<span style="color: #ff0000;">"content"</span><span style="color: #000000; font-weight: bold;">&gt;</span></a></span><br />
&nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #009900;"><a href="http://december.com/html/4/element/ul.html"><span style="color: #000000; font-weight: bold;">&lt;ul</span></a> data-role=<span style="color: #ff0000;">"listview"</span><span style="color: #000000; font-weight: bold;">&gt;</span></a></span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #009900;"><a href="http://december.com/html/4/element/li.html"><span style="color: #000000; font-weight: bold;">&lt;li&gt;</span></a></span><span style="color: #009900;"><a href="http://december.com/html/4/element/a.html"><span style="color: #000000; font-weight: bold;">&lt;a</span></a> <span style="color: #000066;">href</span>=<span style="color: #ff0000;">"#one"</span><span style="color: #000000; font-weight: bold;">&gt;</span></a></span>One<span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;/a&gt;</span></span><span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;/li&gt;</span></span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #009900;"><a href="http://december.com/html/4/element/li.html"><span style="color: #000000; font-weight: bold;">&lt;li&gt;</span></a></span><span style="color: #009900;"><a href="http://december.com/html/4/element/a.html"><span style="color: #000000; font-weight: bold;">&lt;a</span></a> <span style="color: #000066;">href</span>=<span style="color: #ff0000;">"#two"</span><span style="color: #000000; font-weight: bold;">&gt;</span></a></span>Two<span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;/a&gt;</span></span><span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;/li&gt;</span></span><br />
&nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;/ul&gt;</span></span><br />
&nbsp; &nbsp; <span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;/div&gt;</span></span><br />
<span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;/div&gt;</span></span><br />
<span style="color: #009900;"><a href="http://december.com/html/4/element/div.html"><span style="color: #000000; font-weight: bold;">&lt;div</span></a> data-role=<span style="color: #ff0000;">"page"</span> <span style="color: #000066;">id</span>=<span style="color: #ff0000;">"one"</span><span style="color: #000000; font-weight: bold;">&gt;</span></a></span><br />
...<br />
<span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;/div&gt;</span></span><br />
<span style="color: #009900;"><a href="http://december.com/html/4/element/div.html"><span style="color: #000000; font-weight: bold;">&lt;div</span></a> data-role=<span style="color: #ff0000;">"page"</span> <span style="color: #000066;">id</span>=<span style="color: #ff0000;">"two"</span><span style="color: #000000; font-weight: bold;">&gt;</span></a></span><br />
...<br />
<span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;/div&gt;</span></span></div>
</div>
</div>
<p>
Przejścia pomiędzy stronami nieźle imitują natywny UI platform mobilnych, gdyż są zrealizowane przy pomocy <em>javascriptowych</em> animacji zaimplementowanych w jQuery. Co więcej, jak widać powyżej odnośniki mogą być zwykłymi linkami (<code>&lt;a&gt;</code>). Czego zaś nie widać to to, że przy okazji przechodzenia między stronami historia przeglądarki - a więc chociażby przyciski <em>Wstecz</em> i <em>Dalej</em> - działa zgodnie z przewidywaniami i "nie psuje" zachowania aplikacji.<br />
<img style="float:right; margin:5px" src="http://xion.org.pl/wp-content/uploads/2011/04/jqm-sample.png" alt="" />Naturalnie samo przełączanie stron to nie wszystko, bo wypadałoby przecież coś na nich pokazać :) Tutaj jQuery Mobile też prezentuje się dobrze, bo niejako automagicznie dba o odpowiedni wygląd elementów aplikacji poprzez stosowanie wbudowanego zestawu "mobilnych" stylów CSS. Zmieniają one wygląd tekstu, linków oraz pól formularzy na taki, który dobrze udaje kontrolki natywnego interfejsu. No, a przynajmniej może uchodzić za takowy w przypadku urządzeń pracujących pod kontrolą iOS-a, bo właśnie do interfejsu tego systemu aplikacje jQuery Mobile są najbardziej podobne.</p>
<p>Niemniej także na innych platformach (chociażby Androidzie) rezultat zastosowania tego <em>frameworka</em> jest więcej niż zadowalający. Wydaje mi się aczkolwiek, że podobne rozwiązania chwilowo wyprzedzają jeszcze trochę swój czas. Ich podstawowym mankamentem jest brak sensownych dojść z przeglądarki internetowej do większości ciekawych podsystemów urządzeń mobilnych, takich chociażby jak kamera; póki co dostępne są chyba tylko usługi lokalizacyjne. Nie da się więc w ten sposób tworzyć skomplikowanych aplikacji, korzystających ze sprzętu czy bardziej zaawansowanych funkcjonalności systemu.<br />
Jeśli jednak chodzi o proste rozwiązania oparte na tekście, obrazkach i formularzach - a więc jako szeroko pojęte <em>front-endy</em> do zdalnych repozytoriów z danymi - to jQuery Mobile może być dobrą alternatywą dla mozolnego portowania aplikacji między różnymi platformami. Podobnie zresztą rzecz ma się z mobilnymi wersjami zwykłych stron internetowych.</p>
]]></content:encoded>
			<wfw:commentRss>http://xion.org.pl/2011/04/05/przenosne-aplikacje-mobilne/feed/</wfw:commentRss>
		<slash:comments>8</slash:comments>
		</item>
		<item>
		<title>Bo konsola to też okno</title>
		<link>http://xion.org.pl/2011/01/26/bo-konsola-to-tez-okno/</link>
		<comments>http://xion.org.pl/2011/01/26/bo-konsola-to-tez-okno/#comments</comments>
		<pubDate>Wed, 26 Jan 2011 08:48:03 +0000</pubDate>
		<dc:creator>Xion</dc:creator>
				<category><![CDATA[Applications]]></category>
		<category><![CDATA[console]]></category>
		<category><![CDATA[PowerShell]]></category>
		<category><![CDATA[Windows]]></category>

		<guid isPermaLink="false">http://xion.org.pl/?p=2393</guid>
		<description><![CDATA[Systemy uniksowe dość długo wyróżniały się znacznie lepszym wsparciem dla trybu wiersza poleceń niż Windows. To się w pewnym sensie zmieniło po powstaniu PowerShella, będącego co najmniej równie dobrą powłoką tekstową co bash czy zsh. Jednak przynajmniej w jednym aspekcie Linuksy wciąż mają tutaj wyraźną przewagę. Chodzi o graficzną otoczkę tekstowej konsoli. W Windows programy [...]]]></description>
			<content:encoded><![CDATA[<p>Systemy uniksowe dość długo wyróżniały się znacznie lepszym wsparciem dla trybu wiersza poleceń niż Windows. To się w pewnym sensie zmieniło po powstaniu <a href="http://technet.microsoft.com/pl-pl/scriptcenter/dd742419.aspx">PowerShella</a>, będącego co najmniej równie dobrą powłoką tekstową co <em>bash</em> czy <em>zsh</em>. Jednak przynajmniej w jednym aspekcie Linuksy wciąż mają tutaj wyraźną przewagę. Chodzi o graficzną otoczkę tekstowej konsoli.<br />
W Windows programy konsole uruchamiane są wciąż w starym, w gruncie rzeczy obleśnym i w dodatku bardzo słabo i trudno konfigurowalnym oknie. Nie da się płynnie zmienić jego rozmiaru, zmaksymalizować, nie wspominając już nawet o otwieraniu kilku konsol w zakładkach tego samego okna. Możliwość modyfikacji czcionki czy też kolorów tekstu i tła też jest ograniczona i niewygodna. Dla porównania, okienka konsoli w systemach linuksowych są pod tym względem o wiele elastyczniejsze, zapewniając wszystkie te <em>feature</em>'y i jeszcze sporo innych. W rezultacie interfejs tekstowy jest tam przyjemniejszy w obsłudze, nawet jeśli obiektywnie ustępuje możliwościami temu windowsowemu.</p>
<p><img style="float:right; margin:5px" src="http://xion.org.pl/wp-content/uploads/2011/01/console.png" alt="" title="Console2 (screen)" width="345" height="235" class="alignnone size-full wp-image-2401" />Czy da się coś na to poradzić, czyniąc windowsowe okienko konsoli bardziej znośnym?... Otóż można w pewnym - może nawet zadowalającym - stopniu to uczynić, lecz w tym celu trzeba się posłużyć zewnętrzną aplikacją. Chodzi mianowicie o <em>open-source</em>'owy projekt <a href="http://console.sourceforge.net/">Console2</a>, będący okienkowym środowiskiem uruchamiania programów konsolowych. Technicznie działa on zapewne w podobny sposób, jak mój <a href="http://xion.org.pl/2008/03/21/przekierowanie-standardowych-strumieni/">eksperyment sprzed prawie trzech lat</a>, z tym że oczywiście robi to znacznie lepiej :) W międzyczasie zapewnia też sporą część funkcjonalności okienek terminala pracujących w X-Window, a mianowicie:</p>
<ul>
<li>obsługę kilku zakładek z przełączaniem się między nimi za pomocą konfigurowalnych skrótów klawiszowych</li>
<li>wybór domyślnego <em>shella</em> (np. <code>cmd</code>, <code>cygwin</code> albo <code>powershell</code>), a także możliwość skonfigurowania kilku powłok uruchamianych automatycznie w osobnych zakładkach</li>
<li>zaawansowaną konfigurację wyglądu, aż do kształtu kursora włącznie</li>
<li>obsługę przezroczystości całego okna</li>
<li>zmianę jego rozmiaru poprzez przeciąganie za krawędź</li>
</ul>
<p>i jeszcze kilka innych, w gruncie rzeczy naturalnych funkcji, których w tajemniczy sposób zabrakło w standardowym oknie konsoli w Windows. Jeżeli chodzi o stabilność i szybkość działania, to również prezentuje się nie najgorzej, chociaż zdarzają się problemy, np. z przesłaniem sygnału <em>Ctrl+C</em> w celu przerwania spamującego polecenia w rodzaju <code>ls -r /</code>. Małą wadą jest też konfiguracja, która może zająć trochę czasu i kłopotów, jeśli umieścimy program w standardowy folderze <em>Program Files</em> (wskazówka: należy wtedy poinstruować go, by zapisywał ustawienia w katalogu użytkownika).<br />
Ogólnie jednak moje wrażenia co do tej aplikacji są w miarę pozytywne, lecz pamiętajmy, że rywal jest godny pożałowania ;) Tym niemniej polecam zapoznanie się z tym programem, jeśli dużo pracujemy z tekstowym <em>shellem</em> pod Windows.</p>
]]></content:encoded>
			<wfw:commentRss>http://xion.org.pl/2011/01/26/bo-konsola-to-tez-okno/feed/</wfw:commentRss>
		<slash:comments>7</slash:comments>
		</item>
		<item>
		<title>Nie tylko pisanie kodu</title>
		<link>http://xion.org.pl/2011/01/21/nie-tylko-pisanie-kodu/</link>
		<comments>http://xion.org.pl/2011/01/21/nie-tylko-pisanie-kodu/#comments</comments>
		<pubDate>Fri, 21 Jan 2011 18:25:55 +0000</pubDate>
		<dc:creator>Xion</dc:creator>
				<category><![CDATA[Applications]]></category>
		<category><![CDATA[Programming]]></category>
		<category><![CDATA[Thoughts]]></category>
		<category><![CDATA[compilation]]></category>
		<category><![CDATA[debugging]]></category>
		<category><![CDATA[version control systems]]></category>

		<guid isPermaLink="false">http://xion.org.pl/?p=2388</guid>
		<description><![CDATA[Gdyby było to fizycznie możliwe, chętnie przeprowadziłbym następujący eksperyment. Z odległej przeszłości - na przykład z połowy lat 90. poprzedniego stulecia - sprowadziłbym w obecne czasy dowolnego ponadprzeciętnie uzdolnionego programistę. Jak szybko odnalazłby się we współczesnym koderskim środowisku pracy?... W celu redukcji złożoności problemu poczyńmy daleko idące uproszczenia i pomińmy wszelkiego typu zmiany związane z [...]]]></description>
			<content:encoded><![CDATA[<p>Gdyby było to fizycznie możliwe, chętnie przeprowadziłbym następujący eksperyment. Z odległej przeszłości - na przykład z połowy lat 90. poprzedniego stulecia - sprowadziłbym w obecne czasy dowolnego ponadprzeciętnie uzdolnionego programistę. Jak szybko odnalazłby się we współczesnym koderskim środowisku pracy?... W celu redukcji złożoności problemu poczyńmy daleko idące uproszczenia i pomińmy wszelkiego typu zmiany związane z postępem technologicznym (jak choćby nieporównywalnie większe znaczenie Internetu wtedy i teraz), a także modyfikacje, które zachodzą w samych językach programowania. Interesuje mnie raczej to, czy ów przybysz z przeszłości doceniłby i uznał za przydatne różnego rodzaju czynności i narzędzia pomocnicze, niebędące edytorem tekstu (lub IDE) ani kompilatorem, i pozostające w luźniejszym związku z samym pisaniem kodu jako takiego.</p>
<p>Jakby bowiem przyjrzeć się dokładnie wachlarzowi tych narzędzi, okazuje się, że jest on już całkiem szeroki. Programowanie, zwłaszcza zespołowe (jeżeli w ogóle istnieje jeszcze jakieś inne) już od dawna przestało ograniczać do tworzenia kodu i czasami wydaje się nawet, że czynność ta stała się poboczną. Coraz więcej czasu zajmuje praca z takimi narzędziami jak systemy kontroli wersji, systemy śledzenia błędów (<em>issue tracking systems</em>), narzędzia automatyzujące proces kompilacji, programy do statycznej analizy kodu, systemy zdalnej kompilacji i pewnie mnóstwo jeszcze innych wynalazków, z którymi nie miałem dotąd okazji się zetknąć.<br />
Między innymi dlatego nie potrafię jednoznacznie określić, czy uważam je wszystkie raczej za przydatne czy raczej za zbędne. Wiążące opinie mogę jak dotąd wyrazić tylko o niektórych.</p>
<p>Tym niemniej ciekawi mnie również, czy w dziedzinie wspomagania kodowania (czy ogólnie pracy nad projektami) od strony zautomatyzowanych narzędzi da się wymyślić coś jeszcze...</p>
]]></content:encoded>
			<wfw:commentRss>http://xion.org.pl/2011/01/21/nie-tylko-pisanie-kodu/feed/</wfw:commentRss>
		<slash:comments>6</slash:comments>
		</item>
		<item>
		<title>Więcej pulpitów</title>
		<link>http://xion.org.pl/2010/12/09/wiecej-pulpitow/</link>
		<comments>http://xion.org.pl/2010/12/09/wiecej-pulpitow/#comments</comments>
		<pubDate>Thu, 09 Dec 2010 22:23:30 +0000</pubDate>
		<dc:creator>Xion</dc:creator>
				<category><![CDATA[Applications]]></category>
		<category><![CDATA[desktop]]></category>
		<category><![CDATA[Linux]]></category>
		<category><![CDATA[Windows]]></category>

		<guid isPermaLink="false">http://xion.org.pl/?p=2308</guid>
		<description><![CDATA[Pracując przez chwilę na Linuksie, odkryłem poważną zaletę jego interfejsu graficznego, którą Windows domyślnie nie może się pochwalić. Wirtualne pulpity, bo o nich mowa, to koncept, który w pierwszej chwili może wydawać się nieco dezorientujący. W końcu czasami ma się problem z ogarnięciem okien na jednym tylko pulpicie, więc co dopiero powiedzieć o - powiedzmy [...]]]></description>
			<content:encoded><![CDATA[<p>Pracując przez chwilę na Linuksie, odkryłem poważną zaletę jego interfejsu graficznego, którą Windows domyślnie nie może się pochwalić. Wirtualne pulpity, bo o nich mowa, to koncept, który w pierwszej chwili może wydawać się nieco dezorientujący. W końcu czasami ma się problem z ogarnięciem okien na jednym tylko pulpicie, więc co dopiero powiedzieć o - powiedzmy - czterech? :) Ale więcej miejsca na bałagan to także więcej miejsca na porządek i jeśli tylko potrafimy dobrze tę powiększoną przestrzeń zagospodarować, możemy znacznie zyskać na efektywności. Ograniczamy bowiem konieczność przełączania między programami za pomocą powolnych i niewygodnych metod, takich jaki klikanie w przyciski na pasku zadań czy pracowite przechodzenie po liście okien za pomocą przełącznika <em>Alt+Tab</em>.</p>
<p>To doprawdy wstyd, że Windows nie oferuje takiego mechanizmu wbudowanego w system. Jakby się jednak chwilę nad nim zastanowić, nie jest on żadnym rodzajem magii. Można go przynajmniej symulować za pomocą odpowiednio przemyślanego ukrywania i odkrywania okien na żądanie użytkownika, przechodzącego między kolejnymi "wirtualnymi &laquo;wirtualnymi pulpitami&raquo;". Zdaje się, że właśnie na takiej zasadzie działają programy, które uzupełniają system Windows o tę pożyteczną funkcjonalność.<br />
Rozwiązaniem wypróbowanym przeze mnie jest <a href="http://virtuawin.sourceforge.net/">VirtuaWin</a>. Jest to bardzo mała, ale całkiem zmyślna aplikacja. Bez widocznego narzutu na zasoby systemowe (kilka megabajtów w pamięci) wprowadza ona możliwość przełączania się między wirtualnymi pulpitami przy pomocy typowych kombinacji klawiszy (czyli <em>Ctrl+Alt+strzałki</em>). I to niemal dowolną liczbą wirtualnych pulpitów, do których można automatycznie przypisywać okna na podstawie ustalonych (bazujących np. na klasie okna lub jego tytule). Jedyne, czego tu brakuje, to ładna animacja przełączania zamiast znikających i pojawiających się okien... ale cóż, nie można mieć wszystkiego ;)</p>
<p>W każdym razie polecam przyjrzenie się możliwości powielenia swojego pulpitu nawet bez przyłączania dodatkowych ekranów. Opłaca się.</p>
]]></content:encoded>
			<wfw:commentRss>http://xion.org.pl/2010/12/09/wiecej-pulpitow/feed/</wfw:commentRss>
		<slash:comments>2</slash:comments>
		</item>
	</channel>
</rss>

