<?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:creativeCommons="http://backend.userland.com/creativeCommonsRssModule">

<channel>
	<title>Room 303</title>
	<atom:link href="http://room-303.com/blog/feed/" rel="self" type="application/rss+xml" />
	<link>http://room-303.com/blog</link>
	<description>Bug to the Feature</description>
	<lastBuildDate>Mon, 15 Mar 2010 20:12:56 +0000</lastBuildDate>
	<generator>http://wordpress.org/?v=2.9.2</generator>
	<language>en</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
	<creativeCommons:license>http://creativecommons.org/licenses/by-nc-sa/2.5/pl/</creativeCommons:license>		<item>
		<title>Django: TestCase i testowanie szablonów</title>
		<link>http://room-303.com/blog/2010/03/15/django-testcase-i-testowanie-szablonow/</link>
		<comments>http://room-303.com/blog/2010/03/15/django-testcase-i-testowanie-szablonow/#comments</comments>
		<pubDate>Mon, 15 Mar 2010 17:03:55 +0000</pubDate>
		<dc:creator>Patrys</dc:creator>
				<category><![CDATA[code]]></category>
		<category><![CDATA[web]]></category>
		<category><![CDATA[django]]></category>
		<category><![CDATA[python]]></category>

		<guid isPermaLink="false">http://room-303.com/blog/?p=851</guid>
		<description><![CDATA[Bardzo brzydki hack, oparty o załącznik do ticketu 7611. Czyści wewnętrzny cache Django, ale pozwala testować działanie kodu opierającego się o renderowanie szablonów bez ryzyka, że aplikacja owe szablony nadpisze:

import os
import sys
from django.conf import settings
from django.template import loader
from django.test import TestCase

class TemplateTestCase(TestCase):
    def _pre_setup(self):
        self._template_setup()
 [...]]]></description>
			<content:encoded><![CDATA[<p>Bardzo brzydki hack, oparty o <a href="http://code.djangoproject.com/attachment/ticket/7611/7611.diff">załącznik do ticketu 7611</a>. Czyści wewnętrzny cache Django, ale pozwala testować działanie kodu opierającego się o renderowanie szablonów bez ryzyka, że aplikacja owe szablony nadpisze:</p>
<div class="highlight">
<pre><span class="kn">import</span> <span class="nn">os</span>
<span class="kn">import</span> <span class="nn">sys</span>
<span class="kn">from</span> <span class="nn">django.conf</span> <span class="kn">import</span> <span class="n">settings</span>
<span class="kn">from</span> <span class="nn">django.template</span> <span class="kn">import</span> <span class="n">loader</span>
<span class="kn">from</span> <span class="nn">django.test</span> <span class="kn">import</span> <span class="n">TestCase</span>

<span class="k">class</span> <span class="nc">TemplateTestCase</span><span class="p">(</span><span class="n">TestCase</span><span class="p">):</span>
    <span class="k">def</span> <span class="nf">_pre_setup</span><span class="p">(</span><span class="bp">self</span><span class="p">):</span>
        <span class="bp">self</span><span class="o">.</span><span class="n">_template_setup</span><span class="p">()</span>
        <span class="nb">super</span><span class="p">(</span><span class="n">TestCase</span><span class="p">,</span> <span class="bp">self</span><span class="p">)</span><span class="o">.</span><span class="n">_pre_setup</span><span class="p">()</span>

    <span class="k">def</span> <span class="nf">_post_teardown</span><span class="p">(</span><span class="bp">self</span><span class="p">):</span>
        <span class="bp">self</span><span class="o">.</span><span class="n">_template_teardown</span><span class="p">()</span>
        <span class="nb">super</span><span class="p">(</span><span class="n">TestCase</span><span class="p">,</span> <span class="bp">self</span><span class="p">)</span><span class="o">.</span><span class="n">_post_teardown</span><span class="p">()</span>

    <span class="k">def</span> <span class="nf">_template_setup</span><span class="p">(</span><span class="bp">self</span><span class="p">):</span>
        <span class="k">if</span> <span class="nb">hasattr</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="s">&#39;template_loaders&#39;</span><span class="p">):</span>
            <span class="bp">self</span><span class="o">.</span><span class="n">_old_template_loaders</span> <span class="o">=</span> <span class="n">settings</span><span class="o">.</span><span class="n">TEMPLATE_LOADERS</span>
            <span class="n">settings</span><span class="o">.</span><span class="n">TEMPLATE_LOADERS</span> <span class="o">=</span> <span class="bp">self</span><span class="o">.</span><span class="n">template_loaders</span>
            <span class="n">loader</span><span class="o">.</span><span class="n">template_source_loaders</span> <span class="o">=</span> <span class="bp">None</span>
        <span class="k">if</span> <span class="nb">hasattr</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="s">&#39;template_dirs&#39;</span><span class="p">):</span>
            <span class="bp">self</span><span class="o">.</span><span class="n">_old_template_dirs</span> <span class="o">=</span> <span class="n">settings</span><span class="o">.</span><span class="n">TEMPLATE_DIRS</span>
            <span class="n">test_dir</span> <span class="o">=</span> <span class="n">os</span><span class="o">.</span><span class="n">path</span><span class="o">.</span><span class="n">dirname</span><span class="p">(</span><span class="n">sys</span><span class="o">.</span><span class="n">modules</span><span class="p">[</span><span class="bp">self</span><span class="o">.</span><span class="n">__module__</span><span class="p">]</span><span class="o">.</span><span class="n">__file__</span><span class="p">)</span>
            <span class="n">settings</span><span class="o">.</span><span class="n">TEMPLATE_DIRS</span> <span class="o">=</span> <span class="p">[</span> <span class="n">os</span><span class="o">.</span><span class="n">path</span><span class="o">.</span><span class="n">join</span><span class="p">(</span><span class="n">test_dir</span><span class="p">,</span> <span class="n">dirname</span><span class="p">)</span> <span class="k">for</span> <span class="n">dirname</span> <span class="ow">in</span> <span class="bp">self</span><span class="o">.</span><span class="n">template_dirs</span> <span class="p">]</span>

    <span class="k">def</span> <span class="nf">_template_teardown</span><span class="p">(</span><span class="bp">self</span><span class="p">):</span>
        <span class="k">if</span> <span class="nb">hasattr</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="s">&#39;_old_template_loaders&#39;</span><span class="p">):</span>
            <span class="n">settings</span><span class="o">.</span><span class="n">TEMPLATE_LOADERS</span> <span class="o">=</span> <span class="bp">self</span><span class="o">.</span><span class="n">_old_template_loaders</span>
            <span class="n">loader</span><span class="o">.</span><span class="n">template_source_loaders</span> <span class="o">=</span> <span class="bp">None</span>
        <span class="k">if</span> <span class="nb">hasattr</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="s">&#39;_old_template_dirs&#39;</span><span class="p">):</span>
            <span class="n">settings</span><span class="o">.</span><span class="n">TEMPLATE_DIRS</span> <span class="o">=</span> <span class="bp">self</span><span class="o">.</span><span class="n">_old_template_dirs</span>
</pre>
</div>
<p>Użycie:</p>
<div class="highlight">
<pre><span class="k">class</span> <span class="nc">TestSomething</span><span class="p">(</span><span class="n">TemplateTestCase</span><span class="p">):</span>
    <span class="n">template_loaders</span> <span class="o">=</span> <span class="p">(</span><span class="s">&#39;django.template.loaders.app_directories.load_template_source&#39;</span><span class="p">,)</span>

    <span class="k">def</span> <span class="nf">test_foo</span><span class="p">(</span><span class="bp">self</span><span class="p">):</span>
        <span class="k">pass</span>
</pre>
</div>
<p><small><a href="http://room-303.com/blog/2010/03/15/django-testcase-i-testowanie-szablonow/">Django: TestCase i testowanie szablonów</a> © <a href="http://room-303.com/blog/" rel="cc:attributionURL">Patryk Zawadzki</a>, <a rel="license" href="http://creativecommons.org/licenses/by-nc-sa/2.5/pl/">Creative Commons Attribution-NonCommercial-ShareAlike 2.5 Poland</a>.</small></p>]]></content:encoded>
			<wfw:commentRss>http://room-303.com/blog/2010/03/15/django-testcase-i-testowanie-szablonow/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Django: pluralize</title>
		<link>http://room-303.com/blog/2010/03/03/django-pluralize/</link>
		<comments>http://room-303.com/blog/2010/03/03/django-pluralize/#comments</comments>
		<pubDate>Wed, 03 Mar 2010 17:18:57 +0000</pubDate>
		<dc:creator>Patrys</dc:creator>
				<category><![CDATA[code]]></category>
		<category><![CDATA[web]]></category>
		<category><![CDATA[django]]></category>
		<category><![CDATA[gettext]]></category>
		<category><![CDATA[python]]></category>

		<guid isPermaLink="false">http://room-303.com/blog/?p=841</guid>
		<description><![CDATA[Najważniejszą rzeczą, jaką powinniście wiedzieć na temat filtra pluralize jest ta, żeby go nigdy nie używać. Nigdy. Jego istnienie wynika z lenistwa ludzi, którzy nigdy w życiu nie przygotowywali aplikacji do tłumaczenia. Jeśli nie wyraziłem się dość jasno, używanie filtra pluralize wywoła u ciebie raka, stereoporoże i zatwardzenie rozsiane.
Jakkolwiek sprytnie by nie wyglądał, ten kod [...]]]></description>
			<content:encoded><![CDATA[<p>Najważniejszą rzeczą, jaką powinniście wiedzieć na temat filtra <code>pluralize</code> jest ta, żeby go nigdy nie używać. <em>Nigdy</em>. Jego istnienie wynika z lenistwa ludzi, którzy nigdy w życiu nie przygotowywali aplikacji do tłumaczenia. Jeśli nie wyraziłem się dość jasno, używanie filtra <code>pluralize</code> wywoła u ciebie raka, stereoporoże i zatwardzenie rozsiane.</p>
<p>Jakkolwiek sprytnie by nie wyglądał, ten kod nie nadaje się do niczego:</p>
<div class="highlight">
<pre><span class="nt">&lt;p&gt;</span>
    There <span class="cp">{{</span> <span class="nv">item_count</span><span class="o">|</span><span class="nf">pluralize</span><span class="s2">:&quot;is,are&quot;</span> <span class="cp">}}</span>
    <span class="cp">{{</span> <span class="nv">item_count</span> <span class="cp">}}</span> thing<span class="cp">{{</span> <span class="nv">item_count</span><span class="o">|</span><span class="nf">pluralize</span><span class="s2">:&quot;s&quot;</span> <span class="cp">}}</span>.
<span class="nt">&lt;/p&gt;</span>
</pre>
</div>
<p>Dlaczego się nie nadaje? Spróbujcie go przetłumaczyć na kilka języków. Niektórzy chwytają się <a href="http://code.google.com/p/django-pluralize-pl/">brzydkich obejść</a>, inni wolą zrobić to zgodnie ze sztuką. Jeśli kiedykolwiek pracowaliście przy lokalizacji oprogramowania, doskonale wiecie, że tłumaczenie jednego słowa jest tak samo sensowne, jak tłumaczenie każdej litery z osobna.</p>
<p>Poprawna wersja jest przy okazji czytelna:</p>
<div class="highlight">
<pre><span class="nt">&lt;p&gt;</span>
<span class="cp">{%</span> <span class="k">blocktrans</span> <span class="nv">count</span> <span class="nv">item_count</span> <span class="k">as</span> <span class="nv">items</span> <span class="cp">%}</span>
    There is <span class="cp">{{</span> <span class="nv">items</span> <span class="cp">}}</span> thing.
<span class="cp">{%</span> <span class="k">plural</span> <span class="cp">%}</span>
    There are <span class="cp">{{</span> <span class="nv">items</span> <span class="cp">}}</span> things.
<span class="cp">{%</span> <span class="k">endblocktrans</span> <span class="cp">%}</span>
<span class="nt">&lt;/p&gt;</span>
</pre>
</div>
<p><code>{% blocktrans %}</code> z <code>{% plural %}</code> używają <code>ungettext</code>, dzięki czemu bez konieczności odprawiania czarów radzą sobie z polskimi liczebnikami (<q>jeden tysiąc, dwa tysiące, pięć tysięcy</q>).</p>
<p><small><a href="http://room-303.com/blog/2010/03/03/django-pluralize/">Django: pluralize</a> © <a href="http://room-303.com/blog/" rel="cc:attributionURL">Patryk Zawadzki</a>, <a rel="license" href="http://creativecommons.org/licenses/by-nc-sa/2.5/pl/">Creative Commons Attribution-NonCommercial-ShareAlike 2.5 Poland</a>.</small></p>]]></content:encoded>
			<wfw:commentRss>http://room-303.com/blog/2010/03/03/django-pluralize/feed/</wfw:commentRss>
		<slash:comments>2</slash:comments>
		</item>
		<item>
		<title>Python: alternatywa dla dict.update</title>
		<link>http://room-303.com/blog/2010/02/26/python-alternatywa-dla-dict-update/</link>
		<comments>http://room-303.com/blog/2010/02/26/python-alternatywa-dla-dict-update/#comments</comments>
		<pubDate>Fri, 26 Feb 2010 15:42:15 +0000</pubDate>
		<dc:creator>Patrys</dc:creator>
				<category><![CDATA[code]]></category>
		<category><![CDATA[python]]></category>

		<guid isPermaLink="false">http://room-303.com/blog/?p=835</guid>
		<description><![CDATA[Kolejny skrót. Dość regularny przypadek zwrócenia sumy słowników bez niszczenia któregokolwiek z nich:

def foo(bar, baz):
    tmpdict = dict(bar)
    tmpdict.update(baz)
    return tmpdict


Można również rozwiązać inaczej, korzystając z faktu, że dict akceptuje nazwane parametry:

def foo(bar, baz):
    return dict(bar, **baz)


Korzystając ze skrótów zawsze upewnij się, że [...]]]></description>
			<content:encoded><![CDATA[<p>Kolejny skrót. Dość regularny przypadek zwrócenia sumy słowników bez niszczenia któregokolwiek z nich:</p>
<div class="highlight">
<pre><span class="k">def</span> <span class="nf">foo</span><span class="p">(</span><span class="n">bar</span><span class="p">,</span> <span class="n">baz</span><span class="p">):</span>
    <span class="n">tmpdict</span> <span class="o">=</span> <span class="nb">dict</span><span class="p">(</span><span class="n">bar</span><span class="p">)</span>
    <span class="n">tmpdict</span><span class="o">.</span><span class="n">update</span><span class="p">(</span><span class="n">baz</span><span class="p">)</span>
    <span class="k">return</span> <span class="n">tmpdict</span>
</pre>
</div>
<p>Można również rozwiązać inaczej, korzystając z faktu, że <code>dict</code> akceptuje nazwane parametry:</p>
<div class="highlight">
<pre><span class="k">def</span> <span class="nf">foo</span><span class="p">(</span><span class="n">bar</span><span class="p">,</span> <span class="n">baz</span><span class="p">):</span>
    <span class="k">return</span> <span class="nb">dict</span><span class="p">(</span><span class="n">bar</span><span class="p">,</span> <span class="o">**</span><span class="n">baz</span><span class="p">)</span>
</pre>
</div>
<p>Korzystając ze skrótów zawsze upewnij się, że na pierwszy rzut oka wiadomo, co dany kod robi.</p>
<p><small><a href="http://room-303.com/blog/2010/02/26/python-alternatywa-dla-dict-update/">Python: alternatywa dla dict.update</a> © <a href="http://room-303.com/blog/" rel="cc:attributionURL">Patryk Zawadzki</a>, <a rel="license" href="http://creativecommons.org/licenses/by-nc-sa/2.5/pl/">Creative Commons Attribution-NonCommercial-ShareAlike 2.5 Poland</a>.</small></p>]]></content:encoded>
			<wfw:commentRss>http://room-303.com/blog/2010/02/26/python-alternatywa-dla-dict-update/feed/</wfw:commentRss>
		<slash:comments>3</slash:comments>
		</item>
		<item>
		<title>Django: direct_to_template</title>
		<link>http://room-303.com/blog/2010/02/26/django-direct_to_template/</link>
		<comments>http://room-303.com/blog/2010/02/26/django-direct_to_template/#comments</comments>
		<pubDate>Thu, 25 Feb 2010 23:36:23 +0000</pubDate>
		<dc:creator>Patrys</dc:creator>
				<category><![CDATA[code]]></category>
		<category><![CDATA[web]]></category>
		<category><![CDATA[django]]></category>
		<category><![CDATA[python]]></category>

		<guid isPermaLink="false">http://room-303.com/blog/?p=830</guid>
		<description><![CDATA[Nie wiem, czemu niektórzy tak uparcie korzystają z funkcji render_to_response, by za każdym razem przekazać do niej ręcznie stworzony obiekt kontekstu. Zresztą, sami oceńcie, która wersja jest ładniejsza:

from django.shortcuts import render_to_response
from django.template import RequestContext

def foo(request):
    # ...
    return render_to_response(&#39;foo.html&#39;, {&#39;bar&#39;: baz},
         [...]]]></description>
			<content:encoded><![CDATA[<p>Nie wiem, czemu niektórzy tak uparcie korzystają z funkcji <code>render_to_response</code>, by za każdym razem przekazać do niej ręcznie stworzony obiekt kontekstu. Zresztą, sami oceńcie, która wersja jest ładniejsza:</p>
<div class="highlight">
<pre><span class="kn">from</span> <span class="nn">django.shortcuts</span> <span class="kn">import</span> <span class="n">render_to_response</span>
<span class="kn">from</span> <span class="nn">django.template</span> <span class="kn">import</span> <span class="n">RequestContext</span>

<span class="k">def</span> <span class="nf">foo</span><span class="p">(</span><span class="n">request</span><span class="p">):</span>
    <span class="c"># ...</span>
    <span class="k">return</span> <span class="n">render_to_response</span><span class="p">(</span><span class="s">&#39;foo.html&#39;</span><span class="p">,</span> <span class="p">{</span><span class="s">&#39;bar&#39;</span><span class="p">:</span> <span class="n">baz</span><span class="p">},</span>
            <span class="n">context_instance</span><span class="o">=</span><span class="n">RequestContext</span><span class="p">(</span><span class="n">request</span><span class="p">))</span>
</pre>
</div>
<p>Czy może:</p>
<div class="highlight">
<pre><span class="kn">from</span> <span class="nn">django.views.generic.simple</span> <span class="kn">import</span> <span class="n">direct_to_template</span>

<span class="k">def</span> <span class="nf">foo</span><span class="p">(</span><span class="n">request</span><span class="p">):</span>
    <span class="c"># ...</span>
    <span class="k">return</span> <span class="n">direct_to_template</span><span class="p">(</span><span class="n">request</span><span class="p">,</span> <span class="s">&#39;foo.html&#39;</span><span class="p">,</span> <span class="p">{</span><span class="s">&#39;bar&#39;</span><span class="p">:</span> <span class="n">baz</span><span class="p">})</span>
</pre>
</div>
<p>A teraz pomnóżcie to przez liczbę widoków w aplikacji.</p>
<p><small><a href="http://room-303.com/blog/2010/02/26/django-direct_to_template/">Django: direct_to_template</a> © <a href="http://room-303.com/blog/" rel="cc:attributionURL">Patryk Zawadzki</a>, <a rel="license" href="http://creativecommons.org/licenses/by-nc-sa/2.5/pl/">Creative Commons Attribution-NonCommercial-ShareAlike 2.5 Poland</a>.</small></p>]]></content:encoded>
			<wfw:commentRss>http://room-303.com/blog/2010/02/26/django-direct_to_template/feed/</wfw:commentRss>
		<slash:comments>5</slash:comments>
		</item>
		<item>
		<title>Python: prawdziwy polimorfizm</title>
		<link>http://room-303.com/blog/2010/02/13/python-prawdziwy-polimorfizm/</link>
		<comments>http://room-303.com/blog/2010/02/13/python-prawdziwy-polimorfizm/#comments</comments>
		<pubDate>Sat, 13 Feb 2010 15:47:50 +0000</pubDate>
		<dc:creator>Patrys</dc:creator>
				<category><![CDATA[code]]></category>
		<category><![CDATA[python]]></category>

		<guid isPermaLink="false">http://room-303.com/blog/?p=799</guid>
		<description><![CDATA[Taki weekendowy żarcik:

#!/usr/bin/env python
import random

class Foo(random.choice([int, str, unicode, Exception])):
    pass

f = Foo(&#39;1&#39;)
print `f`


Python: prawdziwy polimorfizm © Patryk Zawadzki, Creative Commons Attribution-NonCommercial-ShareAlike 2.5 Poland.]]></description>
			<content:encoded><![CDATA[<p>Taki weekendowy żarcik:</p>
<div class="highlight">
<pre><span class="c">#!/usr/bin/env python</span>
<span class="kn">import</span> <span class="nn">random</span>

<span class="k">class</span> <span class="nc">Foo</span><span class="p">(</span><span class="n">random</span><span class="o">.</span><span class="n">choice</span><span class="p">([</span><span class="nb">int</span><span class="p">,</span> <span class="nb">str</span><span class="p">,</span> <span class="nb">unicode</span><span class="p">,</span> <span class="ne">Exception</span><span class="p">])):</span>
    <span class="k">pass</span>

<span class="n">f</span> <span class="o">=</span> <span class="n">Foo</span><span class="p">(</span><span class="s">&#39;1&#39;</span><span class="p">)</span>
<span class="k">print</span> <span class="sb">`f`</span>
</pre>
</div>
<p><small><a href="http://room-303.com/blog/2010/02/13/python-prawdziwy-polimorfizm/">Python: prawdziwy polimorfizm</a> © <a href="http://room-303.com/blog/" rel="cc:attributionURL">Patryk Zawadzki</a>, <a rel="license" href="http://creativecommons.org/licenses/by-nc-sa/2.5/pl/">Creative Commons Attribution-NonCommercial-ShareAlike 2.5 Poland</a>.</small></p>]]></content:encoded>
			<wfw:commentRss>http://room-303.com/blog/2010/02/13/python-prawdziwy-polimorfizm/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>O fontach raz jeszcze, czyli wielkość się liczy</title>
		<link>http://room-303.com/blog/2010/02/10/o-fontach-raz-jeszcze-czyli-wielkosc-sie-liczy/</link>
		<comments>http://room-303.com/blog/2010/02/10/o-fontach-raz-jeszcze-czyli-wielkosc-sie-liczy/#comments</comments>
		<pubDate>Wed, 10 Feb 2010 15:04:31 +0000</pubDate>
		<dc:creator>Patrys</dc:creator>
				<category><![CDATA[web]]></category>

		<guid isPermaLink="false">http://room-303.com/blog/?p=787</guid>
		<description><![CDATA[Z powodu występującego dzisiaj u mnie przesilenia kataru, zostałem zmuszony (dosłownie ze łzami w oczach) do zmiany wielkości fontów z 10 na 12 punktów. Później wspomniałem o tym kilku osobom, dodając, że nie rozróżniam liter poniżej 16 pikseli, co w dwóch przypadkach wywołało konsternację. Punkty i piksele to nie to samo.
Punkt jest jednostką typograficzną pochodzącą [...]]]></description>
			<content:encoded><![CDATA[<p>Z powodu występującego dzisiaj u mnie przesilenia kataru, zostałem zmuszony (dosłownie ze łzami w oczach) do zmiany wielkości fontów z 10 na 12 punktów. Później wspomniałem o tym kilku osobom, dodając, że nie rozróżniam liter poniżej 16 pikseli, co w dwóch przypadkach wywołało konsternację. Punkty i piksele to nie to samo.</p>
<p>Punkt jest jednostką typograficzną pochodzącą ze standardu pica, który to stworzyli Amerykanie by zemścić się za nasz system metryczny. Według standardu okrągłe¹ dwanaście punktów (<code>pt</code>) równe jest tytułowemu pica (<code>pc</code>). Z kolei sześć pica równe jest jednemu calowi (<code>in</code>). Jak wiemy cal to 2,54 centymetra (<code>cm</code>), ale w tym przypadku nie jest to wiedza istotna.</p>
<p><small>¹ Tak, bezczelnie naśmiewam się z systemu zbudowanego na wielokrotnościach liczby 6.</small></p>
<p>Co wiemy do tej pory: <code>72pt = 6pc = 1in = 2.54cm = 25.4mm</code>.</p>
<p>Na szczęście rozdzielczość sprzętową (DPI) również zdefiniowali Amerykanie i liczymy ją w punktach na cal. W punktach ekranowych, czyli pikselach (nie w punktach typograficznych, o których mówiliśmy wcześniej). DPI jest parametrem konkretnego ekranu² i mówi nam, ile kolejnych pikseli (<code>px</code>) ekranu należy zapalić, żeby długość powstałej linii wynosiła dokładnie jeden cal. Dla przykładu: rozdzielczość sprzętowa mojego laptopa wynosi 96 pikseli na cal, a mojego telefonu 260 pikseli na cal.</p>
<p><small>² Oczywiście zakładając poprawną konfigurację systemu operacyjnego, nic nie stoi bowiem na przeszkodzie do wmówienia komputerowi, że jego ekran jest wielkości biurka czy stadionu.</small></p>
<p>Posiadając tę wiedzę, możemy zacząć przeliczać: <code>12pt = 12 × 1/72in = 12/72in × 96px/in = 16px</code>. <em>Voilà!</em> Teraz mogę spokojnie poumierać dalej.</p>
<p><small><a href="http://room-303.com/blog/2010/02/10/o-fontach-raz-jeszcze-czyli-wielkosc-sie-liczy/">O fontach raz jeszcze, czyli wielkość się liczy</a> © <a href="http://room-303.com/blog/" rel="cc:attributionURL">Patryk Zawadzki</a>, <a rel="license" href="http://creativecommons.org/licenses/by-nc-sa/2.5/pl/">Creative Commons Attribution-NonCommercial-ShareAlike 2.5 Poland</a>.</small></p>]]></content:encoded>
			<wfw:commentRss>http://room-303.com/blog/2010/02/10/o-fontach-raz-jeszcze-czyli-wielkosc-sie-liczy/feed/</wfw:commentRss>
		<slash:comments>9</slash:comments>
		</item>
		<item>
		<title>Krzemowe kostki, czyli jak komputery zjadły RPG</title>
		<link>http://room-303.com/blog/2010/02/07/krzemowe-kostki-czyli-jak-komputery-zjadly-rpg/</link>
		<comments>http://room-303.com/blog/2010/02/07/krzemowe-kostki-czyli-jak-komputery-zjadly-rpg/#comments</comments>
		<pubDate>Sun, 07 Feb 2010 02:14:39 +0000</pubDate>
		<dc:creator>Patrys</dc:creator>
				<category><![CDATA[gry]]></category>
		<category><![CDATA[varia]]></category>
		<category><![CDATA[rpg]]></category>

		<guid isPermaLink="false">http://room-303.com/blog/?p=780</guid>
		<description><![CDATA[Kiedy byliśmy szczylami zupełnymi (pierwsze dwie klasy podstawówki), zagrywaliśmy się w Talizman, wtedy znany jedynie jako Magia i miecz. Gra wciągała, ale z czasem zaczęliśmy szukać odmiany. Advanced Dungeons &#38; Dragons okazało się strzałem w dziesiątkę, przynajmniej na jakiś czas.
Niedługo później zaczęliśmy swoje pierwsze eksperymenty z poważnymi RPG. Eksperymenty to dobre określenie, bo pierwsze spotkania [...]]]></description>
			<content:encoded><![CDATA[<p>Kiedy byliśmy szczylami zupełnymi (pierwsze dwie klasy podstawówki), zagrywaliśmy się w Talizman, wtedy znany jedynie jako <q>Magia i miecz</q>. Gra wciągała, ale z czasem zaczęliśmy szukać odmiany. Advanced Dungeons &amp; Dragons okazało się strzałem w dziesiątkę, przynajmniej na jakiś czas.</p>
<p>Niedługo później zaczęliśmy swoje pierwsze eksperymenty z <q>poważnymi</q> RPG. Eksperymenty to dobre określenie, bo pierwsze spotkania dziesięciolatków z odbitym na ksero podręcznikiem do Warhammera (po angielsku) były dość nieporadne.</p>
<p>Szybko jednak rozkręciliśmy się na tyle, że granie nie wymagało już posiłkowania się słownikiem (jeśli chodzi o angielski, to wszyscy byliśmy samoukami). W 1991 pojawiły się kserówki z tłumaczeniem Cyberpunka 2020. Na jakiś czas Warhammer poszedł w odstawkę — przynajmniej jeśli chodziło o gry fabularne, bo figurki do bitewniaka skutecznie uszczuplały skromne zasoby finansowe całej grupy.</p>
<p>Oczywiście grywaliśmy również na komputerze, ale ówczesne RPG dzieliły się na te z fabułą (jak np. Kult) i na te z <em>tabelkami</em> (jak Eye of the Beholder). Nikomu wtedy nie przyszło do głowy kojarzyć role-play’u z paskiem doświadczenia.</p>
<p>W papierowe gry fabularne graliśmy dużo i często, bo nie mieliśmy praktycznie żadnych obowiązków. W naszym repertuarze gościły kolejne systemy (Zew Cthulhu, Wampir: Maskarada), było dobrze. Gdzieś w tamtym czasie, na łamach pisma Magia i Miecz, pojawił się dziwoląg, który według obecnych standardów ktoś nazwać mógłby <q>klasycznym RPG</q>: <em>Kryształy Czasu</em>. Po raz pierwszy postać mistrza gry została sprowadzona do roli krupiera, który miał jedynie pilnować, by akcje graczy były zgodne z odpowiednimi tabelkami. Po jednej sesji daliśmy sobie spokój i wróciliśmy do tradycyjnych systemów.</p>
<p>Niestety, pod koniec podstawówki grupa się rozpadła i na jakiś czas szlag trafił granie. Kolejną ekipę znalazłem dopiero rok później. Pograliśmy razem niemal trzy lata, po czym nasze drogi się rozeszły.</p>
<p>W tym czasie komputerowe gry RPG poszły naprzód. Diablo stało się kamieniem węgielnym gatunku hack&amp;slash, jednak z grami fabularnymi nie łączyło go zbyt wiele. Za ciosem poszły jednak genialny Fallout oraz Wrota Baldura, które wielu stawia za przykład RPG idealnego. Ci ostatni chyba nie wiedzą, że prawdziwa perełka ukazała się dopiero w roku kolejnym. Mowa oczywiście o Planescape: Torment, który w cudownie odświeżający sposób zerwał z klasycznie pojmowanym światem fantasy.</p>
<p>Mijały lata, a mi coraz trudniej było wrócić do papierowych RPG. Zdecydowana większość napotkanych graczy zdawała się traktować gry fabularne jak salonową wersję Diablo. Nie było już istotne, w jaki system gramy. Liczyło się to, żeby mieć wysokie wszystkie statystyki na karcie postaci. Nadeszły czasy, kiedy każdy rybak znał kung-fu, każdy chłop pisał w minimum trzech językach, a najczęstszym pytaniem do mistrza gry stało się <q>kiedy będziemy zabijać potwory?</q></p>
<p>Innymi słowy historia zatoczyła pełne koło. Papierowe RPG wróciło do mojego punktu wyjścia, czyli ADnD. Komputery pozbawiły RPG dwóch pierwszych literek, została sama gra. Gra w licytowanie się na statystyki i dyskutowanie z mistrzem gry na temat tego, czy poziom 9 danej cechy oznacza już <em>megazajebistość</em>, czy może warto jeszcze rzucić kostką.</p>
<p>Na szczęście niektóre historie mają szczęśliwe zakończenia i za namową <a href="http://jakotwojprawnik.com/">swojej wspaniałej kobiety</a> wracam powoli do grania w środowisku graczy, którzy cenią sobie również fabułę. Którzy potrafią rzuty kostką ograniczyć do absolutnego minimum i prowadzić przygody w duchu podręcznika, a nie traktując dosłownie każde jego zdanie. Męczymy nawet Google Wave z <a href="http://gsc.stricte.net/">Ciepłym</a> i <a href="http://najpiekniejszyreaktor.blogspot.com/">Zenem</a>, próbując użyć go jako platformy do grania. A nuż uda się wziąć odwet na komputerach? Jest nadzieja.</p>
<p><small><a href="http://room-303.com/blog/2010/02/07/krzemowe-kostki-czyli-jak-komputery-zjadly-rpg/">Krzemowe kostki, czyli jak komputery zjadły RPG</a> © <a href="http://room-303.com/blog/" rel="cc:attributionURL">Patryk Zawadzki</a>, <a rel="license" href="http://creativecommons.org/licenses/by-nc-sa/2.5/pl/">Creative Commons Attribution-NonCommercial-ShareAlike 2.5 Poland</a>.</small></p>]]></content:encoded>
			<wfw:commentRss>http://room-303.com/blog/2010/02/07/krzemowe-kostki-czyli-jak-komputery-zjadly-rpg/feed/</wfw:commentRss>
		<slash:comments>6</slash:comments>
		</item>
		<item>
		<title>Intencją tej notki jest zapobieganie głupocie</title>
		<link>http://room-303.com/blog/2010/01/27/intencja-tej-notki-jest-zapobieganie-glupocie/</link>
		<comments>http://room-303.com/blog/2010/01/27/intencja-tej-notki-jest-zapobieganie-glupocie/#comments</comments>
		<pubDate>Wed, 27 Jan 2010 21:42:55 +0000</pubDate>
		<dc:creator>Patrys</dc:creator>
				<category><![CDATA[varia]]></category>

		<guid isPermaLink="false">http://room-303.com/blog/?p=775</guid>
		<description><![CDATA[Za VaGlą:
Uważnie śledzę Wasze opinie, komentarze, pytania i wątpliwości. Zdecydowałem, że jeszcze raz przyjrzę się projektowanej ustawie. Intencją mojego rządu jest zapobieganie wykorzystywania Internetu do rozpowszechniania pornografii dziecięcej, oszustw finansowych czy nielegalnych gier hazardowych, a nie ograniczanie wolności w sieci. Spróbujmy to razem pogodzić. W związku z tym zapraszam Was do debaty, która odbędzie się [...]]]></description>
			<content:encoded><![CDATA[<p>Za <a href="http://prawo.vagla.pl/node/8906">VaGlą</a>:</p>
<blockquote><p>Uważnie śledzę Wasze opinie, komentarze, pytania i wątpliwości. Zdecydowałem, że jeszcze raz przyjrzę się projektowanej ustawie. <em>Intencją mojego rządu jest zapobieganie wykorzystywania Internetu do rozpowszechniania pornografii dziecięcej, oszustw finansowych czy nielegalnych gier hazardowych, a nie ograniczanie wolności w sieci.</em> Spróbujmy to razem pogodzić. W związku z tym zapraszam Was do debaty, która odbędzie się w przyszłym tygodniu.</p>
</blockquote>
<p><cite><a href="http://www.premier.gov.pl/centrum_prasowe/wydarzenia/id:4042/">List premiera do internautów</a> (wyróżnienie moje)</cite></p>
<p>Pytam się tedy, czy intencją rządu pana Tuska jest mord? Wszak nie zabronił on sprzedaży tasaków, pił, bejsboli, szpikulców do lodu, noży, a nawet widelców. To nie do pomyślenia, zupełnie jak gdybyśmy chcieli ułatwiać mordercom życie.</p>
<p>Zapytuję, czy intencją rządu pana Tuska jest może gwałt? Parki nie wykarczowane, brak nakazu palenia światła przez całą dobę, w aptekach nadal sprzedają prezerwatywy, a w pobliskim sklepie widziałem spodnie z rozporkiem na suwak. To wszystko przecież okoliczności mogące się przyczynić.</p>
<p>Rozdarty wobec tych obserwacji, wątpię ostatecznie, czy rząd pana Tuska planuje przeciwdziałać włamaniom. Łomy nadal bez zezwolenia, dorabianie kluczy dostępne dla ludu, a w Tesco sprzedają druciane wieszaki. Mało tego, dożyliśmy czasów, w których do kamienicy można wejść bez uprzedniej rewizji osobistej.</p>
<p>Ludzie, czy wyście na łeb upadli?</p>
<p><small><a href="http://room-303.com/blog/2010/01/27/intencja-tej-notki-jest-zapobieganie-glupocie/">Intencją tej notki jest zapobieganie głupocie</a> © <a href="http://room-303.com/blog/" rel="cc:attributionURL">Patryk Zawadzki</a>, <a rel="license" href="http://creativecommons.org/licenses/by-nc-sa/2.5/pl/">Creative Commons Attribution-NonCommercial-ShareAlike 2.5 Poland</a>.</small></p>]]></content:encoded>
			<wfw:commentRss>http://room-303.com/blog/2010/01/27/intencja-tej-notki-jest-zapobieganie-glupocie/feed/</wfw:commentRss>
		<slash:comments>4</slash:comments>
		</item>
		<item>
		<title>Kolejny film: Avatar</title>
		<link>http://room-303.com/blog/2010/01/27/kolejny-film-avatar/</link>
		<comments>http://room-303.com/blog/2010/01/27/kolejny-film-avatar/#comments</comments>
		<pubDate>Tue, 26 Jan 2010 23:49:18 +0000</pubDate>
		<dc:creator>Patrys</dc:creator>
				<category><![CDATA[varia]]></category>
		<category><![CDATA[avatar]]></category>
		<category><![CDATA[film]]></category>

		<guid isPermaLink="false">http://room-303.com/blog/?p=768</guid>
		<description><![CDATA[Tak, to znów ten czas, kiedy wracam z kina. Tym razem, za namową wielu, udaliśmy się obejrzeć kolejną ofiarę Jamesa Camerona, czyli człowieka, który nie zrobił dobrego filmu od czasów Obcego i Terminatora. Tak, wiem, że niektórym podobały się również jego późniejsze dzieła, ale jakoś nigdy nie byłem fanem muzyki Celine Dion.
Żeby zaoszczędzić czasu, zacznę [...]]]></description>
			<content:encoded><![CDATA[<p>Tak, to znów ten czas, kiedy wracam z kina. Tym razem, za namową wielu, udaliśmy się obejrzeć kolejną ofiarę Jamesa Camerona, czyli człowieka, który nie zrobił dobrego filmu od czasów Obcego i Terminatora. Tak, wiem, że niektórym podobały się również jego późniejsze dzieła, ale jakoś nigdy nie byłem fanem muzyki Celine Dion.</p>
<p>Żeby zaoszczędzić czasu, zacznę od marudzenia, a potem sobie pooglądacie dla równowagi puchate króliczki w internecie i świat znów stanie się piękny. Na początek kwestia techniczna.</p>
<p>Drodzy filmowcy, oko ludzkie samo doskonale radzi sobie z ograniczaniem głębi ostrości. Rozumiem, że nie stać was na precyzyjne renderowanie kilometr w głąb sceny, ale jeśli rozmyte jest 90% pierwszego planu i do ostrego widzenia konieczne jest skupienie się na nosie głównego bohatera, to zamiast rewolucji zafundowaliście widzom <em>pieprzony ból głowy</em>.</p>
<p>Lepsze efekty 3D mieliśmy na domowych pecetach w 2004 roku. Za dowód niech posłuży fakt, że wtedy potrafiłem bez cienia migreny spędzić 24 godziny w tak zwanych <q>shutter glasses</q> przy partyjce Operacji Flashpoint (z 2001 roku!). A zapewniam, że prócz okularów powodów do migreny mieliśmy całą skrzynkę.</p>
<p>Co zaś się samej fabuły tyczy, najkrótsza recenzja Avatara, jaką znam, to <q>Pokahontas w kosmosie</q>. Coś w tym jest, mi jednak uparcie kojarzył się inny film:</p>
<p><img src="http://room-303.com/blog/wp-content/uploads/2010/01/Kaena.jpg" alt="" title="Kaena" /></p>
<p>Cała reszta to muzyka z <q>Króla lwa</q> czy innej <q>Księgi dżungli</q> oraz przemowy aż proszące się o łopoczącą w tle flagę USA. Disney pełną gębą. Jeśli ktoś po wizycie w kinie spodziewał się rewolucji, to chyba po nieświeżym popcornie.</p>
<p><small><a href="http://room-303.com/blog/2010/01/27/kolejny-film-avatar/">Kolejny film: Avatar</a> © <a href="http://room-303.com/blog/" rel="cc:attributionURL">Patryk Zawadzki</a>, <a rel="license" href="http://creativecommons.org/licenses/by-nc-sa/2.5/pl/">Creative Commons Attribution-NonCommercial-ShareAlike 2.5 Poland</a>.</small></p>]]></content:encoded>
			<wfw:commentRss>http://room-303.com/blog/2010/01/27/kolejny-film-avatar/feed/</wfw:commentRss>
		<slash:comments>20</slash:comments>
		</item>
		<item>
		<title>Django: szybszy SQLite do testów</title>
		<link>http://room-303.com/blog/2010/01/22/django-szybszy-sqlite-do-testow/</link>
		<comments>http://room-303.com/blog/2010/01/22/django-szybszy-sqlite-do-testow/#comments</comments>
		<pubDate>Fri, 22 Jan 2010 12:18:37 +0000</pubDate>
		<dc:creator>Patrys</dc:creator>
				<category><![CDATA[code]]></category>
		<category><![CDATA[web]]></category>
		<category><![CDATA[django]]></category>
		<category><![CDATA[python]]></category>
		<category><![CDATA[sqlite]]></category>

		<guid isPermaLink="false">http://room-303.com/blog/?p=764</guid>
		<description><![CDATA[Domyślna konfiguracja SQLite każe mu synchronizować plik bazy po każdej operacji. W środowiskach testowych nie musimy się martwić o spójność danych w wypadku awarii, poniżej zamieszczam więc backend pozbawiony zbędnego narzutu:

from django.db.backends.sqlite3.base import (
    DatabaseWrapper as Sqlite3Wrapper,
    DatabaseError,
    IntegrityError,
    DatabaseFeatures,
    [...]]]></description>
			<content:encoded><![CDATA[<p>Domyślna konfiguracja SQLite każe mu synchronizować plik bazy po każdej operacji. W środowiskach testowych nie musimy się martwić o spójność danych w wypadku awarii, poniżej zamieszczam więc backend pozbawiony zbędnego narzutu:</p>
<div class="highlight">
<pre><span class="kn">from</span> <span class="nn">django.db.backends.sqlite3.base</span> <span class="kn">import</span> <span class="p">(</span>
    <span class="n">DatabaseWrapper</span> <span class="k">as</span> <span class="n">Sqlite3Wrapper</span><span class="p">,</span>
    <span class="n">DatabaseError</span><span class="p">,</span>
    <span class="n">IntegrityError</span><span class="p">,</span>
    <span class="n">DatabaseFeatures</span><span class="p">,</span>
    <span class="n">DatabaseOperations</span><span class="p">,</span>
<span class="p">)</span>

<span class="k">class</span> <span class="nc">DatabaseWrapper</span><span class="p">(</span><span class="n">Sqlite3Wrapper</span><span class="p">):</span>
    <span class="k">def</span> <span class="nf">_cursor</span><span class="p">(</span><span class="bp">self</span><span class="p">):</span>
        <span class="n">new_conn</span> <span class="o">=</span> <span class="bp">self</span><span class="o">.</span><span class="n">connection</span> <span class="ow">is</span> <span class="bp">None</span>
        <span class="n">cursor</span> <span class="o">=</span> <span class="nb">super</span><span class="p">(</span><span class="n">DatabaseWrapper</span><span class="p">,</span> <span class="bp">self</span><span class="p">)</span><span class="o">.</span><span class="n">_cursor</span><span class="p">()</span>
        <span class="k">if</span> <span class="n">new_conn</span><span class="p">:</span>
            <span class="n">cursor</span><span class="o">.</span><span class="n">execute</span><span class="p">(</span><span class="s">&#39;PRAGMA synchronous=OFF&#39;</span><span class="p">)</span>
        <span class="k">return</span> <span class="n">cursor</span>
</pre>
</div>
<p>W przypadku projektu, nad którym właśnie pracujemy, czas przebudowania bazy od nowa na partycji XFS <em>spadł z półtorej minuty do pięciu sekund</em>.</p>
<p><small><a href="http://room-303.com/blog/2010/01/22/django-szybszy-sqlite-do-testow/">Django: szybszy SQLite do testów</a> © <a href="http://room-303.com/blog/" rel="cc:attributionURL">Patryk Zawadzki</a>, <a rel="license" href="http://creativecommons.org/licenses/by-nc-sa/2.5/pl/">Creative Commons Attribution-NonCommercial-ShareAlike 2.5 Poland</a>.</small></p>]]></content:encoded>
			<wfw:commentRss>http://room-303.com/blog/2010/01/22/django-szybszy-sqlite-do-testow/feed/</wfw:commentRss>
		<slash:comments>1</slash:comments>
		</item>
	</channel>
</rss>
