<?xml version="1.0" encoding="UTF-8"?>
<?xml-stylesheet type="text/xsl" media="screen" href="/~d/styles/rss2full.xsl"?><?xml-stylesheet type="text/css" media="screen" href="http://feeds.feedburner.com/~d/styles/itemcontent.css"?><rss 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" version="2.0">

<channel>
	<title>/home/Śpiechu-&gt;Blog</title>
	
	<link>http://spiechu.pl</link>
	<description>o wszystkim co się nawinie… a najczęściej o PHP, Linuksie i szerzącej się głupocie</description>
	<lastBuildDate>Mon, 09 Jan 2012 06:29:15 +0000</lastBuildDate>
	<language>en</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
	<generator>http://wordpress.org/?v=3.1</generator>
		<atom10:link xmlns:atom10="http://www.w3.org/2005/Atom" rel="self" type="application/rss+xml" href="http://feeds.feedburner.com/spiechu" /><feedburner:info xmlns:feedburner="http://rssnamespace.org/feedburner/ext/1.0" uri="spiechu" /><atom10:link xmlns:atom10="http://www.w3.org/2005/Atom" rel="hub" href="http://pubsubhubbub.appspot.com/" /><creativeCommons:license>http://creativecommons.org/licenses/by-nc-sa/2.5/</creativeCommons:license><image><link>http://creativecommons.org/licenses/by-nc-sa/2.5/</link><url>http://creativecommons.org/images/public/somerights20.gif</url><title>Some Rights Reserved</title></image><item>
		<title>Reprezentacja bitowa znaków Unicode i UTF-8</title>
		<link>http://spiechu.pl/2012/01/08/reprezentacja-bitowa-znakow-unicode-i-utf-8/</link>
		<comments>http://spiechu.pl/2012/01/08/reprezentacja-bitowa-znakow-unicode-i-utf-8/#comments</comments>
		<pubDate>Sun, 08 Jan 2012 15:59:13 +0000</pubDate>
		<dc:creator>Śpiechu</dc:creator>
				<category><![CDATA[webmastering]]></category>
		<category><![CDATA[php]]></category>

		<guid isPermaLink="false">http://spiechu.pl/?p=1220</guid>
		<description><![CDATA[Jakiś taki naukowy ten tytuł wyszedł. Ale inaczej się chyba nie da. Potrzebowałem pretekstu żeby się trochę pobawić w manipulowanie bitami. Padło na Unicode z racji fajnego sposobu, w jaki wymyślono sam zapis znaków. Jeśli jest jeszcze ktoś kto nie wie co to jest Unicode to zapraszam do źródła. Wszystko zostało tak przemyślane, że im <a href="http://spiechu.pl/2012/01/08/reprezentacja-bitowa-znakow-unicode-i-utf-8/"> read more <span class="meta-nav">&#187;</span></a>]]></description>
			<content:encoded><![CDATA[<p>Jakiś taki naukowy ten tytuł wyszedł. Ale inaczej się chyba nie da. Potrzebowałem pretekstu żeby się trochę pobawić w manipulowanie bitami. Padło na Unicode z racji fajnego sposobu, w jaki wymyślono sam zapis znaków. Jeśli jest jeszcze ktoś kto nie wie co to jest Unicode to <a href="http://www.unicode.org/standard/translations/polish.html">zapraszam do źródła</a>.</p>
<p>Wszystko zostało tak przemyślane, że im bardziej pokręcony język, tym więcej miejsca potrzeba na jego zapisanie. Wszystkie liczby i litery bez ogonków damy radę zapisać w postaci 1 bajta. Chodziło o kompatybilność z formatem ASCII. Znaczki języka polskiego znajdują się w <a href="http://www.unicode.org/charts/">dziale Latin Extended-A</a>. Zapis znaków polskich zajmie 2 bajty w formacie UTF-8.</p>
<p>Mając numer znaku z tabeli Unicode najłatwiej wyświetlić go za pomocą wbudowanej w PHP funkcji <code>html_entity_decode()</code>:</p>

<div class="wp_syntax"><div class="code"><pre class="php" style="font-family:monospace;"><span style="color: #b1b100;">echo</span> <span style="color: #990000;">html_entity_decode</span><span style="color: #009900;">&#40;</span><span style="color: #0000ff;">'&amp;#'</span> <span style="color: #339933;">.</span> <span style="color: #208080;">0xA7</span> <span style="color: #339933;">.</span> <span style="color: #0000ff;">';'</span><span style="color: #339933;">,</span> <span style="color: #009900; font-weight: bold;">ENT_NOQUOTES</span><span style="color: #339933;">,</span> <span style="color: #0000ff;">'UTF-8'</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span></pre></div></div>

<p>Wywołanie powyższego wiersza spowoduje wyświetlenie znaku o kodzie 0xA7 — paragrafu §. W jaki więc sposób wykonuje się czary-mary i znak Unicode staje się znakiem UTF-8? Weźmy na warsztat znak ę opisany w tablicy jako <em>latin small letter e with ogonek</em>. Ma numer 0119 (heksadecymalnie!), czyli można zapisać tak:<br />
0x119<sub>16</sub> = 281<sub>10</sub> = 100011001<sub>2</sub><br />
Z powyższego widać, że liczbę dziesiętną 281 możemy zapisać w postaci 9 bitów. <a href="http://pl.php.net/manual/en/function.utf8-encode.php">Dokumentacja funkcji <code>utf8_encode()</code></a> zawiera tabelkę ile bitów znaku zmieścimy w ilu bajtach UTF-8. Wygląda na to, że w jednobajtowym zapisie zmieścimy znaki o numerach od 0 do 127<sub>10</sub> (7 bitów). Za to dysponując 2 bajtami zapiszemy liczby aż do 2047<sub>10</sub>, czyli w zupełności nam wystarczy.</p>
<p>Znak ę w UTF-8 zapisujemy w 2 bajtach, czyli do liczby 11000000<sub>2</sub> musimy dodać przesuniętą o 6 bitów w prawo liczbę 281 (ponieważ pójdą do drugiego bajtu znaku). Z drugiego wyrzucamy wszystko poza 6 ostatnimi bitami, a następnie dodajemy do liczby 10000000<sub>2</sub>.</p>

<div class="wp_syntax"><div class="code"><pre class="php" style="font-family:monospace;"><span style="color: #000088;">$uniChar</span> <span style="color: #339933;">=</span> <span style="color: #208080;">0x119</span><span style="color: #339933;">;</span>
<span style="color: #000088;">$byte1</span> <span style="color: #339933;">=</span> <span style="color: #000088;">$uniChar</span> <span style="color: #339933;">&gt;&gt;</span> <span style="color: #cc66cc;">6</span> <span style="color: #339933;">|</span> <span style="color: #208080;">0xC0</span><span style="color: #339933;">;</span>
<span style="color: #000088;">$byte2</span> <span style="color: #339933;">=</span> <span style="color: #000088;">$uniChar</span> <span style="color: #339933;">&amp;</span> <span style="color: #208080;">0x3F</span> <span style="color: #339933;">|</span> <span style="color: #208080;">0x80</span></pre></div></div>

<p>Wyszło na to, że ę w zapisie UTF-8 to będzie 11000100 10011001. Po ubraniu tego wszystkiego w funkcję:</p>

<div class="wp_syntax"><div class="code"><pre class="php" style="font-family:monospace;"><span style="color: #000000; font-weight: bold;">function</span> hexToUTF8HexArray<span style="color: #009900;">&#40;</span><span style="color: #000088;">$hexNum</span><span style="color: #009900;">&#41;</span>
<span style="color: #009900;">&#123;</span>
   <span style="color: #666666; font-style: italic;">// konwertujemy na liczbe w razie czego</span>
   <span style="color: #b1b100;">if</span> <span style="color: #009900;">&#40;</span><span style="color: #990000;">is_string</span><span style="color: #009900;">&#40;</span><span style="color: #000088;">$hexNum</span><span style="color: #009900;">&#41;</span><span style="color: #009900;">&#41;</span> <span style="color: #000088;">$hexNum</span> <span style="color: #339933;">=</span> <span style="color: #990000;">hexdec</span><span style="color: #009900;">&#40;</span><span style="color: #000088;">$hexNum</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
&nbsp;
   <span style="color: #000088;">$hexArray</span> <span style="color: #339933;">=</span> <span style="color: #990000;">array</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
   <span style="color: #b1b100;">if</span> <span style="color: #009900;">&#40;</span><span style="color: #000088;">$hexNum</span> <span style="color: #339933;">&lt;</span> <span style="color: #208080;">0x80</span><span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span>
      <span style="color: #000088;">$hexArray</span><span style="color: #009900;">&#91;</span><span style="color: #cc66cc;">0</span><span style="color: #009900;">&#93;</span> <span style="color: #339933;">=</span> <span style="color: #0000ff;">'0x'</span> <span style="color: #339933;">.</span> <span style="color: #990000;">dechex</span><span style="color: #009900;">&#40;</span><span style="color: #000088;">$hexNum</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
      <span style="color: #b1b100;">return</span> <span style="color: #000088;">$hexArray</span><span style="color: #339933;">;</span>
   <span style="color: #009900;">&#125;</span> <span style="color: #b1b100;">elseif</span> <span style="color: #009900;">&#40;</span><span style="color: #000088;">$hexNum</span> <span style="color: #339933;">&lt;</span> <span style="color: #208080;">0x800</span><span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span>
      <span style="color: #000088;">$hexArray</span><span style="color: #009900;">&#91;</span><span style="color: #cc66cc;">0</span><span style="color: #009900;">&#93;</span> <span style="color: #339933;">=</span> <span style="color: #0000ff;">'0x'</span> <span style="color: #339933;">.</span> <span style="color: #990000;">dechex</span><span style="color: #009900;">&#40;</span><span style="color: #000088;">$hexNum</span> <span style="color: #339933;">&gt;&gt;</span> <span style="color: #cc66cc;">6</span> <span style="color: #339933;">|</span> <span style="color: #208080;">0xC0</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
      <span style="color: #000088;">$hexArray</span><span style="color: #009900;">&#91;</span><span style="color: #cc66cc;">1</span><span style="color: #009900;">&#93;</span> <span style="color: #339933;">=</span> <span style="color: #0000ff;">'0x'</span> <span style="color: #339933;">.</span> <span style="color: #990000;">dechex</span><span style="color: #009900;">&#40;</span><span style="color: #000088;">$hexNum</span> <span style="color: #339933;">&amp;</span> <span style="color: #208080;">0x3F</span> <span style="color: #339933;">|</span> <span style="color: #208080;">0x80</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
      <span style="color: #b1b100;">return</span> <span style="color: #000088;">$hexArray</span><span style="color: #339933;">;</span>
   <span style="color: #009900;">&#125;</span> <span style="color: #b1b100;">else</span> <span style="color: #009900;">&#123;</span>
      <span style="color: #b1b100;">throw</span> <span style="color: #000000; font-weight: bold;">new</span> Exception<span style="color: #009900;">&#40;</span><span style="color: #0000ff;">'Not supported'</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
   <span style="color: #009900;">&#125;</span>
<span style="color: #009900;">&#125;</span></pre></div></div>

<p>Wywołując <code>hexToUTF8HexArray(0x119)</code> da nam tablicę z wartościami 0xc4 i 0x99. No dobra, a co jak chcę odwrócić proces? Teraz będzie przyjemniej:</p>

<div class="wp_syntax"><div class="code"><pre class="php" style="font-family:monospace;"><span style="color: #000000; font-weight: bold;">function</span> utf8ToUnicode<span style="color: #009900;">&#40;</span><span style="color: #990000;">array</span> <span style="color: #000088;">$utf8Array</span><span style="color: #009900;">&#41;</span>
<span style="color: #009900;">&#123;</span>
   <span style="color: #666666; font-style: italic;">// konwertujemy na liczby</span>
   <span style="color: #000088;">$utf8ArrayChecked</span> <span style="color: #339933;">=</span> <span style="color: #990000;">array</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
   <span style="color: #b1b100;">foreach</span> <span style="color: #009900;">&#40;</span><span style="color: #000088;">$utf8Array</span> <span style="color: #b1b100;">as</span> <span style="color: #000088;">$utf8</span><span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span>
      <span style="color: #b1b100;">if</span> <span style="color: #009900;">&#40;</span><span style="color: #990000;">is_string</span><span style="color: #009900;">&#40;</span><span style="color: #000088;">$utf8</span><span style="color: #009900;">&#41;</span><span style="color: #009900;">&#41;</span> <span style="color: #000088;">$utf8</span> <span style="color: #339933;">=</span> <span style="color: #990000;">hexdec</span><span style="color: #009900;">&#40;</span><span style="color: #000088;">$utf8</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
      <span style="color: #000088;">$utf8ArrayChecked</span><span style="color: #009900;">&#91;</span><span style="color: #009900;">&#93;</span> <span style="color: #339933;">=</span> <span style="color: #000088;">$utf8</span><span style="color: #339933;">;</span>
   <span style="color: #009900;">&#125;</span>
&nbsp;
   <span style="color: #000088;">$bytesCount</span> <span style="color: #339933;">=</span> <span style="color: #990000;">count</span><span style="color: #009900;">&#40;</span><span style="color: #000088;">$utf8ArrayChecked</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
   <span style="color: #b1b100;">switch</span> <span style="color: #009900;">&#40;</span><span style="color: #000088;">$bytesCount</span><span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span>
      <span style="color: #b1b100;">case</span> <span style="color: #cc66cc;">1</span><span style="color: #339933;">:</span>
         <span style="color: #b1b100;">return</span> <span style="color: #000088;">$utf8ArrayChecked</span><span style="color: #009900;">&#91;</span><span style="color: #cc66cc;">0</span><span style="color: #009900;">&#93;</span><span style="color: #339933;">;</span>
      <span style="color: #b1b100;">case</span> <span style="color: #cc66cc;">2</span><span style="color: #339933;">:</span>
         <span style="color: #666666; font-style: italic;">// wyrzucamy naglowki</span>
         <span style="color: #000088;">$b1</span> <span style="color: #339933;">=</span> <span style="color: #000088;">$utf8ArrayChecked</span><span style="color: #009900;">&#91;</span><span style="color: #cc66cc;">0</span><span style="color: #009900;">&#93;</span> <span style="color: #339933;">&amp;</span> <span style="color: #208080;">0x1F</span><span style="color: #339933;">;</span>
         <span style="color: #000088;">$b2</span> <span style="color: #339933;">=</span> <span style="color: #000088;">$utf8ArrayChecked</span><span style="color: #009900;">&#91;</span><span style="color: #cc66cc;">1</span><span style="color: #009900;">&#93;</span> <span style="color: #339933;">&amp;</span> <span style="color: #208080;">0x3F</span><span style="color: #339933;">;</span>
&nbsp;
         <span style="color: #666666; font-style: italic;">// tutaj cala magia</span>
         <span style="color: #000088;">$number</span> <span style="color: #339933;">=</span> <span style="color: #000088;">$b1</span> <span style="color: #339933;">&lt;&lt;</span> <span style="color: #cc66cc;">6</span> <span style="color: #339933;">|</span> <span style="color: #000088;">$b2</span><span style="color: #339933;">;</span>
         <span style="color: #b1b100;">return</span> <span style="color: #0000ff;">'0x'</span> <span style="color: #339933;">.</span> <span style="color: #990000;">dechex</span><span style="color: #009900;">&#40;</span><span style="color: #000088;">$number</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
      <span style="color: #b1b100;">default</span><span style="color: #339933;">:</span>
         <span style="color: #b1b100;">throw</span> <span style="color: #000000; font-weight: bold;">new</span> Exception<span style="color: #009900;">&#40;</span><span style="color: #0000ff;">'Not supported'</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span> 
   <span style="color: #009900;">&#125;</span>
<span style="color: #009900;">&#125;</span></pre></div></div>

<p>Wywołując <code>utf8ToUnicode(array(0xc4, 0x99))</code> otrzymamy 0x119, czyli gra jak trzeba.</p>
<p>Na koniec ciekawostka: mając jakiś znak możemy łatwo wydobyć jego wartość UTF-8.</p>

<div class="wp_syntax"><div class="code"><pre class="php" style="font-family:monospace;"><span style="color: #000000; font-weight: bold;">function</span> charToUTF8HexArray<span style="color: #009900;">&#40;</span><span style="color: #000088;">$char</span><span style="color: #009900;">&#41;</span>
<span style="color: #009900;">&#123;</span>
   <span style="color: #000088;">$i</span> <span style="color: #339933;">=</span> <span style="color: #cc66cc;">0</span><span style="color: #339933;">;</span>
   <span style="color: #000088;">$hexArray</span> <span style="color: #339933;">=</span> <span style="color: #990000;">array</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
   <span style="color: #b1b100;">while</span> <span style="color: #009900;">&#40;</span><span style="color: #990000;">isset</span><span style="color: #009900;">&#40;</span><span style="color: #000088;">$char</span><span style="color: #009900;">&#91;</span><span style="color: #000088;">$i</span><span style="color: #009900;">&#93;</span><span style="color: #009900;">&#41;</span><span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span>
      <span style="color: #000088;">$hexArray</span><span style="color: #009900;">&#91;</span><span style="color: #009900;">&#93;</span> <span style="color: #339933;">=</span> <span style="color: #0000ff;">'0x'</span> <span style="color: #339933;">.</span> <span style="color: #990000;">dechex</span><span style="color: #009900;">&#40;</span><span style="color: #990000;">ord</span><span style="color: #009900;">&#40;</span><span style="color: #000088;">$char</span><span style="color: #009900;">&#91;</span><span style="color: #000088;">$i</span><span style="color: #339933;">++</span><span style="color: #009900;">&#93;</span><span style="color: #009900;">&#41;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
   <span style="color: #009900;">&#125;</span>
   <span style="color: #b1b100;">return</span> <span style="color: #000088;">$hexArray</span><span style="color: #339933;">;</span>
<span style="color: #009900;">&#125;</span></pre></div></div>

<p><code>charToUTF8HexArray('ę')</code> da nam tablicę 0xc4, 0x99.</p>
<p>Ten wpis to taka trochę notatka dla mnie, przez co może trochę chaotycznie napisany…</p>
<div class="google_plusone_widget" style="margin-bottom:10px"><g:plusone 
      count="false" href="http://spiechu.pl/2012/01/08/reprezentacja-bitowa-znakow-unicode-i-utf-8/" size="standard"></g:plusone></div>]]></content:encoded>
			<wfw:commentRss>http://spiechu.pl/2012/01/08/reprezentacja-bitowa-znakow-unicode-i-utf-8/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Algorytmy liczące Pi w Pythonie</title>
		<link>http://spiechu.pl/2011/12/04/algorytmy-liczace-pi-w-pythonie/</link>
		<comments>http://spiechu.pl/2011/12/04/algorytmy-liczace-pi-w-pythonie/#comments</comments>
		<pubDate>Sun, 04 Dec 2011 21:50:41 +0000</pubDate>
		<dc:creator>Śpiechu</dc:creator>
				<category><![CDATA[Inne]]></category>
		<category><![CDATA[python]]></category>

		<guid isPermaLink="false">http://spiechu.pl/?p=1200</guid>
		<description><![CDATA[Dzisiaj będzie o długich liczbach. Wiedzieliście, że Python w stałej Pi zawiera tylko 48 cyfr po przecinku? (a przynajmniej wersja 2.6) 3.141592653589793 (odtąd błędnie) 115997963468544185161590576171875. To stanowczo za mało! Tyle to ja liczyłem na liczydle w przedszkolu A ja chciałbym wiedzieć jaka jest liczba pięciotysięczna po przecinku Zademonstruję 3 metody liczenia liczby Pi. Od razu <a href="http://spiechu.pl/2011/12/04/algorytmy-liczace-pi-w-pythonie/"> read more <span class="meta-nav">&#187;</span></a>]]></description>
			<content:encoded><![CDATA[<p>Dzisiaj będzie o długich liczbach. Wiedzieliście, że Python w stałej Pi zawiera tylko 48 cyfr po przecinku? (a przynajmniej wersja 2.6) 3.141592653589793 (<a href="http://3.141592653589793238462643383279502884197169399375105820974944592.com/index31415.html">odtąd błędnie</a>) 115997963468544185161590576171875. To stanowczo za mało! Tyle to ja liczyłem na liczydle w przedszkolu  A ja chciałbym wiedzieć jaka jest liczba pięciotysięczna po przecinku <img src='http://spiechu.pl/wp-includes/images/smilies/icon_wink.gif' alt=';-)' class='wp-smiley' />  Zademonstruję 3 metody liczenia liczby Pi.</p>
<p>Od razu mówię, nie pytajcie mnie o nic w związku z tymi metodami, bo zazwyczaj rozumiem tylko wstęp i pierwszy wzór z opisu.</p>
<p>I. <a href="http://pl.wikipedia.org/wiki/Wz%C3%B3r_Wallisa">Metoda Wallisa</a><br />
Posłużymy się takim fajnym tworem jak generator (yield w pętli zamiast return)</p>

<div class="wp_syntax"><div class="code"><pre class="python" style="font-family:monospace;"><span style="color: #ff7700;font-weight:bold;">def</span> wallisFormulaGenerator<span style="color: black;">&#40;</span>counterMax<span style="color: black;">&#41;</span>:
   counter = <span style="color: #ff4500;">0</span>
   <span style="color: #ff7700;font-weight:bold;">while</span><span style="color: black;">&#40;</span>counter <span style="color: #66cc66;">&lt;</span>= counterMax<span style="color: black;">&#41;</span>:
      counter += <span style="color: #ff4500;">1</span>
      <span style="color: #ff7700;font-weight:bold;">yield</span> <span style="color: black;">&#40;</span><span style="color: #ff4500;">4</span><span style="color: #66cc66;">*</span><span style="color: black;">&#40;</span>counter<span style="color: #66cc66;">**</span><span style="color: #ff4500;">2</span><span style="color: black;">&#41;</span><span style="color: black;">&#41;</span>/<span style="color: black;">&#40;</span><span style="color: #ff4500;">4</span><span style="color: #66cc66;">*</span><span style="color: black;">&#40;</span>counter<span style="color: #66cc66;">**</span><span style="color: #ff4500;">2</span><span style="color: black;">&#41;</span>-<span style="color: #ff4500;">1</span><span style="color: black;">&#41;</span>       
&nbsp;
<span style="color: #ff7700;font-weight:bold;">def</span> gimmePiBaby<span style="color: black;">&#40;</span>loops<span style="color: black;">&#41;</span>:
   result = <span style="color: #ff4500;">1</span>
   <span style="color: #ff7700;font-weight:bold;">for</span> value <span style="color: #ff7700;font-weight:bold;">in</span> wallisFormulaGenerator<span style="color: black;">&#40;</span>loops<span style="color: black;">&#41;</span>:
      result <span style="color: #66cc66;">*</span>= value
      <span style="color: #ff7700;font-weight:bold;">return</span> <span style="color: #ff4500;">2</span><span style="color: #66cc66;">*</span>result
&nbsp;
<span style="color: #ff7700;font-weight:bold;">print</span><span style="color: black;">&#40;</span>gimmePiBaby<span style="color: black;">&#40;</span><span style="color: #ff4500;">10000</span><span style="color: black;">&#41;</span><span style="color: black;">&#41;</span></pre></div></div>

<p>Ta metoda jest najsłabsza, po 18 obrotach mamy dopiero 3.1, po 492 3.14, a dopiero po 8476 3.1415.</p>
<p>II. <a href="http://en.wikipedia.org/wiki/Leibniz_formula_for_%CF%80">Metoda Leibnitza</a><br />
W moim przypadku mocno oszukana ta metoda, ale działa poprawnie. I dużo szybciej!</p>

<div class="wp_syntax"><div class="code"><pre class="python" style="font-family:monospace;">minus = <span style="color: #008000;">True</span>
partial = <span style="color: #ff4500;">1</span>
denominator = <span style="color: #ff4500;">3</span>
<span style="color: #ff7700;font-weight:bold;">for</span> i <span style="color: #ff7700;font-weight:bold;">in</span> <span style="color: #008000;">range</span><span style="color: black;">&#40;</span><span style="color: #ff4500;">100000</span><span style="color: black;">&#41;</span>:
   <span style="color: #ff7700;font-weight:bold;">if</span> minus:
      partial -= <span style="color: #ff4500;">1</span>/denominator
      minus = <span style="color: #008000;">False</span>
   <span style="color: #ff7700;font-weight:bold;">else</span>:
      partial += <span style="color: #ff4500;">1</span>/denominator
      minus = <span style="color: #008000;">True</span>
   denominator += <span style="color: #ff4500;">2</span>
   result = <span style="color: #ff4500;">4</span> <span style="color: #66cc66;">*</span> partial</pre></div></div>

<p>Jest lepiej, obliczenia wykonywały się 3x szybciej niż poprzednio.</p>
<p>III. <a href="http://numbers.computation.free.fr/Constants/Pi/piclassic.html">Metoda Abrahama Sharpa</a><br />
Najwydajniejsza z wyżej przedstawionych. Na pewno są wydajniejsze, ale dla określenia liczby nr 5000 wystarczy. Aby wypisać tyle liczb ile nas interesuje, zwykły obiekt typu <code>float</code> nie wystarczy, potrzebujemy <a href="http://pypi.python.org/pypi/bigfloat/0.2.1">biblioteki BigFloat</a>. Niestety nie daje się zainstalować z wersją 3 Pythona mimo użycia 2to3, więc pozostaje wbudowane w Ubuntu 2.6.</p>

<div class="wp_syntax"><div class="code"><pre class="python" style="font-family:monospace;"><span style="color: #ff7700;font-weight:bold;">import</span> bigfloat
<span style="color: #ff7700;font-weight:bold;">with</span> bigfloat.<span style="color: black;">precision</span><span style="color: black;">&#40;</span><span style="color: #ff4500;">17000</span><span style="color: black;">&#41;</span>:
   minus = <span style="color: #008000;">True</span>
   partial = bigfloat.<span style="color: black;">BigFloat</span><span style="color: black;">&#40;</span><span style="color: #ff4500;">1</span><span style="color: black;">&#41;</span>
   denominator = <span style="color: #ff4500;">3</span>
   <span style="color: #ff7700;font-weight:bold;">for</span> i <span style="color: #ff7700;font-weight:bold;">in</span> <span style="color: #008000;">range</span><span style="color: black;">&#40;</span><span style="color: #ff4500;">1</span>, <span style="color: #ff4500;">500000</span><span style="color: black;">&#41;</span>:
      <span style="color: #ff7700;font-weight:bold;">if</span> minus:
         partial -= <span style="color: black;">&#40;</span><span style="color: #ff4500;">1</span>/<span style="color: black;">&#40;</span><span style="color: black;">&#40;</span>bigfloat.<span style="color: #008000;">pow</span><span style="color: black;">&#40;</span><span style="color: #ff4500;">3</span>,i<span style="color: black;">&#41;</span><span style="color: black;">&#41;</span><span style="color: #66cc66;">*</span>denominator<span style="color: black;">&#41;</span><span style="color: black;">&#41;</span>
         minus = <span style="color: #008000;">False</span>
      <span style="color: #ff7700;font-weight:bold;">else</span>:
         partial += <span style="color: black;">&#40;</span><span style="color: #ff4500;">1</span>/<span style="color: black;">&#40;</span><span style="color: black;">&#40;</span>bigfloat.<span style="color: #008000;">pow</span><span style="color: black;">&#40;</span><span style="color: #ff4500;">3</span>,i<span style="color: black;">&#41;</span><span style="color: black;">&#41;</span><span style="color: #66cc66;">*</span>denominator<span style="color: black;">&#41;</span><span style="color: black;">&#41;</span>
         minus = <span style="color: #008000;">True</span>
      denominator += <span style="color: #ff4500;">2</span>
   result = <span style="color: #ff4500;">6</span> <span style="color: #66cc66;">*</span> <span style="color: black;">&#40;</span><span style="color: black;">&#40;</span><span style="color: #ff4500;">1</span>/bigfloat.<span style="color: black;">sqrt</span><span style="color: black;">&#40;</span><span style="color: #ff4500;">3</span><span style="color: black;">&#41;</span><span style="color: black;">&#41;</span> <span style="color: #66cc66;">*</span> partial<span style="color: black;">&#41;</span></pre></div></div>

<p>Mój procek za 45zł 500 000 obrotów wykonał w 2339 sek., a dzisiejszy wpis sponsoruje cyferka 1 będąca wartością pięciotysięczną po przecinku.</p>
<p>Mam nadzieję, że chociaż gimnazjalistom algorytmy się przydadzą…</p>
<div class="google_plusone_widget" style="margin-bottom:10px"><g:plusone 
      count="false" href="http://spiechu.pl/2011/12/04/algorytmy-liczace-pi-w-pythonie/" size="standard"></g:plusone></div>]]></content:encoded>
			<wfw:commentRss>http://spiechu.pl/2011/12/04/algorytmy-liczace-pi-w-pythonie/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Śpiechu goes Android</title>
		<link>http://spiechu.pl/2011/11/15/spiechu-goes-android/</link>
		<comments>http://spiechu.pl/2011/11/15/spiechu-goes-android/#comments</comments>
		<pubDate>Tue, 15 Nov 2011 20:10:17 +0000</pubDate>
		<dc:creator>Śpiechu</dc:creator>
				<category><![CDATA[Android]]></category>
		<category><![CDATA[android]]></category>
		<category><![CDATA[gmail]]></category>
		<category><![CDATA[google talk]]></category>

		<guid isPermaLink="false">http://spiechu.pl/?p=1187</guid>
		<description><![CDATA[No to teraz wiecie już, że Śpiechu dochrapał się Androidka (2.3.3). Wprawdzie na najsłabszym sprzęcie jaki istnieje — HTC Wildfire S, ale zawsze. Udało się wylicytować na Alledrogo za 500 zł. Człowiek, od którego kupiłem sprzęt wierzył, że zrobił dobry interes. Ja również. Kto zrobił lepszy? On w końcu zapłacił tylko złotówkę, a dostał 499 <a href="http://spiechu.pl/2011/11/15/spiechu-goes-android/"> read more <span class="meta-nav">&#187;</span></a>]]></description>
			<content:encoded><![CDATA[<p>No to teraz wiecie już, że Śpiechu dochrapał się Androidka (2.3.3). Wprawdzie na najsłabszym sprzęcie jaki istnieje — HTC Wildfire S, ale zawsze. Udało się wylicytować na Alledrogo za 500 zł. Człowiek, od którego kupiłem sprzęt wierzył, że zrobił dobry interes. Ja również. Kto zrobił lepszy? On w końcu zapłacił tylko złotówkę, a dostał 499 w zamian <img src='http://spiechu.pl/wp-includes/images/smilies/icon_wink.gif' alt=';-)' class='wp-smiley' /> </p>
<p>W związku z tym warto byłoby odpalić mały cykl androidowego how-to. Na początek jak pozbyć się tego uciążliwego powiadomienia dźwiękowego o nowym mailu i nowej wiadomości na Google Talk. Jeśli otrzymujecie kilkadziesiąt maili dziennie, jest to spory problem. Dioda wg mnie wystarczy.</p>
<p>Opcja jest na tyle schowana, że warto o niej tutaj napisać. Znajdując się w aplikacji Gmail naciskamy przycisk <em>menu -&gt; więcej -&gt; ustawienia -&gt; swoje konto -&gt; etykiety do powiadomień -&gt; odebrane -&gt; dzwonek -&gt; <strong>Cichy</strong></em>. W Talku jest jeszcze prościej: <em>menu -&gt; ustawienia -&gt; wybierz dzwonek -&gt; cichy</em>.</p>
<p>Tyle na dzisiaj. W ciągu 2 dni nie stałem się jeszcze smartfonowym guru, ale wszystko przede mną. I żeby nie było, 7 letnia Nokia 6230i ma się świetnie. W dalszym ciągu bateria trzyma 5 dni, a w nowym HTC 1.</p>
<div class="google_plusone_widget" style="margin-bottom:10px"><g:plusone 
      count="false" href="http://spiechu.pl/2011/11/15/spiechu-goes-android/" size="standard"></g:plusone></div>]]></content:encoded>
			<wfw:commentRss>http://spiechu.pl/2011/11/15/spiechu-goes-android/feed/</wfw:commentRss>
		<slash:comments>1</slash:comments>
		</item>
		<item>
		<title>MySQL, PDO i procedury składowane</title>
		<link>http://spiechu.pl/2011/11/06/mysql-pdo-i-procedury-skladowane/</link>
		<comments>http://spiechu.pl/2011/11/06/mysql-pdo-i-procedury-skladowane/#comments</comments>
		<pubDate>Sun, 06 Nov 2011 13:10:44 +0000</pubDate>
		<dc:creator>Śpiechu</dc:creator>
				<category><![CDATA[webmastering]]></category>
		<category><![CDATA[mysql]]></category>
		<category><![CDATA[PDO]]></category>
		<category><![CDATA[php]]></category>

		<guid isPermaLink="false">http://spiechu.pl/?p=1167</guid>
		<description><![CDATA[Trochę nie pisałem. Mam nadzieję, że dzisiejszy wpis wszystkim wynagrodzi moją nieobecność. Ostatnio stanąłem przed wyzwaniem zrobienia galerii zdjęć, których kolejność dałoby się dowolnie modyfikować za pomocą przeciągania i upuszczania. Dzisiaj opiszę operacje bazodanowe, a na następny raz jQuery. Będę maksymalnie upraszczał aby nie zaciemniać meritum. 1. Przygotowania Powiedzmy, że mamy 2 tabele relacyjne odpowiedzialne <a href="http://spiechu.pl/2011/11/06/mysql-pdo-i-procedury-skladowane/"> read more <span class="meta-nav">&#187;</span></a>]]></description>
			<content:encoded><![CDATA[<p>Trochę nie pisałem. Mam nadzieję, że dzisiejszy wpis wszystkim wynagrodzi moją nieobecność. Ostatnio stanąłem przed wyzwaniem zrobienia galerii zdjęć, których kolejność dałoby się dowolnie modyfikować za pomocą przeciągania i upuszczania. Dzisiaj opiszę operacje bazodanowe, a na następny raz jQuery. Będę maksymalnie upraszczał aby nie zaciemniać meritum.</p>
<h3>1. Przygotowania</h3>
<p>Powiedzmy, że mamy 2 tabele relacyjne odpowiedzialne za przechowywanie galerii i obrazów. Np. takie:</p>

<div class="wp_syntax"><div class="code"><pre class="sql" style="font-family:monospace;"><span style="color: #993333; font-weight: bold;">CREATE</span> <span style="color: #993333; font-weight: bold;">TABLE</span> <span style="color: #ff0000;">`galleries`</span> <span style="color: #66cc66;">&#40;</span>
  <span style="color: #ff0000;">`id`</span> <span style="color: #993333; font-weight: bold;">INT</span><span style="color: #66cc66;">&#40;</span><span style="color: #cc66cc;">10</span><span style="color: #66cc66;">&#41;</span> <span style="color: #993333; font-weight: bold;">UNSIGNED</span> <span style="color: #993333; font-weight: bold;">NOT</span> <span style="color: #993333; font-weight: bold;">NULL</span> <span style="color: #993333; font-weight: bold;">AUTO_INCREMENT</span><span style="color: #66cc66;">,</span>
  <span style="color: #ff0000;">`created`</span> <span style="color: #993333; font-weight: bold;">TIMESTAMP</span> <span style="color: #993333; font-weight: bold;">NOT</span> <span style="color: #993333; font-weight: bold;">NULL</span> <span style="color: #993333; font-weight: bold;">DEFAULT</span> <span style="color: #993333; font-weight: bold;">CURRENT_TIMESTAMP</span><span style="color: #66cc66;">,</span>
  <span style="color: #ff0000;">`updated`</span> <span style="color: #993333; font-weight: bold;">TIMESTAMP</span> <span style="color: #993333; font-weight: bold;">NOT</span> <span style="color: #993333; font-weight: bold;">NULL</span> <span style="color: #993333; font-weight: bold;">DEFAULT</span> <span style="color: #ff0000;">'0000-00-00 00:00:00'</span><span style="color: #66cc66;">,</span>
  <span style="color: #ff0000;">`title`</span> <span style="color: #993333; font-weight: bold;">VARCHAR</span><span style="color: #66cc66;">&#40;</span><span style="color: #cc66cc;">250</span><span style="color: #66cc66;">&#41;</span> <span style="color: #993333; font-weight: bold;">DEFAULT</span> <span style="color: #993333; font-weight: bold;">NULL</span><span style="color: #66cc66;">,</span>
  <span style="color: #993333; font-weight: bold;">PRIMARY</span> <span style="color: #993333; font-weight: bold;">KEY</span> <span style="color: #66cc66;">&#40;</span><span style="color: #ff0000;">`id`</span><span style="color: #66cc66;">&#41;</span>
<span style="color: #66cc66;">&#41;</span> ENGINE<span style="color: #66cc66;">=</span>InnoDB  <span style="color: #993333; font-weight: bold;">DEFAULT</span> CHARSET<span style="color: #66cc66;">=</span>utf8 ;
&nbsp;
<span style="color: #993333; font-weight: bold;">CREATE</span> <span style="color: #993333; font-weight: bold;">TABLE</span> <span style="color: #993333; font-weight: bold;">IF</span> <span style="color: #993333; font-weight: bold;">NOT</span> <span style="color: #993333; font-weight: bold;">EXISTS</span> <span style="color: #ff0000;">`images`</span> <span style="color: #66cc66;">&#40;</span>
  <span style="color: #ff0000;">`id`</span> <span style="color: #993333; font-weight: bold;">INT</span><span style="color: #66cc66;">&#40;</span><span style="color: #cc66cc;">10</span><span style="color: #66cc66;">&#41;</span> <span style="color: #993333; font-weight: bold;">UNSIGNED</span> <span style="color: #993333; font-weight: bold;">NOT</span> <span style="color: #993333; font-weight: bold;">NULL</span> <span style="color: #993333; font-weight: bold;">AUTO_INCREMENT</span><span style="color: #66cc66;">,</span>
  <span style="color: #ff0000;">`gallery_id`</span> <span style="color: #993333; font-weight: bold;">INT</span><span style="color: #66cc66;">&#40;</span><span style="color: #cc66cc;">10</span><span style="color: #66cc66;">&#41;</span> <span style="color: #993333; font-weight: bold;">UNSIGNED</span> <span style="color: #993333; font-weight: bold;">NOT</span> <span style="color: #993333; font-weight: bold;">NULL</span><span style="color: #66cc66;">,</span>
  <span style="color: #ff0000;">`filename`</span> <span style="color: #993333; font-weight: bold;">VARCHAR</span><span style="color: #66cc66;">&#40;</span><span style="color: #cc66cc;">50</span><span style="color: #66cc66;">&#41;</span> <span style="color: #993333; font-weight: bold;">NOT</span> <span style="color: #993333; font-weight: bold;">NULL</span><span style="color: #66cc66;">,</span>
  <span style="color: #ff0000;">`ordr`</span> <span style="color: #993333; font-weight: bold;">INT</span><span style="color: #66cc66;">&#40;</span><span style="color: #cc66cc;">10</span><span style="color: #66cc66;">&#41;</span> <span style="color: #993333; font-weight: bold;">UNSIGNED</span> <span style="color: #993333; font-weight: bold;">NOT</span> <span style="color: #993333; font-weight: bold;">NULL</span> <span style="color: #993333; font-weight: bold;">DEFAULT</span> <span style="color: #ff0000;">'1'</span><span style="color: #66cc66;">,</span>
  <span style="color: #ff0000;">`created`</span> <span style="color: #993333; font-weight: bold;">TIMESTAMP</span> <span style="color: #993333; font-weight: bold;">NOT</span> <span style="color: #993333; font-weight: bold;">NULL</span> <span style="color: #993333; font-weight: bold;">DEFAULT</span> <span style="color: #993333; font-weight: bold;">CURRENT_TIMESTAMP</span><span style="color: #66cc66;">,</span>
  <span style="color: #993333; font-weight: bold;">PRIMARY</span> <span style="color: #993333; font-weight: bold;">KEY</span> <span style="color: #66cc66;">&#40;</span><span style="color: #ff0000;">`id`</span><span style="color: #66cc66;">&#41;</span><span style="color: #66cc66;">,</span>
  <span style="color: #993333; font-weight: bold;">KEY</span> <span style="color: #ff0000;">`image_to_gallery`</span> <span style="color: #66cc66;">&#40;</span><span style="color: #ff0000;">`gallery_id`</span><span style="color: #66cc66;">&#41;</span>
<span style="color: #66cc66;">&#41;</span> ENGINE<span style="color: #66cc66;">=</span>InnoDB  <span style="color: #993333; font-weight: bold;">DEFAULT</span> CHARSET<span style="color: #66cc66;">=</span>utf8 ;</pre></div></div>

<p>Od razu widać dwa dziwactwa: dlaczego pole nazywa się <em>ordr</em> a nie <em>order</em>? Z czystego lenistwa. Order jest słowem zarezerwowanym w SQL (<code>ORDER BY coś tam</code>). Każdorazowo nazwa pola musiałaby być w nawiasach. Dlaczego pole <em>updated</em> ma domyślną wartość <em>0000–00-00 00:00:00</em>? Ano dlatego, że <code>CURRENT_TIMESTAMP</code> można użyć tylko raz w tabeli. Wobec tego stworzymy od razu wyzwalacz (trigger), który przed każdym zapytaniem typu <code>UPDATE</code> poprawi wartość na taką jak trzeba.</p>

<div class="wp_syntax"><div class="code"><pre class="sql" style="font-family:monospace;">DELIMITER $$
<span style="color: #993333; font-weight: bold;">CREATE</span> <span style="color: #993333; font-weight: bold;">TRIGGER</span> <span style="color: #ff0000;">`updated_current_timestamp`</span> <span style="color: #993333; font-weight: bold;">BEFORE</span> <span style="color: #993333; font-weight: bold;">UPDATE</span> <span style="color: #993333; font-weight: bold;">ON</span> <span style="color: #ff0000;">`galleries`</span>
   <span style="color: #993333; font-weight: bold;">FOR</span> EACH <span style="color: #993333; font-weight: bold;">ROW</span> <span style="color: #993333; font-weight: bold;">BEGIN</span>
      <span style="color: #993333; font-weight: bold;">SET</span> <span style="color: #993333; font-weight: bold;">NEW</span><span style="color: #66cc66;">.</span>updated <span style="color: #66cc66;">=</span> NOW<span style="color: #66cc66;">&#40;</span><span style="color: #66cc66;">&#41;</span>;
<span style="color: #993333; font-weight: bold;">END</span>$$</pre></div></div>

<p>Na koniec trzeba stworzyć relację 1 galeria do wielu zdjęć.</p>

<div class="wp_syntax"><div class="code"><pre class="sql" style="font-family:monospace;"><span style="color: #993333; font-weight: bold;">ALTER</span> <span style="color: #993333; font-weight: bold;">TABLE</span> <span style="color: #ff0000;">`images`</span>
   <span style="color: #993333; font-weight: bold;">ADD</span> <span style="color: #993333; font-weight: bold;">CONSTRAINT</span> <span style="color: #ff0000;">`image_to_gallery`</span> <span style="color: #993333; font-weight: bold;">FOREIGN</span> <span style="color: #993333; font-weight: bold;">KEY</span> <span style="color: #66cc66;">&#40;</span><span style="color: #ff0000;">`gallery_id`</span><span style="color: #66cc66;">&#41;</span> <span style="color: #993333; font-weight: bold;">REFERENCES</span> <span style="color: #ff0000;">`galleries`</span> <span style="color: #66cc66;">&#40;</span><span style="color: #ff0000;">`id`</span><span style="color: #66cc66;">&#41;</span> <span style="color: #993333; font-weight: bold;">ON</span> <span style="color: #993333; font-weight: bold;">DELETE</span> CASCADE <span style="color: #993333; font-weight: bold;">ON</span> <span style="color: #993333; font-weight: bold;">UPDATE</span> CASCADE;</pre></div></div>

<p>Oznacza to, że kasując galerię od razu pozbędziemy się również wszystkich powiązanych z nią zdjęć. Pliki z dysku oczywiście nie znikną. Można napisać funkcję, która przed usunięciem galerii z bazy najpierw wyrzuca wszystkie powiązane z nią pliki, a dopiero potem wykonuje polecenie <code>DELETE</code>.</p>
<h2>2. Decyzje</h2>
<p>Teraz nadszedł czas na poważne decyzje. Chodzi o sposób manipulacji wierszami dotyczącymi zdjęć. Można to zrobić za pomocą PHP. Jest to rozwiązanie prostsze. Powoduje jednak spory narzut komunikacji PHP&lt;—&gt;SQL. W przypadku zwalenia wszystkiego na bazę danych, pchamy logikę wyżej i bliżej modyfikowanych danych. Minusem jest cholerna składnia SQLowa i późniejsze problematyczne utrzymanie kodu.<br />
Problem oczywiście nie istnieje gdy robimy galeryjkę na 10 obrazków i przestawimy sobie kolejność ostatniego na przedostatni. Ja raczej podchodzę do rzeczy poważnie i wolę od początku zrobić to tak jak powinno być. Poza tym wyzwalacze i procedury składowane to jest to, co bazodanowe tygryski lubią najbardziej <img src='http://spiechu.pl/wp-includes/images/smilies/icon_smile.gif' alt=':-)' class='wp-smiley' /> </p>
<h3>3. Wykonanie</h3>
<p>Każdy nowy rekord tabeli <em>images</em> musi mieć nadany odpowiedni identyfikator pozycji <em>ordr</em> o 1 większy od ostatniego w danej galerii. Mamy trzy rozwiązania: czysty PHP, wyzwalacz wywoływany przed <code>INSERT</code>em lub procedura składowana. Zapytanie w PHP może wyglądać tak:</p>

<div class="wp_syntax"><div class="code"><pre class="php" style="font-family:monospace;"><span style="color: #000088;">$q</span> <span style="color: #339933;">=</span> <span style="color: #000088;">$pdo</span><span style="color: #339933;">-&gt;</span><span style="color: #004000;">prepare</span><span style="color: #009900;">&#40;</span><span style="color: #0000ff;">'INSERT INTO images (filename,gallery_id,ordr) (SELECT ?,?,MAX(ordr)+1 FROM images WHERE gallery_id=? LIMIT 1)'</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
<span style="color: #000088;">$q</span><span style="color: #339933;">-&gt;</span><span style="color: #004000;">bindValue</span><span style="color: #009900;">&#40;</span><span style="color: #cc66cc;">1</span><span style="color: #339933;">,</span> <span style="color: #0000ff;">'obrazek.jpg'</span><span style="color: #339933;">,</span> PDO<span style="color: #339933;">::</span><span style="color: #004000;">PARAM_STR</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
<span style="color: #000088;">$q</span><span style="color: #339933;">-&gt;</span><span style="color: #004000;">bindParam</span><span style="color: #009900;">&#40;</span><span style="color: #cc66cc;">2</span><span style="color: #339933;">,</span> <span style="color: #000088;">$galleryId</span><span style="color: #339933;">,</span> PDO<span style="color: #339933;">::</span><span style="color: #004000;">PARAM_INT</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
<span style="color: #000088;">$q</span><span style="color: #339933;">-&gt;</span><span style="color: #004000;">bindParam</span><span style="color: #009900;">&#40;</span><span style="color: #cc66cc;">3</span><span style="color: #339933;">,</span> <span style="color: #000088;">$galleryId</span><span style="color: #339933;">,</span> PDO<span style="color: #339933;">::</span><span style="color: #004000;">PARAM_INT</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
<span style="color: #000088;">$q</span><span style="color: #339933;">-&gt;</span><span style="color: #004000;">execute</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span></pre></div></div>

<p>Wspominam o tym rozwiązaniu dlatego, że ma ciekawą konstrukcję <code>INSERT SELECT</code>. Zapewne większość z was po kilkunastokrotnej próbie wywołania polecenia <code>INSERT INTO VALUES</code> i gdzieś tam <code>SELECT</code> dostanie cholery i rozbije zapytanie na 2: pierwsze sprawdza ostatni <em>ordr</em>, a następne doda 1 i umieści <code>INSERT</code>em pozostałe dane.<br />
Bazodanowe tygryski wybiorą jednak co innego. Procedury składowane!</p>

<div class="wp_syntax"><div class="code"><pre class="sql" style="font-family:monospace;">DELIMITER $$
<span style="color: #993333; font-weight: bold;">CREATE</span> <span style="color: #993333; font-weight: bold;">PROCEDURE</span> <span style="color: #ff0000;">`insert_image`</span><span style="color: #66cc66;">&#40;</span><span style="color: #993333; font-weight: bold;">IN</span> image_filename <span style="color: #993333; font-weight: bold;">VARCHAR</span><span style="color: #66cc66;">&#40;</span><span style="color: #cc66cc;">50</span><span style="color: #66cc66;">&#41;</span><span style="color: #66cc66;">,</span> <span style="color: #993333; font-weight: bold;">IN</span> image_gallery_id <span style="color: #993333; font-weight: bold;">INT</span><span style="color: #66cc66;">,</span> <span style="color: #993333; font-weight: bold;">OUT</span> last_inserted_id <span style="color: #993333; font-weight: bold;">INT</span><span style="color: #66cc66;">&#41;</span>
   <span style="color: #993333; font-weight: bold;">MODIFIES</span> <span style="color: #993333; font-weight: bold;">SQL</span> <span style="color: #993333; font-weight: bold;">DATA</span>
   COMMENT <span style="color: #ff0000;">'Inserts new image at the end of given gallery.'</span>
   <span style="color: #993333; font-weight: bold;">BEGIN</span>
      <span style="color: #993333; font-weight: bold;">DECLARE</span> max_order <span style="color: #993333; font-weight: bold;">INT</span>;
&nbsp;
      # Zamiast <span style="color: #993333; font-weight: bold;">SET</span> zmienna<span style="color: #66cc66;">=</span> uzywam <span style="color: #993333; font-weight: bold;">SELECT</span> <span style="color: #993333; font-weight: bold;">INTO</span> just <span style="color: #993333; font-weight: bold;">FOR</span> fun
      <span style="color: #993333; font-weight: bold;">SELECT</span> <span style="color: #993333; font-weight: bold;">MAX</span><span style="color: #66cc66;">&#40;</span>ordr<span style="color: #66cc66;">&#41;</span> <span style="color: #993333; font-weight: bold;">INTO</span> max_order <span style="color: #993333; font-weight: bold;">FROM</span> images <span style="color: #993333; font-weight: bold;">WHERE</span> gallery_id<span style="color: #66cc66;">=</span>image_gallery_id <span style="color: #993333; font-weight: bold;">LIMIT</span> <span style="color: #cc66cc;">1</span>;
&nbsp;
      # Gdy obrazek jest pierwszy w galerii
      <span style="color: #993333; font-weight: bold;">IF</span> max_order <span style="color: #993333; font-weight: bold;">IS</span> <span style="color: #993333; font-weight: bold;">NULL</span> <span style="color: #993333; font-weight: bold;">THEN</span> 
         <span style="color: #993333; font-weight: bold;">SET</span> max_order <span style="color: #66cc66;">=</span> <span style="color: #cc66cc;">1</span>;
      <span style="color: #993333; font-weight: bold;">ELSE</span>
         <span style="color: #993333; font-weight: bold;">SET</span> max_order <span style="color: #66cc66;">=</span> max_order <span style="color: #66cc66;">+</span> <span style="color: #cc66cc;">1</span>;
      <span style="color: #993333; font-weight: bold;">END</span> <span style="color: #993333; font-weight: bold;">IF</span>;
      <span style="color: #993333; font-weight: bold;">INSERT</span> <span style="color: #993333; font-weight: bold;">INTO</span> images <span style="color: #66cc66;">&#40;</span>filename<span style="color: #66cc66;">,</span> gallery_id<span style="color: #66cc66;">,</span> ordr<span style="color: #66cc66;">&#41;</span> <span style="color: #993333; font-weight: bold;">VALUES</span> <span style="color: #66cc66;">&#40;</span>image_filename<span style="color: #66cc66;">,</span> image_gallery_id<span style="color: #66cc66;">,</span> max_order<span style="color: #66cc66;">&#41;</span>;
      <span style="color: #993333; font-weight: bold;">SELECT</span> LAST_INSERT_ID<span style="color: #66cc66;">&#40;</span><span style="color: #66cc66;">&#41;</span> <span style="color: #993333; font-weight: bold;">INTO</span> last_inserted_id;
<span style="color: #993333; font-weight: bold;">END</span>$$</pre></div></div>

<p>Próba wywołania <code>$pdo->lastInsertId()</code> zakończy się niepowodzeniem (a raczej zerem <img src='http://spiechu.pl/wp-includes/images/smilies/icon_smile.gif' alt=':-)' class='wp-smiley' />  ). Dlatego potrzebujemy parametru wyjściowego. Poniżej pokazuję jak całość wywołać w PDO:</p>

<div class="wp_syntax"><div class="code"><pre class="php" style="font-family:monospace;"><span style="color: #000088;">$q</span> <span style="color: #339933;">=</span> <span style="color: #000088;">$pdo</span><span style="color: #339933;">-&gt;</span><span style="color: #004000;">prepare</span><span style="color: #009900;">&#40;</span><span style="color: #0000ff;">'CALL insert_image(?,?,@lastInsertId)'</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
<span style="color: #000088;">$q</span><span style="color: #339933;">-&gt;</span><span style="color: #004000;">bindValue</span><span style="color: #009900;">&#40;</span><span style="color: #cc66cc;">1</span><span style="color: #339933;">,</span> <span style="color: #0000ff;">'obrazek.jpg'</span><span style="color: #339933;">,</span> PDO<span style="color: #339933;">::</span><span style="color: #004000;">PARAM_STR</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
<span style="color: #000088;">$q</span><span style="color: #339933;">-&gt;</span><span style="color: #004000;">bindParam</span><span style="color: #009900;">&#40;</span><span style="color: #cc66cc;">2</span><span style="color: #339933;">,</span> <span style="color: #000088;">$galleryId</span><span style="color: #339933;">,</span> PDO<span style="color: #339933;">::</span><span style="color: #004000;">PARAM_INT</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
<span style="color: #000088;">$q</span><span style="color: #339933;">-&gt;</span><span style="color: #004000;">execute</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
<span style="color: #000088;">$outputArray</span> <span style="color: #339933;">=</span> <span style="color: #000088;">$pdo</span><span style="color: #339933;">-&gt;</span><span style="color: #004000;">query</span><span style="color: #009900;">&#40;</span><span style="color: #0000ff;">'select @lastInsertId'</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">-&gt;</span><span style="color: #004000;">fetch</span><span style="color: #009900;">&#40;</span>PDO<span style="color: #339933;">::</span><span style="color: #004000;">FETCH_ASSOC</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
<span style="color: #000088;">$lastInsertId</span> <span style="color: #339933;">=</span> <span style="color: #000088;">$outputArray</span><span style="color: #009900;">&#91;</span><span style="color: #0000ff;">'@lastInsertId'</span><span style="color: #009900;">&#93;</span><span style="color: #339933;">;</span></pre></div></div>

<p>Ktoś może się zapytać po co te numery ze zmienną wyjściową. PDO i sterownik MySQL w PHP ma szpetny błąd dotyczący obsługi parametrów wyjściowych z procedur składowanych. Podobno w nowszych wersjach jest OK. Trik podany wyżej u mnie działa i oszczędza trochę nerwów.</p>
<p>Procedura kasująca obrazki również jest raczej prosta. Rzućcie okiem:</p>

<div class="wp_syntax"><div class="code"><pre class="sql" style="font-family:monospace;">DELIMITER $$
<span style="color: #993333; font-weight: bold;">CREATE</span> <span style="color: #993333; font-weight: bold;">PROCEDURE</span> <span style="color: #ff0000;">`delete_image`</span><span style="color: #66cc66;">&#40;</span><span style="color: #993333; font-weight: bold;">IN</span> image_id <span style="color: #993333; font-weight: bold;">INT</span><span style="color: #66cc66;">&#41;</span>
   <span style="color: #993333; font-weight: bold;">MODIFIES</span> <span style="color: #993333; font-weight: bold;">SQL</span> <span style="color: #993333; font-weight: bold;">DATA</span>
   COMMENT <span style="color: #ff0000;">'Deletes and reorders if there is a gap.'</span>
   <span style="color: #993333; font-weight: bold;">BEGIN</span>
      <span style="color: #993333; font-weight: bold;">DECLARE</span> image_gallery_id<span style="color: #66cc66;">,</span> image_order<span style="color: #66cc66;">,</span> max_order <span style="color: #993333; font-weight: bold;">INT</span>;
      <span style="color: #993333; font-weight: bold;">SELECT</span> gallery_id<span style="color: #66cc66;">,</span> ordr <span style="color: #993333; font-weight: bold;">INTO</span> image_gallery_id<span style="color: #66cc66;">,</span> image_order <span style="color: #993333; font-weight: bold;">FROM</span> images <span style="color: #993333; font-weight: bold;">WHERE</span> id<span style="color: #66cc66;">=</span>image_id <span style="color: #993333; font-weight: bold;">LIMIT</span> <span style="color: #cc66cc;">1</span>;
      <span style="color: #993333; font-weight: bold;">DELETE</span> <span style="color: #993333; font-weight: bold;">FROM</span> images <span style="color: #993333; font-weight: bold;">WHERE</span> id<span style="color: #66cc66;">=</span>image_id <span style="color: #993333; font-weight: bold;">LIMIT</span> <span style="color: #cc66cc;">1</span>;
      <span style="color: #993333; font-weight: bold;">SELECT</span> <span style="color: #993333; font-weight: bold;">MAX</span><span style="color: #66cc66;">&#40;</span>ordr<span style="color: #66cc66;">&#41;</span> <span style="color: #993333; font-weight: bold;">INTO</span> max_order <span style="color: #993333; font-weight: bold;">FROM</span> images <span style="color: #993333; font-weight: bold;">WHERE</span> gallery_id<span style="color: #66cc66;">=</span>image_gallery_id <span style="color: #993333; font-weight: bold;">LIMIT</span> <span style="color: #cc66cc;">1</span>;
&nbsp;
      # Sprawdzamy czy istnieja jakies obrazki za skasowanym
      <span style="color: #993333; font-weight: bold;">IF</span> max_order <span style="color: #993333; font-weight: bold;">IS</span> <span style="color: #993333; font-weight: bold;">NOT</span> <span style="color: #993333; font-weight: bold;">NULL</span> <span style="color: #993333; font-weight: bold;">AND</span> max_order <span style="color: #66cc66;">&gt;</span> image_order <span style="color: #993333; font-weight: bold;">THEN</span>
         WHILE image_order <span style="color: #66cc66;">&lt;</span> max_order DO
&nbsp;
            # Cofamy w petli wypelniajac luke po skasowanym obrazku
            <span style="color: #993333; font-weight: bold;">UPDATE</span> images <span style="color: #993333; font-weight: bold;">SET</span> ordr<span style="color: #66cc66;">=</span>image_order <span style="color: #993333; font-weight: bold;">WHERE</span> ordr<span style="color: #66cc66;">=</span>image_order<span style="color: #66cc66;">+</span><span style="color: #cc66cc;">1</span> <span style="color: #993333; font-weight: bold;">AND</span> gallery_id<span style="color: #66cc66;">=</span>image_gallery_id;
            <span style="color: #993333; font-weight: bold;">SET</span> image_order <span style="color: #66cc66;">=</span> image_order <span style="color: #66cc66;">+</span> <span style="color: #cc66cc;">1</span>;
       <span style="color: #993333; font-weight: bold;">END</span> WHILE;
   <span style="color: #993333; font-weight: bold;">END</span> <span style="color: #993333; font-weight: bold;">IF</span>;
<span style="color: #993333; font-weight: bold;">END</span>$$</pre></div></div>

<p>Wywołanie jest super proste. Wpisujemy i zapominamy:</p>

<div class="wp_syntax"><div class="code"><pre class="php" style="font-family:monospace;"><span style="color: #000088;">$q</span> <span style="color: #339933;">=</span> <span style="color: #000088;">$pdo</span><span style="color: #339933;">-&gt;</span><span style="color: #004000;">prepare</span><span style="color: #009900;">&#40;</span><span style="color: #0000ff;">'CALL delete_image(?)'</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
<span style="color: #000088;">$q</span><span style="color: #339933;">-&gt;</span><span style="color: #004000;">bindParam</span><span style="color: #009900;">&#40;</span><span style="color: #cc66cc;">1</span><span style="color: #339933;">,</span> <span style="color: #000088;">$imageId</span><span style="color: #339933;">,</span> PDO<span style="color: #339933;">::</span><span style="color: #004000;">PARAM_INT</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
<span style="color: #000088;">$q</span><span style="color: #339933;">-&gt;</span><span style="color: #004000;">execute</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span></pre></div></div>

<p>Najlepsze zostawiłem na koniec. Procedura przestawiająca pozycję obrazka. Spotkałem się w necie z rozwiązaniem typu <em>„bierzesz sobie wszystkie id obrazków w kolejności, przejeżdżasz foreachem, który nadaje kolejność i na każdym obrazku wykonujesz update”</em>. No dobra, ale co jeżeli przestawiam kolejność tylko ostatniego i przedostatniego, a w galerii mam 1000 zdjęć? Powyższe rozwiązanie orze całą galerię, a userzy czekają 5 sek. na załadowanie się strony. A co jeżeli kilka osób na raz coś przestawia w swoich galeriach? Wtedy na serwerze włącza się na kilka minut turbo hardcore i pojawia się „Pan Gąbka” <img src='http://spiechu.pl/wp-includes/images/smilies/icon_biggrin.gif' alt=':-D' class='wp-smiley' /><br />
Moje rozwiązanie polega na wyłapaniu wyłącznie tego co wymaga zmian. Dałem kilka komentarzy dla jasności.</p>

<div class="wp_syntax"><div class="code"><pre class="sql" style="font-family:monospace;">DELIMITER $$
<span style="color: #993333; font-weight: bold;">CREATE</span> <span style="color: #993333; font-weight: bold;">PROCEDURE</span> <span style="color: #ff0000;">`reorder_image`</span><span style="color: #66cc66;">&#40;</span><span style="color: #993333; font-weight: bold;">IN</span> image_id <span style="color: #993333; font-weight: bold;">INT</span><span style="color: #66cc66;">,</span> <span style="color: #993333; font-weight: bold;">IN</span> new_image_order <span style="color: #993333; font-weight: bold;">INT</span><span style="color: #66cc66;">&#41;</span>
   <span style="color: #993333; font-weight: bold;">MODIFIES</span> <span style="color: #993333; font-weight: bold;">SQL</span> <span style="color: #993333; font-weight: bold;">DATA</span>
   COMMENT <span style="color: #ff0000;">'Reorders images. Does nothing if given order is out of scope.'</span>
   <span style="color: #993333; font-weight: bold;">BEGIN</span>
      <span style="color: #993333; font-weight: bold;">DECLARE</span> current_image_order<span style="color: #66cc66;">,</span> image_gallery_id<span style="color: #66cc66;">,</span> is_destination_order_exists <span style="color: #993333; font-weight: bold;">INT</span>;
&nbsp;
      # Lapie obecne polozenie obrazka i przy okazji id galerii
      <span style="color: #993333; font-weight: bold;">SELECT</span> ordr<span style="color: #66cc66;">,</span> gallery_id <span style="color: #993333; font-weight: bold;">INTO</span> current_image_order<span style="color: #66cc66;">,</span> image_gallery_id <span style="color: #993333; font-weight: bold;">FROM</span> images <span style="color: #993333; font-weight: bold;">WHERE</span> id<span style="color: #66cc66;">=</span>image_id <span style="color: #993333; font-weight: bold;">LIMIT</span> <span style="color: #cc66cc;">1</span>;
&nbsp;
      # Sprawdzam czy punkt docelowy w ogole istnieje
      <span style="color: #993333; font-weight: bold;">SELECT</span> ordr <span style="color: #993333; font-weight: bold;">INTO</span> is_destination_order_exists <span style="color: #993333; font-weight: bold;">FROM</span> images <span style="color: #993333; font-weight: bold;">WHERE</span> gallery_id<span style="color: #66cc66;">=</span>image_gallery_id <span style="color: #993333; font-weight: bold;">AND</span> ordr<span style="color: #66cc66;">=</span>new_image_order <span style="color: #993333; font-weight: bold;">LIMIT</span> <span style="color: #cc66cc;">1</span>;
&nbsp;
      # Jezeli punkt docelowy istnieje i jest inny od obecnego <span style="color: #993333; font-weight: bold;">TO</span> rozpoczynam dzialanie
      <span style="color: #993333; font-weight: bold;">IF</span> is_destination_order_exists <span style="color: #993333; font-weight: bold;">IS</span> <span style="color: #993333; font-weight: bold;">NOT</span> <span style="color: #993333; font-weight: bold;">NULL</span> <span style="color: #993333; font-weight: bold;">AND</span> current_image_order <span style="color: #66cc66;">&lt;&gt;</span> new_image_order <span style="color: #993333; font-weight: bold;">THEN</span>
&nbsp;
         # Jezeli przestawiam obrazek do gory
         <span style="color: #993333; font-weight: bold;">IF</span> current_image_order <span style="color: #66cc66;">&gt;</span>  new_image_order <span style="color: #993333; font-weight: bold;">THEN</span> 
            WHILE current_image_order <span style="color: #66cc66;">&gt;=</span>  new_image_order DO
               <span style="color: #993333; font-weight: bold;">UPDATE</span> images <span style="color: #993333; font-weight: bold;">SET</span> ordr<span style="color: #66cc66;">=</span>current_image_order<span style="color: #66cc66;">+</span><span style="color: #cc66cc;">1</span> <span style="color: #993333; font-weight: bold;">WHERE</span> gallery_id<span style="color: #66cc66;">=</span>image_gallery_id <span style="color: #993333; font-weight: bold;">AND</span> ordr<span style="color: #66cc66;">=</span> current_image_order <span style="color: #993333; font-weight: bold;">LIMIT</span> <span style="color: #cc66cc;">1</span>;
               <span style="color: #993333; font-weight: bold;">SET</span> current_image_order <span style="color: #66cc66;">=</span> current_image_order <span style="color: #66cc66;">-</span> <span style="color: #cc66cc;">1</span>;
            <span style="color: #993333; font-weight: bold;">END</span> WHILE;
&nbsp;
         # Jezeli przestawiam obrazek w dol
         ELSEIF  current_image_order <span style="color: #66cc66;">&lt;</span>  new_image_order <span style="color: #993333; font-weight: bold;">THEN</span> 
            WHILE current_image_order <span style="color: #66cc66;">&lt;=</span>  new_image_order DO
               <span style="color: #993333; font-weight: bold;">UPDATE</span> images <span style="color: #993333; font-weight: bold;">SET</span> ordr<span style="color: #66cc66;">=</span>current_image_order<span style="color: #66cc66;">-</span><span style="color: #cc66cc;">1</span> <span style="color: #993333; font-weight: bold;">WHERE</span> gallery_id<span style="color: #66cc66;">=</span>image_gallery_id <span style="color: #993333; font-weight: bold;">AND</span> ordr<span style="color: #66cc66;">=</span> current_image_order <span style="color: #993333; font-weight: bold;">LIMIT</span> <span style="color: #cc66cc;">1</span>;
               <span style="color: #993333; font-weight: bold;">SET</span> current_image_order <span style="color: #66cc66;">=</span> current_image_order <span style="color: #66cc66;">+</span> <span style="color: #cc66cc;">1</span>;
            <span style="color: #993333; font-weight: bold;">END</span> WHILE;
         <span style="color: #993333; font-weight: bold;">END</span> <span style="color: #993333; font-weight: bold;">IF</span>;
&nbsp;
         # Mam juz miejsce<span style="color: #66cc66;">,</span> wrzucam obrazek tam gdzie ma byc
         <span style="color: #993333; font-weight: bold;">UPDATE</span> images <span style="color: #993333; font-weight: bold;">SET</span> ordr<span style="color: #66cc66;">=</span>new_image_order <span style="color: #993333; font-weight: bold;">WHERE</span> id<span style="color: #66cc66;">=</span>image_id <span style="color: #993333; font-weight: bold;">LIMIT</span> <span style="color: #cc66cc;">1</span>;
      <span style="color: #993333; font-weight: bold;">END</span> <span style="color: #993333; font-weight: bold;">IF</span>;
<span style="color: #993333; font-weight: bold;">END</span>$$</pre></div></div>

<p>Użycie przestawiania kolejności jest również proste:</p>

<div class="wp_syntax"><div class="code"><pre class="php" style="font-family:monospace;"><span style="color: #000088;">$q</span> <span style="color: #339933;">=</span> <span style="color: #000088;">$pdo</span><span style="color: #339933;">-&gt;</span><span style="color: #004000;">prepare</span><span style="color: #009900;">&#40;</span><span style="color: #0000ff;">'CALL reorder_image(?,?)'</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
<span style="color: #000088;">$q</span><span style="color: #339933;">-&gt;</span><span style="color: #004000;">bindParam</span><span style="color: #009900;">&#40;</span><span style="color: #cc66cc;">1</span><span style="color: #339933;">,</span> <span style="color: #000088;">$imageId</span><span style="color: #339933;">,</span> PDO<span style="color: #339933;">::</span><span style="color: #004000;">PARAM_INT</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
<span style="color: #000088;">$q</span><span style="color: #339933;">-&gt;</span><span style="color: #004000;">bindParam</span><span style="color: #009900;">&#40;</span><span style="color: #cc66cc;">2</span><span style="color: #339933;">,</span> <span style="color: #000088;">$wantedImageOrder</span><span style="color: #339933;">,</span> PDO<span style="color: #339933;">::</span><span style="color: #004000;">PARAM_INT</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
<span style="color: #000088;">$q</span><span style="color: #339933;">-&gt;</span><span style="color: #004000;">execute</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span></pre></div></div>

<p>Jeśli ktoś dobrnął aż tutaj to proszę „lajknąć” i „plusnąć”. Niedzielne pozdro4all.</p>
<div class="google_plusone_widget" style="margin-bottom:10px"><g:plusone 
      count="false" href="http://spiechu.pl/2011/11/06/mysql-pdo-i-procedury-skladowane/" size="standard"></g:plusone></div>]]></content:encoded>
			<wfw:commentRss>http://spiechu.pl/2011/11/06/mysql-pdo-i-procedury-skladowane/feed/</wfw:commentRss>
		<slash:comments>3</slash:comments>
		</item>
		<item>
		<title>Śpiechu liczy zawartość alkoholu w drinkach</title>
		<link>http://spiechu.pl/2011/09/28/spiechu-liczy-zawartosc-alkoholu-w-drinkach/</link>
		<comments>http://spiechu.pl/2011/09/28/spiechu-liczy-zawartosc-alkoholu-w-drinkach/#comments</comments>
		<pubDate>Wed, 28 Sep 2011 20:00:23 +0000</pubDate>
		<dc:creator>Śpiechu</dc:creator>
				<category><![CDATA[Inne]]></category>
		<category><![CDATA[python]]></category>

		<guid isPermaLink="false">http://spiechu.pl/?p=1147</guid>
		<description><![CDATA[Zastanawiało Was kiedyś o ile dokładnie wzrośnie całkowita zawartość alkoholu gdy do piwa dodamy „u-boota” (50tkę wódki)? A o ile spadnie gdy to piwo zbeszcześcimy dodaniem soku malinowego? Chodzi mi o dokładne wartości, a nie jakieś tam „no pewnie z 2% jak nic”. Dzisiaj się dowiecie Całość napisałem w Pythonie żeby się trochę wdrożyć. Dla <a href="http://spiechu.pl/2011/09/28/spiechu-liczy-zawartosc-alkoholu-w-drinkach/"> read more <span class="meta-nav">&#187;</span></a>]]></description>
			<content:encoded><![CDATA[<p>Zastanawiało Was kiedyś o ile dokładnie wzrośnie całkowita zawartość alkoholu gdy do piwa dodamy „u-boota” (50tkę wódki)? A o ile spadnie gdy to piwo zbeszcześcimy dodaniem soku malinowego? Chodzi mi o dokładne wartości, a nie jakieś tam „no pewnie z 2% jak nic”. Dzisiaj się dowiecie <img src='http://spiechu.pl/wp-includes/images/smilies/icon_smile.gif' alt=':-)' class='wp-smiley' /> </p>
<p>Całość napisałem w Pythonie żeby się trochę wdrożyć. Dla Windowsa jest bardzo fajna rzecz: <a href="http://www.portablepython.com/">Portable Python</a>. Instalujesz na pendraka i niezależnie od maszyny odpalasz interpreter. Do całości dołączony jest całkiem zgrabny edytor PyScripter.</p>
<p>Dobra, do rzeczy. Potrzebna będzie wiedza przedgimnazjalna — mnożenie, dzielenie i trochę procentów. Wynikowy program obsługuje się tak:</p>

<div class="wp_syntax"><div class="code"><pre class="python" style="font-family:monospace;"><span style="color: #808080; font-style: italic;">#!/usr/bin/env python</span>
&nbsp;
<span style="color: #ff7700;font-weight:bold;">from</span> shaker <span style="color: #ff7700;font-weight:bold;">import</span> Shaker, ShakerDisplayer
&nbsp;
shaker = Shaker<span style="color: black;">&#40;</span><span style="color: black;">&#41;</span>
shaker.<span style="color: black;">addIngredient</span><span style="color: black;">&#40;</span><span style="color: #483d8b;">'piwo'</span>, <span style="color: #ff4500;">500</span>, <span style="color: #ff4500;">5.7</span><span style="color: black;">&#41;</span>
shaker.<span style="color: black;">addIngredient</span><span style="color: black;">&#40;</span><span style="color: #483d8b;">'wodka'</span>, <span style="color: #ff4500;">50</span>, <span style="color: #ff4500;">40</span><span style="color: black;">&#41;</span>
shaker.<span style="color: black;">addIngredient</span><span style="color: black;">&#40;</span><span style="color: #483d8b;">'sok malinowy'</span>, <span style="color: #ff4500;">25</span>, <span style="color: #ff4500;">0</span><span style="color: black;">&#41;</span>
&nbsp;
ShakerDisplayer.<span style="color: black;">displayShakerDetails</span><span style="color: black;">&#40;</span>shaker, <span style="color: #ff4500;">89</span>, <span style="color: #008000;">True</span><span style="color: black;">&#41;</span></pre></div></div>

<p>Otrzymamy poniższy tekst:</p>
<blockquote><p>Skladniki drinka:<br />
25.00ml sok malinowy<br />
30.00ml wodka<br />
48.50ml alcohol<br />
471.50ml piwo<br />
Calkowita zawartosc alkoholu w drinku: 8.43%<br />
Calkowita zawartosc alkoholu w drinku (wyrazona w gramach): 38.32g<br />
Prawdopodobna liczba promili dla faceta o wadze 89kg wynosi 0.62‰</p></blockquote>
<p>W pliku (module!) <em>shaker.py</em> stworzymy sobie 2 klasy: <em>Shaker</em> i <em>ShakerDisplayer</em>. Jak linijki nie mieszczą się w okienku to można przesuwać strzałkami na klawiaturze <img src='http://spiechu.pl/wp-includes/images/smilies/icon_wink.gif' alt=';-)' class='wp-smiley' /> </p>

<div class="wp_syntax"><div class="code"><pre class="python" style="font-family:monospace;"><span style="color: #808080; font-style: italic;">#!/usr/bin/env python</span>
&nbsp;
<span style="color: #ff7700;font-weight:bold;">import</span> <span style="color: #dc143c;">unicodedata</span>
<span style="color: #ff7700;font-weight:bold;">from</span> numbers <span style="color: #ff7700;font-weight:bold;">import</span> Number
&nbsp;
<span style="color: #ff7700;font-weight:bold;">class</span> Shaker:
&nbsp;
    <span style="color: #ff7700;font-weight:bold;">def</span> <span style="color: #0000cd;">__init__</span><span style="color: black;">&#40;</span><span style="color: #008000;">self</span>, shakerCapacity = <span style="color: #ff4500;">1000000</span><span style="color: black;">&#41;</span>:
&nbsp;
        <span style="color: #808080; font-style: italic;"># Zakladamy, ze pojemnosc shakera jest nieograniczona ;-)</span>
        <span style="color: #008000;">self</span>._shakerCapacity = shakerCapacity
&nbsp;
        <span style="color: #808080; font-style: italic;"># Inicjalizuje dictionary dla przechowywania klucz =&gt; wartosc</span>
        <span style="color: #808080; font-style: italic;"># Klucz dla alkoholu jest w skladnikach zawsze</span>
        <span style="color: #008000;">self</span>._drinkIngredients = <span style="color: black;">&#123;</span><span style="color: #483d8b;">'alcohol'</span> : <span style="color: #ff4500;">0</span><span style="color: black;">&#125;</span>
&nbsp;
    <span style="color: #ff7700;font-weight:bold;">def</span> addIngredient<span style="color: black;">&#40;</span><span style="color: #008000;">self</span>, name, amount, alcoholPercentage = <span style="color: #ff4500;">0</span><span style="color: black;">&#41;</span>:
&nbsp;
        <span style="color: #808080; font-style: italic;"># Gdyby komus zachcialo sie wprowadzac inne wartosci niz numerki i wartosci dodatnie</span>
        <span style="color: #ff7700;font-weight:bold;">if</span> <span style="color: #ff7700;font-weight:bold;">not</span> <span style="color: #008000;">isinstance</span><span style="color: black;">&#40;</span>amount, Number<span style="color: black;">&#41;</span> <span style="color: #ff7700;font-weight:bold;">or</span> <span style="color: #ff7700;font-weight:bold;">not</span> <span style="color: #008000;">isinstance</span><span style="color: black;">&#40;</span>alcoholPercentage, Number<span style="color: black;">&#41;</span> <span style="color: #ff7700;font-weight:bold;">or</span> alcoholPercentage <span style="color: #66cc66;">&lt;</span> <span style="color: #ff4500;">0</span> <span style="color: #ff7700;font-weight:bold;">or</span> amount <span style="color: #66cc66;">&lt;</span> <span style="color: #ff4500;">0</span>:
&nbsp;
            <span style="color: #808080; font-style: italic;"># Formatowanie za pomoca {} zadziala od Pythona 3.1+    </span>
            <span style="color: #ff7700;font-weight:bold;">raise</span> <span style="color: #008000;">ValueError</span><span style="color: black;">&#40;</span><span style="color: #483d8b;">'Podano {} i {} dla {}'</span>.<span style="color: black;">format</span><span style="color: black;">&#40;</span>amount, alcoholPercentage, name<span style="color: black;">&#41;</span><span style="color: black;">&#41;</span>
&nbsp;
        <span style="color: #808080; font-style: italic;"># Sprawdzam czy jest wystarczajaco duzo miejsca w shakerze</span>
        spaceInShakerLeft = <span style="color: #008000;">self</span>._shakerCapacity - <span style="color: #008000;">self</span>.<span style="color: black;">totalLiquidAmount</span><span style="color: black;">&#40;</span><span style="color: black;">&#41;</span>
        <span style="color: #ff7700;font-weight:bold;">if</span> spaceInShakerLeft <span style="color: #66cc66;">&gt;</span>= amount:
            <span style="color: #008000;">self</span>._storeNewIngredient<span style="color: black;">&#40;</span>name, amount, alcoholPercentage<span style="color: black;">&#41;</span>
        <span style="color: #ff7700;font-weight:bold;">else</span>:
&nbsp;
            <span style="color: #808080; font-style: italic;"># Jak za malo to dolewam tylko tyle ile sie zmiesci</span>
            <span style="color: #008000;">self</span>._storeNewIngredient<span style="color: black;">&#40;</span>name, spaceInShakerLeft, alcoholPercentage<span style="color: black;">&#41;</span>
&nbsp;
    <span style="color: #ff7700;font-weight:bold;">def</span> _storeNewIngredient<span style="color: black;">&#40;</span><span style="color: #008000;">self</span>, name, amount, alcoholPercentage<span style="color: black;">&#41;</span>:
&nbsp;
        <span style="color: #808080; font-style: italic;"># Licze objetosc czystego alkoholu w plynie</span>
        liquidAlcohol = <span style="color: #ff4500;">0</span>
        <span style="color: #ff7700;font-weight:bold;">if</span> alcoholPercentage <span style="color: #66cc66;">&gt;</span> <span style="color: #ff4500;">0</span>:
            liquidAlcohol = <span style="color: black;">&#40;</span>amount <span style="color: #66cc66;">*</span> alcoholPercentage<span style="color: black;">&#41;</span> / <span style="color: #ff4500;">100</span>
            <span style="color: #008000;">self</span>._drinkIngredients<span style="color: black;">&#91;</span><span style="color: #483d8b;">'alcohol'</span><span style="color: black;">&#93;</span> += liquidAlcohol
&nbsp;
        <span style="color: #808080; font-style: italic;"># Sprawdzam czy w drinku jest juz dany skladnik</span>
        <span style="color: #ff7700;font-weight:bold;">if</span> <span style="color: #008000;">self</span>._drinkIngredients.<span style="color: black;">get</span><span style="color: black;">&#40;</span>name<span style="color: black;">&#41;</span> == <span style="color: #008000;">None</span>:
            <span style="color: #008000;">self</span>._drinkIngredients<span style="color: black;">&#91;</span>name<span style="color: black;">&#93;</span> = amount - liquidAlcohol
        <span style="color: #ff7700;font-weight:bold;">else</span>:
            <span style="color: #008000;">self</span>._drinkIngredients<span style="color: black;">&#91;</span>name<span style="color: black;">&#93;</span> += amount - liquidAlcohol
&nbsp;
    <span style="color: #ff7700;font-weight:bold;">def</span> getAllDrinkIngredients<span style="color: black;">&#40;</span><span style="color: #008000;">self</span><span style="color: black;">&#41;</span>:
&nbsp;
        <span style="color: #808080; font-style: italic;"># Wypluwam czysty dictionary ze skladnikami</span>
        <span style="color: #ff7700;font-weight:bold;">return</span> <span style="color: #008000;">self</span>._drinkIngredients
&nbsp;
    <span style="color: #ff7700;font-weight:bold;">def</span> totalLiquidAmount<span style="color: black;">&#40;</span><span style="color: #008000;">self</span><span style="color: black;">&#41;</span>:
&nbsp;
        <span style="color: #808080; font-style: italic;"># Zliczam objetosc wszystkich skladnikow w shakerze</span>
        total = <span style="color: #ff4500;">0</span>
        <span style="color: #ff7700;font-weight:bold;">for</span> value <span style="color: #ff7700;font-weight:bold;">in</span> <span style="color: #008000;">self</span>._drinkIngredients.<span style="color: black;">values</span><span style="color: black;">&#40;</span><span style="color: black;">&#41;</span>:
            total += value
        <span style="color: #ff7700;font-weight:bold;">return</span> total
&nbsp;
    <span style="color: #ff7700;font-weight:bold;">def</span> getTotalLiquidAlcohol<span style="color: black;">&#40;</span><span style="color: #008000;">self</span><span style="color: black;">&#41;</span>:
        <span style="color: #ff7700;font-weight:bold;">return</span> <span style="color: #008000;">self</span>._drinkIngredients<span style="color: black;">&#91;</span><span style="color: #483d8b;">'alcohol'</span><span style="color: black;">&#93;</span>
&nbsp;
    <span style="color: #ff7700;font-weight:bold;">def</span> getTotalAlcoholPercentage<span style="color: black;">&#40;</span><span style="color: #008000;">self</span><span style="color: black;">&#41;</span>:
&nbsp;
        <span style="color: #808080; font-style: italic;"># Licze calkowity procent alkoholu w drinku</span>
        <span style="color: #ff7700;font-weight:bold;">return</span> <span style="color: black;">&#40;</span><span style="color: #008000;">self</span>.<span style="color: black;">getTotalLiquidAlcohol</span><span style="color: black;">&#40;</span><span style="color: black;">&#41;</span> / <span style="color: #008000;">self</span>.<span style="color: black;">totalLiquidAmount</span><span style="color: black;">&#40;</span><span style="color: black;">&#41;</span><span style="color: black;">&#41;</span> <span style="color: #66cc66;">*</span> <span style="color: #ff4500;">100</span>
&nbsp;
    <span style="color: #ff7700;font-weight:bold;">def</span> getTotalAlcoholInGrams<span style="color: black;">&#40;</span><span style="color: #008000;">self</span><span style="color: black;">&#41;</span>:
&nbsp;
        <span style="color: #808080; font-style: italic;"># Przeliczam ml alkoholu na gramy</span>
        <span style="color: #ff7700;font-weight:bold;">return</span> <span style="color: #ff4500;">0.79</span> <span style="color: #66cc66;">*</span> <span style="color: #008000;">self</span>.<span style="color: black;">getTotalLiquidAlcohol</span><span style="color: black;">&#40;</span><span style="color: black;">&#41;</span>
&nbsp;
    <span style="color: #ff7700;font-weight:bold;">def</span> computeAlcoholPromillesPerWeight<span style="color: black;">&#40;</span><span style="color: #008000;">self</span>, weight, man = <span style="color: #008000;">True</span><span style="color: black;">&#41;</span>:
&nbsp;
        <span style="color: #808080; font-style: italic;"># PRZYBLIZONA zawartosc procentowa plynow ustrojowych w zaleznosci od plci</span>
        humanFluidsPercentage = <span style="color: #ff4500;">0.7</span> <span style="color: #ff7700;font-weight:bold;">if</span> man == <span style="color: #008000;">True</span> <span style="color: #ff7700;font-weight:bold;">else</span> <span style="color: #ff4500;">0.6</span>
        <span style="color: #ff7700;font-weight:bold;">return</span> <span style="color: #008000;">self</span>.<span style="color: black;">getTotalAlcoholInGrams</span><span style="color: black;">&#40;</span><span style="color: black;">&#41;</span> / <span style="color: black;">&#40;</span>humanFluidsPercentage <span style="color: #66cc66;">*</span> weight<span style="color: black;">&#41;</span>
&nbsp;
    <span style="color: #ff7700;font-weight:bold;">def</span> pourOutDrink<span style="color: black;">&#40;</span><span style="color: #008000;">self</span>, amount<span style="color: black;">&#41;</span>:
        <span style="color: #483d8b;">&quot;&quot;&quot;
        Metoda wlasciwie niepotrzebna. Mozna wylac (wypic!) czesc zawartosci
        shakera i sobie potem dolewac kolejne skladniki.
        &quot;&quot;&quot;</span>
        <span style="color: #ff7700;font-weight:bold;">if</span> amount <span style="color: #66cc66;">&gt;</span>= <span style="color: #008000;">self</span>.<span style="color: black;">totalLiquidAmount</span><span style="color: black;">&#40;</span><span style="color: black;">&#41;</span>:
            <span style="color: #008000;">self</span>._drinkIngredients = <span style="color: black;">&#123;</span><span style="color: #483d8b;">'alcohol'</span> : <span style="color: #ff4500;">0</span><span style="color: black;">&#125;</span>
        <span style="color: #ff7700;font-weight:bold;">else</span>:
            percentage = amount / <span style="color: #008000;">self</span>.<span style="color: black;">totalLiquidAmount</span><span style="color: black;">&#40;</span><span style="color: black;">&#41;</span>
            <span style="color: #ff7700;font-weight:bold;">for</span> key, value <span style="color: #ff7700;font-weight:bold;">in</span> <span style="color: #008000;">self</span>._drinkIngredients.<span style="color: black;">items</span><span style="color: black;">&#40;</span><span style="color: black;">&#41;</span>:
                <span style="color: #008000;">self</span>._drinkIngredients<span style="color: black;">&#91;</span>key<span style="color: black;">&#93;</span> -= <span style="color: #008000;">self</span>._drinkIngredients<span style="color: black;">&#91;</span>key<span style="color: black;">&#93;</span> <span style="color: #66cc66;">*</span> percentage</pre></div></div>

<p>Klasa powyżej policzy to co trzeba. Wyliczenia dotyczące promili w organizmie należy traktować jako mocno przybliżone. Całej dawki alkoholu nie przyjmujemy w końcu w 1 sekundzie, organizm na bieżąco spala truciznę. Poza tym zależy czy i co się jadło itp. itd., nie wiem, nie znam się.<br />
Teraz jeszcze klasa, która zajmie się wyświetlaniem (a raczej metoda statyczna).</p>

<div class="wp_syntax"><div class="code"><pre class="python" style="font-family:monospace;"><span style="color: #ff7700;font-weight:bold;">class</span> ShakerDisplayer:
&nbsp;
    <span style="color: #ff7700;font-weight:bold;">def</span> displayShakerDetails<span style="color: black;">&#40;</span>shaker, weight, man = <span style="color: #008000;">True</span><span style="color: black;">&#41;</span>:
        <span style="color: #ff7700;font-weight:bold;">if</span> <span style="color: #ff7700;font-weight:bold;">not</span> <span style="color: #008000;">isinstance</span><span style="color: black;">&#40;</span>shaker, Shaker<span style="color: black;">&#41;</span>:
            <span style="color: #ff7700;font-weight:bold;">raise</span> <span style="color: #008000;">ValueError</span><span style="color: black;">&#40;</span><span style="color: #483d8b;">'Podano argument klasy {}'</span>.<span style="color: black;">format</span><span style="color: black;">&#40;</span>shaker.__class__<span style="color: black;">&#41;</span><span style="color: black;">&#41;</span>
&nbsp;
        <span style="color: #ff7700;font-weight:bold;">print</span><span style="color: black;">&#40;</span><span style="color: #483d8b;">'Skladniki drinka:'</span><span style="color: black;">&#41;</span>
        <span style="color: #ff7700;font-weight:bold;">for</span> key,value <span style="color: #ff7700;font-weight:bold;">in</span> shaker.<span style="color: black;">getAllDrinkIngredients</span><span style="color: black;">&#40;</span><span style="color: black;">&#41;</span>.<span style="color: black;">items</span><span style="color: black;">&#40;</span><span style="color: black;">&#41;</span>:
            <span style="color: #808080; font-style: italic;"># Zaokraglamy i wymuszamy 2 miejsca po przecinku</span>
            <span style="color: #ff7700;font-weight:bold;">print</span><span style="color: black;">&#40;</span><span style="color: #483d8b;">'{:.2f}ml {}'</span>.<span style="color: black;">format</span><span style="color: black;">&#40;</span>value,key<span style="color: black;">&#41;</span><span style="color: black;">&#41;</span>
&nbsp;
        <span style="color: #ff7700;font-weight:bold;">print</span><span style="color: black;">&#40;</span><span style="color: #483d8b;">'Calkowita zawartosc alkoholu w drinku: {:.2f}%'</span>.<span style="color: black;">format</span><span style="color: black;">&#40;</span>shaker.<span style="color: black;">getTotalAlcoholPercentage</span><span style="color: black;">&#40;</span><span style="color: black;">&#41;</span><span style="color: black;">&#41;</span><span style="color: black;">&#41;</span>
        <span style="color: #ff7700;font-weight:bold;">print</span><span style="color: black;">&#40;</span><span style="color: #483d8b;">'Calkowita zawartosc alkoholu w drinku (wyrazona w gramach): {:.2f}g'</span>.<span style="color: black;">format</span><span style="color: black;">&#40;</span>shaker.<span style="color: black;">getTotalAlcoholInGrams</span><span style="color: black;">&#40;</span><span style="color: black;">&#41;</span><span style="color: black;">&#41;</span><span style="color: black;">&#41;</span>
&nbsp;
        <span style="color: #808080; font-style: italic;"># Nie znam lepszej metody na wyswietlenie znaku promila niz unicodedata.lookup('PER MILLE SIGN')</span>
        <span style="color: #808080; font-style: italic;"># Ma ktos lepszy pomysl?</span>
        <span style="color: #ff7700;font-weight:bold;">print</span><span style="color: black;">&#40;</span><span style="color: #483d8b;">'Prawdopodobna liczba promili dla {} o wadze {}kg wynosi {:.2f}{}'</span>.<span style="color: black;">format</span><span style="color: black;">&#40;</span><span style="color: #483d8b;">'faceta'</span> <span style="color: #ff7700;font-weight:bold;">if</span> man == <span style="color: #008000;">True</span> <span style="color: #ff7700;font-weight:bold;">else</span> <span style="color: #483d8b;">'kobiety'</span>, weight, shaker.<span style="color: black;">computeAlcoholPromillesPerWeight</span><span style="color: black;">&#40;</span>weight,man<span style="color: black;">&#41;</span>, <span style="color: #dc143c;">unicodedata</span>.<span style="color: black;">lookup</span><span style="color: black;">&#40;</span><span style="color: #483d8b;">'PER MILLE SIGN'</span><span style="color: black;">&#41;</span><span style="color: black;">&#41;</span><span style="color: black;">&#41;</span></pre></div></div>

<p>Gdyby potraktować nasz żołądek jak taki shaker, to po wpisaniu pół litra wódki + 2 piwa + litrowy sprite da nam:</p>
<blockquote><p>Skladniki drinka:<br />
300.00ml wodka<br />
257.00ml alcohol<br />
1000.00ml sprite<br />
943.00ml piwo<br />
Calkowita zawartosc alkoholu w drinku: 10.28%<br />
Calkowita zawartosc alkoholu w drinku (wyrazona w gramach): 203.03g<br />
Prawdopodobna liczba promili dla faceta o wadze 89kg wynosi 3.26‰</p></blockquote>
<p>No nic, na zdrowie i pozdro dla wszystkich Pythonowców! Leniuchom <a href="https://gist.github.com/1249078">podaję link do gotowych plików</a>.</p>
<div class="google_plusone_widget" style="margin-bottom:10px"><g:plusone 
      count="false" href="http://spiechu.pl/2011/09/28/spiechu-liczy-zawartosc-alkoholu-w-drinkach/" size="standard"></g:plusone></div>]]></content:encoded>
			<wfw:commentRss>http://spiechu.pl/2011/09/28/spiechu-liczy-zawartosc-alkoholu-w-drinkach/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
	</channel>
</rss><!-- Performance optimized by W3 Total Cache. Learn more: http://www.w3-edge.com/wordpress-plugins/

Page Caching using disk (enhanced)
Database Caching 3/16 queries in 0.015 seconds using disk
Object Caching 1008/1041 objects using disk

Served from: spiechu.pl @ 2012-01-09 06:29:42 -->

